Merge branch 'master' into rewrite-sheet
authorJohn Darrington <john@darrington.wattle.id.au>
Tue, 11 Nov 2008 04:39:40 +0000 (13:39 +0900)
committerJohn Darrington <john@darrington.wattle.id.au>
Tue, 11 Nov 2008 04:39:40 +0000 (13:39 +0900)
Conflicts:

lib/gtksheet/automake.mk
po/en_GB.po

289 files changed:
.gitignore
AUTHORS
ChangeLog [deleted file]
INSTALL
Makefile.am
NEWS
OChangeLog [new file with mode: 0644]
README
Smake
acinclude.m4
config/ChangeLog [deleted file]
config/OChangeLog [new file with mode: 0644]
config/automake.mk
configure.ac
doc/ChangeLog [deleted file]
doc/OChangeLog [new file with mode: 0644]
doc/automake.mk
doc/data-io.texi
doc/dev/system-file-format.texi
doc/files.texi
doc/invoking.texi
doc/language.texi
doc/statistics.texi
doc/transformation.texi
doc/utilities.texi
doc/variables.texi
examples/ChangeLog [deleted file]
examples/OChangeLog [new file with mode: 0644]
examples/automake.mk
glade/ChangeLog [deleted file]
glade/OChangeLog [new file with mode: 0644]
glade/automake.mk
lib/ChangeLog [deleted file]
lib/OChangeLog [new file with mode: 0644]
lib/automake.mk
lib/gsl-extras/.gitignore [deleted file]
lib/gsl-extras/ChangeLog [deleted file]
lib/gsl-extras/README [deleted file]
lib/gsl-extras/automake.mk [deleted file]
lib/gsl-extras/betadistinv.c [deleted file]
lib/gsl-extras/binomial.c [deleted file]
lib/gsl-extras/geometric.c [deleted file]
lib/gsl-extras/gsl-extras.h [deleted file]
lib/gsl-extras/hypergeometric.c [deleted file]
lib/gsl-extras/negbinom.c [deleted file]
lib/gsl-extras/poisson.c [deleted file]
lib/gtksheet/ChangeLog [deleted file]
lib/gtksheet/OChangeLog [new file with mode: 0644]
lib/gtksheet/automake.mk
lib/linreg/ChangeLog [deleted file]
lib/linreg/OChangeLog [new file with mode: 0644]
lib/linreg/automake.mk
lib/misc/README [new file with mode: 0644]
lib/misc/automake.mk [new file with mode: 0644]
lib/misc/wx-mp-sr.c [new file with mode: 0644]
lib/misc/wx-mp-sr.h [new file with mode: 0644]
po/en_GB.po
src/ChangeLog [deleted file]
src/OChangeLog [new file with mode: 0644]
src/automake.mk
src/data/ChangeLog [deleted file]
src/data/OChangeLog [new file with mode: 0644]
src/data/attributes.c [new file with mode: 0644]
src/data/attributes.h [new file with mode: 0644]
src/data/automake.mk
src/data/case-ordering.c
src/data/case-ordering.h
src/data/casereader-filter.c
src/data/casereader-translator.c
src/data/casereader.h
src/data/casewriter.c
src/data/category.c
src/data/category.h
src/data/data-in.h
src/data/data-out.c
src/data/datasheet.c
src/data/datasheet.h
src/data/dictionary.c
src/data/dictionary.h
src/data/format-guesser.h
src/data/por-file-writer.c
src/data/psql-reader.c
src/data/settings.c
src/data/settings.h
src/data/sys-file-reader.c
src/data/sys-file-writer.c
src/data/value.c
src/data/value.h
src/data/variable.c
src/data/variable.h
src/language/ChangeLog [deleted file]
src/language/OChangeLog [new file with mode: 0644]
src/language/automake.mk
src/language/command.def
src/language/control/ChangeLog [deleted file]
src/language/control/OChangeLog [new file with mode: 0644]
src/language/control/automake.mk
src/language/control/loop.c
src/language/data-io/ChangeLog [deleted file]
src/language/data-io/OChangeLog [new file with mode: 0644]
src/language/data-io/automake.mk
src/language/data-io/data-list.c
src/language/data-io/data-parser.h
src/language/data-io/data-reader.c
src/language/data-io/inpt-pgm.c
src/language/dictionary/ChangeLog [deleted file]
src/language/dictionary/OChangeLog [new file with mode: 0644]
src/language/dictionary/apply-dictionary.c
src/language/dictionary/attributes.c [new file with mode: 0644]
src/language/dictionary/automake.mk
src/language/dictionary/sys-file-info.c
src/language/dictionary/value-labels.c
src/language/expressions/ChangeLog [deleted file]
src/language/expressions/OChangeLog [new file with mode: 0644]
src/language/expressions/automake.mk
src/language/expressions/evaluate.c
src/language/expressions/helpers.c
src/language/expressions/helpers.h
src/language/expressions/operations.def
src/language/lexer/ChangeLog [deleted file]
src/language/lexer/OChangeLog [new file with mode: 0644]
src/language/lexer/automake.mk
src/language/lexer/lexer.c
src/language/lexer/lexer.h
src/language/lexer/q2c.c
src/language/stats/.gitignore
src/language/stats/ChangeLog [deleted file]
src/language/stats/OChangeLog [new file with mode: 0644]
src/language/stats/aggregate.c
src/language/stats/automake.mk
src/language/stats/binomial.c
src/language/stats/binomial.h
src/language/stats/chisquare.c
src/language/stats/chisquare.h
src/language/stats/crosstabs.q
src/language/stats/examine.q
src/language/stats/freq.c
src/language/stats/frequencies.q
src/language/stats/glm.q
src/language/stats/npar-summary.c
src/language/stats/npar.h
src/language/stats/npar.q
src/language/stats/oneway.q
src/language/stats/rank.q
src/language/stats/regression.q
src/language/stats/reliability.q [new file with mode: 0644]
src/language/stats/sort-criteria.c
src/language/stats/t-test.q
src/language/stats/wilcoxon.c [new file with mode: 0644]
src/language/stats/wilcoxon.h [new file with mode: 0644]
src/language/tests/.gitignore [new file with mode: 0644]
src/language/tests/ChangeLog [deleted file]
src/language/tests/OChangeLog [new file with mode: 0644]
src/language/tests/automake.mk
src/language/tests/check-model.q
src/language/tests/datasheet-check.c [new file with mode: 0644]
src/language/tests/datasheet-check.h [new file with mode: 0644]
src/language/tests/datasheet-test.c
src/language/tests/model-checker.c [new file with mode: 0644]
src/language/tests/model-checker.h [new file with mode: 0644]
src/language/utilities/ChangeLog [deleted file]
src/language/utilities/OChangeLog [new file with mode: 0644]
src/language/utilities/automake.mk
src/language/utilities/include.c
src/language/utilities/set.q
src/language/xforms/ChangeLog [deleted file]
src/language/xforms/OChangeLog [new file with mode: 0644]
src/language/xforms/automake.mk
src/language/xforms/recode.c
src/libpspp/ChangeLog [deleted file]
src/libpspp/OChangeLog [new file with mode: 0644]
src/libpspp/automake.mk
src/libpspp/hash-functions.c [new file with mode: 0644]
src/libpspp/hash-functions.h [new file with mode: 0644]
src/libpspp/hash.c
src/libpspp/hash.h
src/libpspp/hmap.c [new file with mode: 0644]
src/libpspp/hmap.h [new file with mode: 0644]
src/libpspp/hmapx.c [new file with mode: 0644]
src/libpspp/hmapx.h [new file with mode: 0644]
src/libpspp/i18n.c
src/libpspp/i18n.h
src/libpspp/ll.h
src/libpspp/misc.h
src/libpspp/model-checker.c [deleted file]
src/libpspp/model-checker.h [deleted file]
src/libpspp/sparse-array.c
src/libpspp/str.c
src/math/ChangeLog [deleted file]
src/math/OChangeLog [new file with mode: 0644]
src/math/automake.mk
src/math/box-whisker.c [new file with mode: 0644]
src/math/box-whisker.h [new file with mode: 0644]
src/math/coefficient.c
src/math/coefficient.h
src/math/covariance-matrix.c [new file with mode: 0644]
src/math/covariance-matrix.h [new file with mode: 0644]
src/math/design-matrix.c
src/math/design-matrix.h
src/math/extrema.c [new file with mode: 0644]
src/math/extrema.h [new file with mode: 0644]
src/math/factor-stats.c [deleted file]
src/math/factor-stats.h [deleted file]
src/math/group.c
src/math/group.h
src/math/histogram.c
src/math/histogram.h
src/math/linreg.c
src/math/linreg.h
src/math/merge.c
src/math/merge.h
src/math/moments.c
src/math/np.c [new file with mode: 0644]
src/math/np.h [new file with mode: 0644]
src/math/order-stats.c [new file with mode: 0644]
src/math/order-stats.h [new file with mode: 0644]
src/math/percentiles.c
src/math/percentiles.h
src/math/sort.c
src/math/sort.h
src/math/statistic.h [new file with mode: 0644]
src/math/time-series/ChangeLog [deleted file]
src/math/trimmed-mean.c [new file with mode: 0644]
src/math/trimmed-mean.h [new file with mode: 0644]
src/math/ts/ChangeLog [deleted file]
src/math/ts/OChangeLog [new file with mode: 0644]
src/math/ts/automake.mk
src/math/ts/innovations.c
src/math/tukey-hinges.c [new file with mode: 0644]
src/math/tukey-hinges.h [new file with mode: 0644]
src/output/ChangeLog [deleted file]
src/output/OChangeLog [new file with mode: 0644]
src/output/automake.mk
src/output/charts/ChangeLog [deleted file]
src/output/charts/OChangeLog [new file with mode: 0644]
src/output/charts/automake.mk
src/output/charts/box-whisker.c
src/output/charts/box-whisker.h
src/output/charts/dummy-chart.c
src/output/charts/plot-hist.c
src/output/charts/plot-hist.h
src/output/dummy-chart.c
src/ui/ChangeLog [deleted file]
src/ui/OChangeLog [new file with mode: 0644]
src/ui/automake.mk
src/ui/command-line.c [new file with mode: 0644]
src/ui/command-line.h [new file with mode: 0644]
src/ui/gui/ChangeLog [deleted file]
src/ui/gui/OChangeLog [new file with mode: 0644]
src/ui/gui/automake.mk
src/ui/gui/data-editor.c
src/ui/gui/find-dialog.c
src/ui/gui/helper.h
src/ui/gui/main.c
src/ui/gui/output-viewer.c
src/ui/gui/psppire.c
src/ui/gui/psppire.h
src/ui/source-init-opts.c [new file with mode: 0644]
src/ui/source-init-opts.h [new file with mode: 0644]
src/ui/syntax-gen.h
src/ui/terminal/ChangeLog [deleted file]
src/ui/terminal/OChangeLog [new file with mode: 0644]
src/ui/terminal/automake.mk
src/ui/terminal/command-line.c [deleted file]
src/ui/terminal/command-line.h [deleted file]
src/ui/terminal/main.c
src/ui/terminal/msg-ui.c
src/ui/terminal/terminal-opts.c [new file with mode: 0644]
src/ui/terminal/terminal-opts.h [new file with mode: 0644]
tests/ChangeLog [deleted file]
tests/OChangeLog [new file with mode: 0644]
tests/automake.mk
tests/bugs/crosstabs-crash.sh
tests/bugs/crosstabs-crash2.sh
tests/bugs/examine-crash.sh [new file with mode: 0755]
tests/bugs/examine-missing2.sh
tests/command/aggregate.sh
tests/command/attributes.sh [new file with mode: 0755]
tests/command/examine-extremes.sh
tests/command/examine.sh
tests/command/insert.sh
tests/command/longvars.sh
tests/command/npar-wilcoxon.sh [new file with mode: 0755]
tests/command/reliability.sh [new file with mode: 0755]
tests/dissect-sysfile.c
tests/expressions/valuelabel.sh
tests/libpspp/hmap-test.c [new file with mode: 0644]
tests/libpspp/hmapx-test.c [new file with mode: 0644]
tests/xforms/recode.sh

index d5b588430c5a44886ed3c9ba553ee6b405fbb40f..1d69e1696363c481df809fff20fbafe821dfce85 100644 (file)
@@ -1,4 +1,5 @@
 ABOUT-NLS
+ChangeLog
 Makefile
 Makefile.in
 aclocal.m4
@@ -30,3 +31,11 @@ pref.h
 reloc-ldflags
 stamp-h1
 texinfo.tex
+gitlog-to-changelog
+*~
+*.o
+*.lo
+*.a
+*.dirstamp
+*.deps
+*.la
diff --git a/AUTHORS b/AUTHORS
index 12b25ab7179ea4b5c75b3682cf48fb35bfc45900..43103dcd8fc7f3560560a29a97971699d176f2db 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,6 +14,11 @@ to other modules.
 including lib/gslextras and the linear regression features. Jason 
 is also an important contributor to GSL, which is used by PSPP. 
 
+* Rob van Son wrote the routine for calculation of the significance
+of the Wilcoxon matched pairs signed rank statistic used by the
+ NPAR TEST command.
+
+
 We also thank past contributors:
 
 * John Williams wrote an initial draft of the T-TEST procedure.
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644 (file)
index bcf78ac..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,2406 +0,0 @@
-2008-06-13  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Fix typo in AC_PREREQ command name.  Thanks to
-       Stepan Kasal <kasal@ucw.cz> for reporting the problem.
-
-2008-06-04  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Update version number to 0.6.0 in preparation for
-       release.
-
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Don't depend on memmem module, because
-       PSPP does not use memmem any longer.  Use
-       unilbrk/ulc-width-linebreaks module instead of the linebreak
-       module, because the latter was split up into multiple modules and
-       that's the one we actually need.
-
-2008-05-09  John Darrington <john@darrington.wattle.id.au>
-
-       * INSTALL: For obscure reasons gettext 0.17 requires that 
-       the string 'GNU pspp' occurs in some file in the root 
-       directory. Otherwise make distcheck fails with a very non-intuitive 
-       error message.  So for want of somewhere better I added it 
-       in INSTALL.
-
-       But since this string now appears in this ChangeLog file, it
-       could be taken out of INSTALL ...
-
-2008-04-19  John Darrington <john@darrington.wattle.id.au>
-
-       * configure.ac : Improve checking of ncurses availability.
-
-2008-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Properly report required version of libglade.
-       Thanks to unknown-1 <pspp@sjpaes.nl> for reporting this bug.
-
-2008-04-15  John Darrington <john@darrington.wattle.id.au>
-
-       * configure.ac : Replace AC_CHECK_LIB with AC_SEARCH_LIBS as
-       recommended by latest autoconf manual.
-
-2008-02-19  John Darrington <john@darrington.wattle.id.au>
-
-       * configure.ac INSTALL: We now depend on GTK+ 2.12
-
-2007-12-11  John Darrington <john@darrington.wattle.id.au>
-
-       * t-test-independent-samples-dialog.c: Quoted the group values, when
-       the group variable is a string variable.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Add ftello module.
-
-2007-11-05  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: No need for check for off_t or for the size of
-       float or long double any longer, as we don't use the results
-       anymore.  Also, no need to put #include <locale.h> into config.h
-       any longer, as this was only needed for --with-included-gettext,
-       which we have not supported for some time.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * Smake (GNULIB_MODULES): Add fatal-signal, tempname modules.
-
-2007-11-02  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Add isfinite, round modules.
-
-2007-10-12  Ben Pfaff  <blp@gnu.org>
-
-       Use trunc module from gnulib instead of our home-grown solution.
-       Patch #6224.
-
-       * Smake: Add trunc to module list.
-
-       * configure.ac: Don't need to check for trunc function any longer.
-
-2007-10-12  Ben Pfaff  <blp@gnu.org>
-
-       Use fseeko module from gnulib instead of our home-grown solution.
-       Patch #6228.
-
-       * acinclude.m4: Delete PSPP_OFF_T macro.
-
-       * configure.ac: Don't call AC_FUNC_FSEEKO or PSPP_OFF_T.
-
-2007-10-12  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add fprintf-posix, printf-posix, printf-safe,
-       snprintf-posix, sprintf-posix, vasprintf-posxi, vfprintf-posix,
-       vprintf-posix, vsnprintf-posix, and vsprintf-posix modules, which
-       allow us to use C99 format specifiers (e.g. 'z') in *printf.
-       Also, changed many formerly casted arguments in *printf calls to
-       use one of these format specifiers and drop the cast.
-2007-10-11  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Drop alloca, alloca-opt modules as we don't use them
-       anymore.
-
-2007-10-10  Ben Pfaff  <blp@gnu.org>
-
-       * acinclude.m4: Improve formatting.
-
-       * configure.ac: Ditto.  Don't check for headers whose presence is
-       never tested.  Don't use AC_C_CONST (we can assume that "const" is
-       implemented these days).  Don't pass default sizes to
-       AC_CHECK_SIZEOF, since modern Autoconf doesn't need them.  Don't
-       define FPREP_IEEE754, since it was not tested for.  Don't use
-       AC_FUNC_VPRINTF, since we never tested for it.
-
-2007-10-06 John Darrington <john@darrington.wattle.id.au>
-
-       * configure.ac INSTALL: Change libglade version requirement.
-       Thanks to Paul Brown for reporting this issue.
-
-2007-09-30  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Print a message indicating success at the end of
-       the run.
-
-       * INSTALL: Improve instructions.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * acinclude.m4 (PSPP_LC_PAPER): New macro.
-
-       * configure.ac: Use PSPP_LC_PAPER.
-
-2007-08-05  Ben Pfaff  <blp@gnu.org>
-
-       Bug #16189.  Reviewed by Jason Stover.
-       * acinclude.m4: If -lplot doesn't work by itself, also test with
-       typical X11 libraries.
-
-2007-07-27  Ben Pfaff  <blp@gnu.org>
-
-       Bug #19069.
-       * INSTALL: Improve installation instructions.
-       * README: Move prerequisites to INSTALL.
-       Reviewed by Jason Stover.
-
-       * configure.ac: Make PKG_CHECK_MODULES tests more user-friendly,
-       by having them give their errors at the end of the configuration
-       process instead of stopping it in the middle.  Patch #6116.
-       Reviewed by Jason Stover.
-
-2007-06-14  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Use xmalloca instead of xallocsa due to module renaming.
-       Update all uses.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add xallocsa to modules.
-
-2007-04-22  Ben Pfaff  <blp@gnu.org>
-
-       Implement model checker for testing purposes.
-       
-       Patch #5873.
-       
-       * Smake (GNULIB_MODULES): Add crypto/md4, fwriteerror,
-       gettimeofday.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Increment version to 0.4.3 due to snapshot posted
-       to alpha.gnu.org.
-       Suggested by John Darrington.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-
-       Use Gnulib's fpieee module instead of specifying -mieee by hand.
-
-       * Smake: Use fpieee module from Gnulib.
-
-       * configure.ac: Don't enable -mieee.
-
-2007-03-19  Ben Pfaff  <blp@gnu.org>
-
-       Work toward modernizing the build system by updating our Automake
-       and Autoconf dependencies and requiring libintl to be available
-       externally (if desired) instead of including a copy in the
-       distribution.
-
-       * Makefile.am (AUTOMAKE_OPTIONS): Require Automake 1.10 (or
-       later), which works better with systems that have a non-empty
-       $(EXEEXT).
-       (SUBDIRS): Drop intl.
-       (DISTCLEANFILES): Drop intl/plural.c.
-
-       * Throughout Makefile.am and the automake.mk files: Change
-       mkinstalldirs to $(MKDIR_P), to support the corresponding Automake
-       change.
-
-       * Smake (GNULIB_MODULES): Use gettext-h instead of gettext module.
-       (all): Don't create intl directory.
-       (gettextize): Don't use --intl flag.
-
-       * configure.ac: Require Autoconf 2.60 or later.  Use external
-       gettext.  Drop intl/Makefile from config files.
-
-2007-02-25  Ben Pfaff  <blp@gnu.org>
-
-       Thanks to Jason Stover for verifying that this patch helps under
-       NetBSD.
-
-       * acinclude.m4: Rename PSPP_ENABLE_WARNING to PSPP_ENABLE_OPTION,
-       because it's useful for more than warnings.
-
-       * configure.ac: Add PSPP_ENABLE_OPTION(-mieee) to improve IEEE
-       floating-point conformance on Alpha and SH architectures.  Also,
-       check for fpsetmask function (available on BSDs).
-
-Mon Feb 19 10:52:21 2007  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Add dirname module, remove canonicalize
-       module.  Corresponds to changes in src/data/file-name.c.
-
-Sat Feb 17 09:22:32 2007  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Add tmpfile module, which fixes the use
-       of the tmpfile function under Windows.
-
-Fri Feb 16 10:50:38 2007  Ben Pfaff  <blp@gnu.org>
-
-       Better support cross-compiling by using CC_FOR_BUILD and
-       EXEEXT_FOR_BUILD for q2c.
-       
-       * Makefile.am: Add CC_FOR_BUILD, EXEEXT_FOR_BUILD variables.  Use
-       in .q.c rule.
-
-       * acinclude.m4: Add PSPP_CC_FOR_BUILD macro.
-
-       * configure.ac: Call PSPP_CC_FOR_BUILD.
-
-Mon Feb 12 16:39:18 2007  Ben Pfaff  <blp@gnu.org>
-
-       * README: Note that iconv is required.
-
-       * configure.ac: Enforce iconv requirement.
-
-Thu Feb  8 14:56:18 2007  Ben Pfaff  <blp@gnu.org>
-
-       Reduce platform dependence.
-
-       * Makefile.am: Don't add -Dunix or -D__MSDOS__ to compiler command
-       line.  Add $(top_builddir)/intl to include path to fix building
-       with the included libintl.
-
-       * Smake (GNULIB_MODULES): Add `canonicalize', `sys_stat',
-       `mkstemp' modules.  Remove `stat-macros' module, which is no
-       longer what we want, because what we want is provided by sys_stat
-       now, and remove its inclusions.  Remove `strstr' module, which is
-       no longer in gnulib.  Remove `readlink', `xreadlink', because we
-       no longer use either function.
-
-       * configure.ac: Move gl_EARLY before AC_PROG_CC, where the gnulib
-       manual says it should be.  Check for presence of execl, fork,
-       and popen.  Drop check for unix versus msdos as host OS.
-
-Sat Nov  4 15:59:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Check for the "round" function added in C99.
-
-Tue Oct 31 19:55:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Add `mempcpy' module.
-
-Tue Oct 31 19:29:05 2006  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Drop tests for strchr, strrchr because now we
-       assume a C89 compliant library.  (Gnulib makes this assumption so
-       we might as well too.)
-
-Sun Oct 29 14:08:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake (GNULIB_MODULES): Remove `restrict' from modules, because
-       recent gnulib doesn't have such a module.
-
-Mon Jul 17 18:23:38 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add --doc-base=gl/doc to gnulib-tool invocation, which is
-       required by recent gnulib.
-
-Sun Jul 16 19:51:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add xsize to GNULIB_MODULES.
-
-Wed Jul 12 13:41:18 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add check_PROGRAMS and define to empty.
-
-Sat Jul  1 15:32:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add noinst_PROGRAMS and define to empty.
-
-Tue May  9 20:46:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add stdarg to GNULIB_MODULES.
-
-Sun May  7 09:27:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * po/en_GB.po : Removed.  Now that messages talking about coloUrs have 
-       been removed, it does nothing.
-
-Tue May  2 10:43:30 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * Bumped the minor version number from 0.4.1 to 0.4.2 to reflect 
-        changes to system file format.
-
-Mon Apr 24 14:12:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add exit to GNULIB_MODULES.
-
-Sun Apr 23 20:34:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add linebreak to GNULIB_MODULES.
-
-Sat Apr 15 21:45:40 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of src/libpspp/debug-print.h and all its uses.  (There
-       were few real users, but many inclusions of its header file.)
-
-Sat Apr 15 19:51:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of our own int32 type in favor of the standard int32_t
-       type.
-       
-       * configure.ac: Don't need to check the sizes of integer types
-       anymore.
-
-Sat Apr 15 19:13:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac, acinclude.m4: Complain about missing prerequisites
-       in a group at the end of configuration, not piecemeal.  This
-       should make building PSPP less frustrating.  Thanks to John
-       Darrington for the suggestion.
-
-Sat Apr 15 18:17:15 2006  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Move code into acinclude.m4 to make the configure
-       script more readable.
-
-       * acinclude.m4: New functions from configure.ac.
-
-Mon Apr  3 11:01:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: (GNULIB_MODULES) Add strsep.
-
-Thu Mar 30 15:50:05 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Enable -Wdeclaration-after-statement warning if
-       available.
-
-       * acinclude.m4: Add macro for checking whether a warning is
-       supported.
-
-Mon Mar 20 16:32:11 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Require "unistd" gnulib module.  Removed tests for
-       HAVE_UNISTD_H from source code.
-
-Sat Mar  4 13:20:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Get rid of pref.h.orig.
-
-       * pref.h.orig: Removed.  Moved SHORT_NAME_LEN, LONG_NAME_LEN to
-       src/data/variable.h.  Removed GLOBAL_DEBUGGING entirely, changing
-       all references to DEBUGGING.  Moved P_tmpdir to
-       src/data/make-file.c.  Moved NO_CHARTS to
-       src/output/charts/automake.mk.
-
-Sat Mar  4 12:58:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Move GCC attribute declarations to
-       new file src/libpspp/compiler.h.
-
-Sat Mar  4 12:27:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Require "intprops" gnulib module.
-
-       * acinclude.m4: Remove BLP_INT_DIGITS.  Now we use the intprops.h
-       header file instead.
-
-       * configure.ac: Don't call BLP_INT_DIGITS.
-
-Sat Mar  4 11:53:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       * acinclude.m4: Remove BLP_RANDOM.  Its results were unused.
-       Remove BLP_IS_SPRINTF_GOOD.  We now assume that the system's
-       sprintf() returns the correct value.
-
-       * configure.ac: Don't call those macros.
-
-John Darrington:
-
-       * Deleted Make.build (inserted its contents into Makefile.am).
-       
-       * Moved the version number to 0.4.1
-
-       * Moved lib/linreg/linreg.[ch] and lib/linreg/coefficient.[ch] to
-         src/math/linreg.
-
-       * Moved the psppire gui into src/ui/gui and the gtk_sheet widget 
-          into lib/gtksheet.
-
-       * Replaced recursive automake system with non-recursive one.
-
-       * Moved files into subdirectories. See src/ChangeLog for details.
-
-Sat Feb 11 21:57:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: (GNULIB_MODULES) Add memcasecmp.
-
-       * configure.ac: Remove existing checks for readline, replacing
-       them by a call to PSPP_READLINE.
-
-       * acinclude.m4: Add PSPP_READLINE macro based on gnulib test for
-       readline.  However, we only accept a readline installation if (1)
-       the header files are in the normal readline/ directory and (2) the
-       history library is also available.  If both criteria are met, we
-       declare HAVE_READLINE.  This reduces the #ifdefs to actually use
-       readline to something manageable.
-
-       * pref.h.orig: Move DIR_SEPARATOR, PATH_DELIMITER definitions to
-       src/filename.h.
-
-Wed Jan 25 21:48:20 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: (po/POTFILE.in) Exclude dotfiles.
-
-Sat Nov 27 20:29:19 2005 Jason Stover <jason@sakla.net>
-
-       * Binary encoding for categorical variables.
-       * Routines for design matrices.
-       
-Thu Oct 20 18:19:58 2005  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Improve error messages.  Thanks to Jaap-Andre de
-       Hoop <j.dehoop@data-assist.nl>.
-
-Wed Oct 12 20:33:07 2005 Jason Stover <jstover@sdf.lonestar.org>
-
-       * regression.q: Initial version of the REGRESSION procedure.
-       
-Sun Sep 25 16:11:09 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Handles `examples' as a subdirectory instead of a
-       dist-hook.  The dist-hook copied examples/CVS into the
-       distribution.  Thanks to James R. Van Zandt <jrvz@comcast.net> for
-       reporting the problem.
-
-Mon Sep 19 10:24:10 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Add `check' target for convenience.  Add
-       --tests-base=tests to gnulib-tool invocation to compensate for
-       bug.
-
-Sat Sep 17 15:57:32 2005 Jason Stover <jason@sakla.net>
-
-       Added lib/linreg for procedures that use ordinary least squares.
-       
-Sat Sep 17 11:01:44 2005  Ben Pfaff  <blp@gnu.org>
-
-       Adapt to newer versions of gnulib.
-
-       * Smake: Put gnulib options directly on its command line, instead
-       of embedding them in configure.ac.
-
-       * configure.ac: Remove gnulib option commands.
-
-Fri Aug  3 07:22:28 2005  Ben Pfaff  <blp@gnu.org>
-
-       * PSPP 0.4.0 released.
-
-Sun Jul 31 10:49:47 2005  Ben Pfaff  <blp@gnu.org>
-
-       Adopt use of gnulib for portability.
-
-       * Makefile.am: Add gl to SUBDIRS.  Add gl/m4 to aclocal include
-       path.  Get rid of pkgdocdir data.  Move noinst_DATA to EXTRA_DIST.
-
-       * README.CVS: Add instructions for fetching gnulib.
-
-       * Smake: Rewrite to run gnulib-tool.  Avoid use of gettextize in
-       normal case (it was unmaintainable).  Just use autoreconf
-       --install to do most of the work.  Rewrite rule for POTFILES.in
-       for non-GNU make compatibility.
-
-       * configure.ac: Add gnulib commands.  Specify gettext version
-       0.14.5 to placate autopoint.  Check that off_t is an integer type,
-       because Solaris can sometimes declare it as a struct.  Drop
-       explicit checks for gnulib-supported functionality.  Fix typo in
-       msdos check.
-
-       * pref.h.orig: Define __attribute__ to avoid wart in gnulib.
-       Don't #include <libintl> and define gettext, _, N_, because gnulib
-       wants to do the same thing.
-
-Sun Jul 24 20:31:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Don't detect libgmp anymore, because we eliminated
-       the dependency.
-
-       * NEWS: Update.
-
-Mon Jul  4 17:59:54 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add pspp-mode.el to EXTRA_DIST.
-
-Wed May  4 08:49:13 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * README.CVS Smake: Added a CONFIGUREFLAGS variable.
-       * INSTALL: Mentioned build dependencies.
-
-Mon May  2 22:37:39 2005  Ben Pfaff  <blp@gnu.org>
-
-       * INSTALL: Mention dependencies.  Thanks to Jaap-Andre de Hoop
-       <j.dehoop@data-assist.nl> for the suggestion.
-
-       * NEWS, README: Update.
-
-Sun May  1 15:00:09 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * pspp-mode.el: Now supports syntax highlighting, indentation and
-       generally works a lot better.
-
-Thu Apr 28 10:24:47 WST 2005 John Darrington <john@darrington.wattle.id.au> 
-
-       * Changed all copyright notices to contain the FSF's new address.
-
-Thu Apr 14 2005 John Darrington
-
-       * AUTHORS:  Added note about the long variable names extension.
-
-       * pref.h.orig: Added definitions for variable names lengths.
-
-Thu Mar  3 22:06:19 WST 2005 John Darrington <john@darrington.wattle.id.au> 
-
-       * configure.ac: Added AC_PROG_RANLIB --- needed by autoconf 1.9
-
-Mon Feb 28 23:16:58 2005  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Check for perl.  Check for bool.  Substitute
-       makefiles in src/expressions.  Don't substitute makefile in
-       deleted directory lib/julcal.
-
-       * pref.h.orig: (macro MALLOC_LIKE) New macro.
-       (macro flt64) Moved to src/sfmP.h.
-       (macro FLT64_MAX) Moved to src/sfmP.h.
-
-Mon Feb 21 15:04:55 WST 2005 John Darrington <john@darrington.wattle.id.au> 
-
-       * configure.ac: Added a --without-valgrind option to cope with
-       building on machines with a broken valgrind installation
-
-Fri Jan  7 08:01:02 WST 2005 John Darrington <john@darrington.wattle.id.au> 
-
-       * configure.ac pref.h.orig: Compilation with libplot is now optional
-       by sacrificing the chart features.
-
-Sun Nov 28 19:24:02 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Smake: Change -a to -pR in cp invocations for SUSv3 compliance.
-
-Mon May 31 17:21:25 2004  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Check for large file support.  Get rid of
-       posix_fadvise check--for some reason glibc 2.3.2 segfaults when I
-       call it and I just couldn't figure out what was going on.
-
-Sun May 30 18:19:03 2004  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Check for valgrind/valgrind.h.
-
-Mon Mar 29 15:22:48 2004  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * configure.ac: Check for posix_fadvise.
-
-Tue Mar 23 14:21:12 WAST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * Removed dcdflib and replaced with a dependency upon the
-        GNU Scientific library instead.
-
-Sat Mar 20 13:55:36 2004  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-Wed Feb 11 23:54:15 2004  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Don't meddle with __WIN32__, __MSDOS, __DJGPP__,
-       __CYGWIN32__, __unix__, or unix anymore, and deal with some of the
-       consequences.  Declare ATTRIBUTE instead of meddling withe
-       __attribute__.  Declare UNUSED instead of unused.  Add macros
-       NO_RETURN, PRINTF_FORMAT, SCANF_FORMAT.  Reformat gettext, N_, _
-       macros.  Move alloca()-related stuff to src/alloc.h and simplify.
-       Get rid of PAGED_STACK entirely.  Remove mkdir macro definition.
-       Get rid of obsolete "procedure-specific options".
-
-2004-01-23  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.am (SUBDIRS): Remove intl.
-       * configure.ac (AC_CONFIG_FILES): Remove intl/Makefile.
-
-Tue Dec 30 22:23:40 WST 2003 John Darrington <john@darrington.wattle.id.au> 
-       
-       * Fixed floating point rounding bug in percentiles calculation
-
-Sat Dec 27 16:16:49 2003  Ben Pfaff  <blp@gnu.org>
-
-       * configure.ac: Add -Wmissing-prototypes flag to gcc.
-
-       * TODO: Updated.
-
-Wed Dec 17 12:19:40 WAST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * Added an --enable-debug flag to configure
-
-2003-12-13  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.am (EXTRA_DIST): Add mkinstalldirs.
-       * configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
-
-
-Thu Dec 11 19:35:32 WST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * Removed autogenerated files from the CVS archive
-
-        * removed the included getopt.c as it failed to build under some
-        systems.
-
-Thu Dec 11 00:12:19 2003  Ben Pfaff  <blp@gnu.org>
-
-       * Update build system to Autoconf 2.58, Automake 1.7, gettext
-       0.12.1.
-
-2003-12-08  gettextize  <bug-gnu-gettext@gnu.org>
-
-       * Makefile.am (SUBDIRS): Add m4.
-       (ACLOCAL_AMFLAGS): New variable.
-       (EXTRA_DIST): Add config.rpath.
-       * configure.in (AC_CONFIG_FILES): Add po/Makefile.in,
-
-Sun Jan  2 21:24:32 2000  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Require Automake 1.4 or later.  It's been out for
-       almost a year now, so why haven't you installed it? :-)
-
-       * TODO: Updated.
-
-       * configure.in: Updated version number.  Check for libgmp.  Check
-       of fenv.h.  Check for feholdexpect().
-
-       * pref.h.orig: Don't include debug-print.h by default.  Don't
-       disable __attribute ((unused))__ for gcc 2.7.2.  Remove LOAD_2,
-       STORE_2.  Comment fixes.
-
-       * Updated copyright notices in all files.
-
-Fri Mar 12 12:38:55 1999  Ben Pfaff  <blp@gnu.org>
-
-       * Forked 0.3.0.
-
-Tue Mar  9 12:46:31 1999  Ben Pfaff  <blp@gnu.org>
-
-       * Released 0.2.3.
-       
-       * TODO: Updated.
-
-Tue Jan  5 15:18:07 1999  Ben Pfaff  <blp@gnu.org>
-
-       * Released 0.2.2.
-
-       * TODO: Update from Zvi Grauer <z.grauer@sims.csuohio.edu>.
-
-Thu Nov 19 12:34:55 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Released 0.2.1.
-
-Sun Aug  9 11:11:32 1998  Ben Pfaff  <blp@gnu.org>
-
-       * LANGUAGE: Updated.
-
-Sat Aug  8 00:19:08 1998  Ben Pfaff  <blp@gnu.org>
-
-       * LANGUAGE: Updated.
-
-       * examples/: New directory.
-
-       * Made patchlevel 95.
-
-Tue Aug  4 23:47:31 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Bump version to 0.1.22 (0.2.0 release candidate).
-
-       * configure.in: Remove --enable-Werror, new option
-       --enable-debugging.  New gcc option -Wpointer-arith.
-
-       * pref.h.orig: Don't enable debugging by default (now a configure
-       option).  Use __inline__ instead of inline with gcc (partial -ansi
-       -pedantic support).
-       (macro local_strdup) Removed.
-
-       * Made patchlevel 94.
-       
-Wed Jul 29 22:03:11 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Bump version to 0.1.21 (0.2.0 release candidate).
-
-       * debian/: Removed.
-
-       * Makefile.am: Don't copy debian/ into distribution.
-       
-       * pref.h.orig: Only enable `unused' attribute if gcc 2.8.0 or
-       later is used.
-
-Sun Jul  5 14:20:04 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bump version to 0.1.20 (0.2.0 release candidate).
-
-       * Made patchlevel 93.
-
-Sun Jul  5 00:13:58 1998  Ben Pfaff  <blp@gnu.org>
-
-       * README: Updated.
-
-       * TODO: Updated.
-
-       * configure.in: Remove -Wno-unused from default gcc flags.
-
-       * pref.h.orig: Add new #define, `unused', which under gcc expands
-       to an explanation to the compiler that a function argument is
-       unused, and expands to the null string under other compilers.
-
-Mon Jun  1 14:33:02 1998  Ben Pfaff  <blp@gnu.org>
-
-       * LANGUAGE: Updated.
-
-       * configure.in: Bump version to 0.1.19.
-
-       * Made patchlevel 92.
-
-Sun May 31 00:55:13 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-               
-       * configure.in: Generate Makefiles for lib/gmp/{,mpn,mpf}/.
-
-       * Made patchlevel 91.
-
-Fri May 29 21:43:09 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * LANGUAGE: Updated.
-
-       * unconfigure: Remove TeX cruft from doc/.
-       
-       * Made patchlevel 90.
-
-Mon May 25 12:41:54 1998  Ben Pfaff  <blp@gnu.org>
-
-       * BUGS: Updated.
-
-       * LANGUAGE: Updated.
-
-       * TODO: Updated.
-
-       * configure.in: Bumped version number up to 0.1.18.
-
-       * Made patchlevel 89.
-
-Sun May 24 22:39:55 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 88.
-
-Sat May 23 23:21:43 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * configure.in: Remove gamma from replaceable functions.
-
-       * Made patchlevel 87.
-
-Fri May 22 00:02:33 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Add gamma to list of functions with replacements.
-
-       * Made patchlevel 86.   
-
-Wed May 20 00:00:12 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 85.
-
-Sat May 16 19:38:49 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 84.
-
-Tue May 12 16:13:48 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * unconfigure: Don't delete Makefile.in under intl/.
-       
-       * Made patchlevel 83.
-
-Thu May  7 23:16:26 1998  Ben Pfaff  <blp@gnu.org>
-
-       * unconfigure: Add some more files to reap.
-
-       * Made patchlevel 82.
-
-Tue May  5 13:17:59 1998  Ben Pfaff  <blp@gnu.org>
-
-       * acconfig.h: Add HAVE_GOOD_RANDOM definition.
-
-       * acinclude.m4: New macro BLP_RANDOM.
-
-       * configure.in: Use new BLP_RANDOM macro.
-
-       * unconfigure: New file.
-       
-       * Made patchlevel 81.
-       
-Fri Apr 24 12:42:14 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Remove bad comment.
-
-       * AUTHORS: Removed Brad Appleton.
-       
-       * TODO: Updated.
-
-       * configure.in: Remove `satisfy automake' bit.  Don't generate
-       avllib Makefile, since we don't use avllib anymore.
-
-       * pref.h.orig: Define PSPP.
-
-       * Made patchlevel 80.
-
-Wed Apr 15 12:59:39 1998  Ben Pfaff  <blp@gnu.org>
-
-       * AUTHORS, BUGS, LANGUAGE, README, THANKS: No longer generated
-       from HTML.  This caused a lot of deletions from the Makefile.am.
-
-       * TODO: Updated.
-       
-       * Made patchlevel 79.
-       
-Tue Apr 14 00:48:00 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * configure.in: Check for unistd.h.  Fix AC_LN_S (should have been
-       AC_PROG_LN_S).
-
-       * Made patchlevel 78.  Must have missed 77 in there somewhere :-)
-       
-Mon Mar  9 15:40:40 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 76.
-
-       * configure.in: Bumped version up to 0.1.16.
-
-1998-03-05  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bumped version up to 0.1.15.
-
-1998-02-23  Ben Pfaff  <blp@gnu.org>
-
-       * acinclude.m4: Add BLP_INT_DIGITS and BLP_IS_SPRINTF_GOOD macros.
-
-       * configure.in: Those macros came from here.  Better modularity
-       this way.  Bump version up to 0.1.14.
-
-       * pref.h.orig: (macros CONFIG_PATH, INCLUDE_PATH, GROFF_FONT_PATH)
-       Removed.
-       
-       * Made patchlevel 75.
-
-1998-02-23  Ben Pfaff  <blp@gnu.org>
-
-       * acconfig.h: Hard-code PACKAGE and GNU_PACKAGE as "PSPP" and "GNU
-       PSPP" respectively.
-
-       * configure.in: Call the package pspp instead of PSPP.  Don't
-       define PACKAGE and GNU_PACKAGE symbols.  Add replacement function
-       for strtok_r.
-
-       * TODO: Updated.
-       
-       * Made patchlevel 74.
-
-1998-02-16  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Remove a few now-useless targets.
-
-       * TODO: Updated.
-
-       * configure.in: Bump version up to 0.1.13.
-
-       * reconfigure: Don't assume . is in PATH.
-
-       * Made patchlevel 73.
-
-Fri Feb 13 15:35:03 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bump version up to 0.1.12.
-
-       * TODO: Updated.
-
-       * pref.h.orig: Make __unix equivalent to unix and __unix__; don't
-       require any of these to be defined to 1, just defined.  Invert
-       sense of some tests from testing for unix to testing for not being
-       msdog.
-
-       * Made patchlevel 72.
-
-Thu Feb  5 00:22:58 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 71.
-
-       * configure.in: Bump version up to 0.1.11.
-
-Tue Feb  3 16:12:34 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 70.
-
-       * configure.in: Bump version up to 0.1.10.
-
-Fri Jan 23 00:17:18 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 69.
-
-Thu Jan 22 00:35:52 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 68.
-
-Sun Jan 18 00:30:18 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Add ieeefp.h to list of headers to check for.
-
-       * Made patchlevel 67.
-
-Tue Jan 13 23:44:16 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Add sys/wait.h to list of headers to check for.
-
-       * Made patchlevel 66.
-       
-Sun Jan 11 21:30:09 1998  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bump version up to 0.1.9.
-       
-       * pref.h.orig (STORE_2): Fix parentheses.  From Alexandre
-       Oliva <oliva@dcc.unicamp.br>.
-
-       * Made patchlevel 65.
-       
-Sat Jan 10 23:59:06 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 64.
-
-Sat Jan 10 02:10:15 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * pref.h.orig: Comment fixes.
-       (macro second_lowest_flt64) New.
-
-       * Made patchlevel 63.
-
-Thu Jan  8 22:27:03 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-       
-       * Made patchlevel 62.
-
-Mon Jan  5 11:18:37 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 61.
-
-Sun Jan  4 18:10:29 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * pref.h.orig: (local_strdup) [HAVE_ALLOCA && PAGED_STACK &&
-       __GNUC__] Rewritten for space and time efficiency and to evaluate
-       its argument only once.
-
-       * Made patchlevel 60.
-
-Sat Jan  3 16:51:20 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 59.
-
-Fri Jan  2 01:38:37 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * config.sub: Got tired of `i686-unknown-linux: Unknown system',
-       so I made 686 equivalent to 586.
-
-       * pref.h.orig: (macros ASCII_*, HTML_*, PS_*) Removed.
-
-       * Made patchlevel 58.
-
-Thu Jan  1 11:50:47 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 57.
-
-Fri Dec 26 15:43:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 56.
-
-Wed Dec 24 22:34:55 1997  Ben Pfaff  <blp@gnu.org>
-
-       * reconfigure: regularized option syntax.
-
-       * configure.in: Bumped version to 0.1.8.  Changed name from pspp
-       to PSPP.  Added lib/dcdflib/Makefile to list of output files.
-
-       * Made patchlevel 55.
-
-Sun Dec 21 15:58:52 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * acconfig.h: Reformat.
-
-       * configure.in: Bumped version to 0.1.7.
-
-       * Made patchlevel 54.
-
-Fri Dec  5 23:38:12 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Replaced prep.ai.mit.edu with ftp.gnu.org and .gnu.ai.mit.edu
-       with .gnu.org, everywhere.
-
-Fri Dec  5 23:02:40 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Replaced remaining instances of Fiasco with PSPP.
-
-       * Made patchlevel 53.
-
-Fri Dec  5 22:51:18 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Every instance of the name Fiasco, throughout every file,
-       replaced in-place with PSPP, with the exceptions of a few files
-       that had `fiasco' in their names; these were renamed.
-
-       * Made patchlevel 52.
-       
-Fri Dec  5 21:50:52 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: (macros NO_HTML, HTML_DEFAULT_OUTPUT_FILE) New
-       macros.
-
-       * TODO: Updated.
-
-       * Made patchlevel 51.
-
-Tue Dec  2 14:35:12 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * configure.in: Bumped version to 0.1.6.
-
-       * Made patchlevel 50.   
-
-Sat Nov 22 01:20:32 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 49.
-
-Fri Nov 21 00:11:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 48.
-
-Sun Nov 16 01:31:38 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 47.
-
-Fri Nov 14 00:17:48 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 46.
-
-       * configure.in: Bumped version to 0.1.5.
-
-Tue Oct 28 16:07:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bumped version to 0.1.4.
-
-       * TODO: Updated.
-
-       * Made patchlevel 45.
-
-Wed Oct  8 15:55:50 1997  Ben Pfaff  <blp@gnu.org>
-
-       * intl: Upgraded from sources to gettext-0.10.32.
-
-       * configure.in: Bumped version to 0.1.3.
-
-       * Made patchlevel 44.
-       
-Tue Oct  7 20:21:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (dist-hook) Use $(top_srcdir).
-
-       * pref.h.orig: (MAX_WORKSPACE) Enlarge to 4 MB (from 1 MB).
-
-       * Made patchlevel 43.
-       
-Sun Oct  5 15:52:37 1997  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Bumped version to 0.1.2.
-       (strerror) Replace instead of check.  From Alexandre Oliva
-       <oliva@dcc.unicamp.br>.
-
-       * pref.h.orig: Include `debug-print' instead of
-       `src/debug-print.h'.
-
-       * Made patchlevel 42.
-
-Sat Oct  4 16:19:44 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Comment fixes.
-       (local_strdup) [HAVE_ALLOCA && PAGED_STACK &&
-       __GNUC__] Use local_alloc() instead of alloca(), as local_alloc()
-       isn't simply an alias for alloca().
-
-       * configure.in: Bumped version to 0.1.1.
-
-       * Made patchlevel 41.
-
-Sat Oct  4 02:13:00 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 40.
-
-Sun Sep 21 00:07:09 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 39.
-
-Thu Sep 18 21:42:27 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: (CONFIG_PATH) [unix] Add /usr/local/etc/fiasco,
-       /usr/etc/fiasco to search path.
-
-       * Made patchlevel 38.
-               
-Wed Aug 20 14:20:06 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (noinst_DATA) Removed ANNOUNCE, HELP-WANTED.
-       (EXTRA_DIST) Removed ANNOUNCE, FAQ, HELP-WANTED, mk-web-dist.
-       (MAINTAINERCLEANFILES) Removed ANNOUNCE, FAQ, HELP-WANTED.
-
-       * Made patchlevel 37.
-
-Wed Aug 20 12:48:25 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (doc/ANNOUNCE.html, ANNOUNCE, FAQ, doc/FAQ.html,
-       HELP-WANTED) Removed.
-       (docfiles) Removed ANNOUNCE, FAQ, HELP-WANTED.
-
-       * mk-web-dist: Removed.
-
-       * Made patchlevel 36.
-
-Mon Aug 18 18:06:12 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * pref.h.orig: (macro DEFAULT_COMPAT) Removed.
-
-       * Made patchlevel 35.
-
-Sun Aug 17 22:48:36 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 34.
-
-Sat Aug 16 10:48:29 1997  Ben Pfaff  <blp@gnu.org>
-
-       * In many files, in this directory and others, messages were
-       rephrased to eliminate or reduce usage of certain deprecated terms
-       at suggestion of rms.
-       
-       * Makefile.am: (EXTRA_DIST) Removed unix2dos.pl.
-       (MAINTAINERCLEANFILES) Removed doc/ANNOUNCE.html, doc/README.html.
-       (docfiles-recursive) Removed.
-
-       * TODO: Updated.
-
-       * mk-web-dist: Doesn't produce any distributions at all, just a
-       webpage.  Doesn't configure the distribution.  Changed list of
-       files installed.
-
-       * pref.h.orig: s/VER_PCP40/VER_PC/; s/VER_WIN61/VER_WND/;
-       s/VER_X40/VER_X/; All references changed.
-
-       * Made patchlevel 33.
-
-Thu Aug 14 22:02:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Comment fixes.  Uses $(VERSION) instead of contents
-       of VERSION file.
-       (EXTRA_DIST) Remove fiasco.ide, mk-bc5-dist.
-       (docfiles-recursive) Works if doc/Makefile doesn't exist.
-       (DIST_BC5_ROOT) Renamed DISTBC5_DISTROOT.
-       (DISTBC5_BC5ROOT) New var.
-       (dist-bc5) Passes $(DISTBC5_BC5ROOT).
-
-       * TODO: Update.
-
-       * acinclude.m4: Remove blp_VERSION_CHEAT kluge.
-
-       * configure.in: Don't use blp_VERSION_CHEAT kluge.
-
-       * mk-web-dist, reconfigure: Extract version number from
-       configure.in.
-
-       * pref.h.orig: (CONFIG_PATH, INCLUDE_PATH, GROFF_FONT_PATH)
-       [__MSDOS__] Fixed bad use of backslashes.
-
-       * reconfigure: Pass $VERSION to Makefile.
-
-       * Made patchlevel 32.
-
-Thu Aug 14 11:49:35 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST, docfiles) Add ONEWS.
-       (docfiles) Depends on docfiles-recursive.
-       (docfiles-recursive) New target, call make for `docfiles' target
-       in doc directory.
-       (dist-bc5) Adds `foo' second arg to mk-bc5-dist.
-       (.PHONY) Add docfiles.
-
-       * mk-bc5-dist: Checks that it is passed a second arg of `foo'.
-
-       * reconfigure: Changed == operators to = as arguments to `test'.
-       No longer uses bash -v switch.
-
-       * mk-distribution: Renamed mk-web-dist, all references changed.
-       Now takes several options, added help.  No longer uses -uv
-       options.
-
-       * Made patchlevel 31.
-
-Tue Aug  5 13:56:39 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (MAINTAINERCLEANFILES) Add HELP-WANTED.
-       (EXTRA_DIST) Add ONEWS.
-
-       * Made patchlevel 30.
-
-Sun Aug  3 11:30:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (noinst_data, docfiles) Added HELP-WANTED.
-       (EXTRA_DIST) Added configure, mk-bc5-dist, unix2dos.pl,
-       HELP-WANTED.
-       (HELP-WANTED) Generated from doc/HELP-WANTED.html.
-       (dist-bc5) New target.
-
-       * TODO: Updated.
-
-       * mk-distribution: Fixed bugs, added HELP-WANTED.
-
-       * reconfigure: When invoking Makefile.am, pass
-       top_srcdir=. explicitly.
-
-       * unix2dos.pl: New file.
-
-       * Made patchlevel 29.
-
-Thu Jul 17 21:49:13 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 28.
-
-Thu Jul 17 01:43:25 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Remove inactive .html suffix rule.
-       New rules to generate doc/ANNOUNCE.html and doc/README.html from
-       corresponding .in files.
-       (EXTRA_DIST) Add VERSION, fiasco.ide, mk-distribution.
-       (MAINTAINERCLEANFILES) Add doc/ANNOUNCE.html, doc/README.html.
-
-       * acinclude.m4: (blp_VERSION_CHEAT) New macro.
-
-       * configure.in: Forces _GNU_SOURCES not only to be defined, but to
-       a value of 1.  Substitutes VERSION from the new file VERSION.
-       Removed DEBIAN reference.  Checks for sys/mman.h header.
-
-       * pref.h.orig: (macro gettext) Don't put parentheses in the
-       expansion.
-       (macro N_) Same.
-
-       * reconfigure: Sets -ev in shell.  Doesn't try to pass
-       --include-deps to configure (it's an automake flag!).  Moved `make
-       docfiles'.
-
-       * sysdeps/borlandc4.0/README, sysdeps/borlandc4.0/_read.c,
-       sysdeps/borlandc4.0/_write.c, sysdeps/borlandc4.0: Removed.
-
-       * VERSION: New file.
-
-       * fiasco.ide: New file.
-
-       * mk-distribution: New file.
-
-       * Made patchlevel 27.
-       
-Fri Jul 11 23:00:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updates.
-
-       * Made patchlevel 26.
-
-Fri Jul 11 14:08:21 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: __CYGWIN32__ is a form of __unix__.
-
-       * reconfigure: Add -k for make maintainer-clean.
-
-       * Made patchlevel 25.
-
-Thu Jul 10 22:13:07 1997  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Add "-D_GNU_SOURCE" to CPPFLAGS to force GNU
-       glibc extensions to be detected.
-
-       * Made patchlevel 24.
-
-Sun Jul  6 19:13:07 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Include "src/debug-print.h" instead of
-       "debug-print.h".
-       (macros local_alloc, local_free) More robust under Checker: put
-       their allocations in namespace different from malloc()/free().
-
-       * Made patchlevel 23.
-
-Sat Jul  5 23:42:14 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updates.
-
-       * Made patchlevel 22.
-
-Fri Jul  4 13:20:47 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Removed orphaned-rules.
-       (docfiles) Removed ChangeLog, COPYING.
-       (html, maintainer-clean-hook, install-data-hook) Removed.
-
-       * reconfigure: Added --help option.  Calls configure again even if
-       --no-include-deps.
-
-       * Made patchlevel 21.
-
-Wed Jun 25 22:47:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Require Automake 1.2.
-       (dist-hook) Don't copy config dir.
-       (EXTRA_DIST, MAINTAINERCLEANFILES) Add FAQ.
-       (docfiles) Made a variable as well as a target; added ChangeLog,
-       COPYING, FAQ, INSTALL, TODO.
-       (html, maintainer-clean-hook, install-data-hook, debian,
-       debian-clean, debian-clean-full) New targets.
-
-       * orphaned-rules: Removed.
-
-       * configure.in: Bumped up to version 0.1.0.
-
-       * reconfigure: New options --enable-nls, --no-include-deps.
-       Comment fixes.
-
-       * Made patchlevel 20.
-
-Sun Jun 22 22:10:27 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 19.
-
-Sun Jun 15 16:44:14 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Comment fixes.  Includes debug-print.h.
-       (DEMAND_PAGE, ALWAYS_PAGE, NEVER_PAGE) Removed.
-
-       * Made patchlevel 18.
-
-Sun Jun  8 01:25:40 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 17.
-
-Fri Jun  6 22:41:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updates.
-
-       * pref.h.orig: Reformatted macros.
-       [!ENABLE_NLS] Defines gettext() as a trivial substitution to allow
-       gcc to give warnings on printf().
-
-       * Made patchlevel 16.
-       
-Thu Jun  5 23:01:49 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 15.
-
-Tue Jun  3 23:24:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: AUTOMAKE_OPTIONS changed from `foreign 1.1l' to
-       `gnits 1.1p'.  SUBDIRS reordered.  New target `docfiles'.
-
-       * TODO: Updates.
-
-       * configure.in: Removed AM_MAINTAINER_MODE.  Added
-       --enable-Werror, which is implied by --with-checker.
-
-       * reconfigure: Moved `aclocal' from beginning to just before
-       cleaning `autoheader'.  Removed --enable-maintainer-mode.  Added
-       --disable-nls.  Added `make docfiles' to placate autoheader.
-       Added `aclocal' before first real `autoheader'.  Uses `make
-       mostlyclean' instead of `make depend'.
-
-       * Made patchlevel 14.
-
-Mon Jun  2 14:21:54 1997  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Removed comment that screwed things up.
-
-       * reconfigure: Added `aclocal' at beginning.
-
-       * Made patchlevel 13.
-
-Sun Jun  1 23:25:39 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add intl, po to SUBDIRS.  Add aclocal.m4,
-       config.h.in to MAINTAINERCLEANFILES.
-
-       * acconfig.h: Add HAVE_LC_MESSAGES, ENABLE_NLS, HAVE_CATGETS,
-       HAVE_GETTEXT, HAVE_STPCPY.
-
-       * configure.in: Reordered to placate autoheader.  Added
-       AC_ISC_POSIX, AM_PROG_CC_STDC.  Added internationalization:
-       ALL_LINGUAS="", AM_GNU_GETTEXT, AC_LINK_FILES(...).  Added
-       po/Makefile.in, intl/Makefile to generated files list.  Generates
-       po/Makefile from po/Makefile.in.  Comment fix.
-
-       * pref.h.orig: Uncommented i18n support.
-
-       * acinclude.m4: New file.
-
-       * ABOUT-NLS: New file.
-
-       * intl/: New directory, taken from gettext-0.10.27.
-
-       * missing: New file, taken from automake-1.1p.
-
-       * po/: New directory.
-
-       * Made patchlevel 12.
-
-Sun Jun  1 17:28:27 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 11.
-
-Sun Jun  1 11:58:43 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: Removed DEFAULT_VER_PCP40, DEFAULT_VER_WIN61,
-       DEFAULT_VER_X40.  Added a macro DEFAULT_COMPAT that takes one of
-       the VER_* enums as a value.
-       (HISTORY_FILE) Changed the definition to "~/.fiasco_history".
-
-       * Made patchlevel 10.
-
-Fri May 30 19:40:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * pref.h.orig: [__MSDOS__] Reordered INCLUDE_PATH.
-
-       * Made patchlevel 9.
-
-Sun May 25 22:32:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * acconfig.h: For support of glibc 2, define _GNU_SOURCE.
-
-       * Made patchlevel 8.
-
-Mon May  5 21:58:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 7. 
-
-Fri May  2 22:27:36 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 6.
-
-Thu May  1 15:34:01 1997  Ben Pfaff  <blp@gnu.org>
-
-       * All files: Changed copyright from `Ben Pfaff' to `Free Software
-       Foundation, Inc'.
-
-       * Made patchlevel 5.
-
-Thu May  1 15:00:51 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 4.
-
-Sat Apr 26 11:34:05 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ChangeLog: Split into one ChangeLog per directory.
-
-       * Made patchlevel 3.
-
-Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Update.
-
-       * Made patchlevel 2.
-
-Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Removed `include', `util' from SUBDIRS; added
-       `config'.  Includes `config' directory in distributions.  Added
-       `private-install', `private-uninstall' targets.
-
-       * configure.in: AC_INIT tests for src/q2c.c now.  Removed
-       redundant AC_PROG_MAKE_SET call.  Removed include/Makefile,
-       util/Makefile from generated files list; added config/Makefile.
-
-       * include/approx.h, include/arena.h, include/common.h,
-       include/dfm.h, include/do-ifP.h, include/error.h, include/expr.h,
-       include/exprP.h, include/file-handle.h, include/filename.h,
-       include/font.h, include/getline.h, include/getopt.h,
-       include/hash.h, include/heap.h, include/log.h, include/misc.h,
-       include/output.h, include/settings.h, include/sfm.h,
-       include/sfmP.h, include/som.h, include/somP.h, include/stat.h,
-       include/stats.h, include/str.h, include/tokens.h, include/var.h,
-       include/version.h, include/vfmP.h: Moved into src/ directory.
-
-       * include/Makefile.am, include/: Removed.
-
-       * util/Makefile.am: Removed.
-
-       * util/q2c.c: Moved to src/.
-
-       * util/reconfigure: Moved to source root.
-
-       * util/: Removed.
-
-       * Made patchlevel 1.
-
-Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Maintainer-cleans generated documentation and
-       Makefile.in.
-
-       * include/Makefile.am, util/Makefile.am: Maintainer-cleans
-       Makefile.in.
-
-       * include/somP.h: (static struct var som) Removed passed_t member.
-
-       * TODO: Updated.
-
-       * configure.in: Fixed source directory for copying pref.h; always
-       updates pref.h or at least touch'es it.
-
-       * pref.h.orig: Made a rather pejorative comment a lot milder so it
-       wouldn't be misinterpreted.
-
-       * Made interim release x3.
-       
-Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
-
-       * All directories now contain new `Makefile.am's, in some cases
-       produced from bits and pieces of the single monolithic old one.
-       
-       * PATCHLEVEL: Removed.
-
-       * acconfig.h: Added GNU_PACKAGE, PACKAGE, PROTOTYPES, VERSION;
-       removed inclusion of conf.h.
-
-       * confh.in: Removed.
-       * confh.tmp.in: Removed.
-       
-       * configure.in: Deepened.  Updated for use with Automake 1.1l.
-       Removed PATCHLEVEL hacks.  Fixed lots of functions in
-       AC_CHECK_FUNCS, AC_REPLACE_FUNCS, and similar.  Only passes
-       `-Werror' to gcc in maintainer mode.  Doesn't output conf.h.
-       Touches pref.h even if it wasn't changed.  
-
-       * aclocal.m4: New file.
-
-       * config.h.in: Renamed from configh.in.
-
-       * pref.h.orig: Renamed from prefh.orig.
-
-       * Made interim release x2.
-       
-Thu Mar 27 01:07:02 1997  Ben Pfaff  <blp@gnu.org>
-
-    Changed the distribution from flat to deep.  New configuration:
-
-       ANNOUNCE        Makefile.in     config.h.in     mkinstalldirs
-       AUTHORS         NEWS            config.sub      orphaned-rules
-       BUGS            README          configure       pref.h
-       COPYING         THANKS          configure.in    pref.h.orig
-       ChangeLog       TODO            debian          src
-       ChangeLog~      acconfig.h      doc             stamp-h.in
-       INSTALL         aclocal.m4      include         sysdeps
-       LANGUAGE        config          install-sh      tests
-       Makefile.am     config.guess    lib             util
-
-       config:
-       devices      environment  papersize    ps-fontmap   ps-prologue
-
-       debian:
-       changelog  control    postinst   rules
-       conffiles  copyright  postrm
-
-       doc:
-       ANNOUNCE.html  Makefile.in    fiasco.info-2  stamp-vti
-       AUTHORS.html   README.html    fiasco.info-3  texinfo.tex
-       BUGS.html      THANKS.html    fiasco.info-4  version.texi
-       LANGUAGE.html  fiasco.info    fiasco.texi
-       Makefile.am    fiasco.info-1  mdate-sh
-
-       include:
-       approx.h       file-handle.h  misc.h         stats.h
-       arena.h        filename.h     output.h       str.h
-       common.h       font.h         settings.h     tokens.h
-       dfm.h          getline.h      sfm.h          var.h
-       do-ifP.h       getopt.h       sfmP.h         version.h
-       error.h        hash.h         som.h          vfmP.h
-       expr.h         heap.h         somP.h
-       exprP.h        log.h          stat.h
-
-       lib:
-       Makefile.am  Makefile.in  avllib       julcal       misc
-
-       lib/avllib:
-       AVLLIB.COPYING  Makefile.in     avl.h
-       Makefile.am     avl.c
-
-       lib/julcal:
-       Makefile.am  Makefile.in  julcal.c     julcal.h
-
-       lib/misc:
-       Makefile.am    getopt1.c      memset.c       strstr.c
-       Makefile.in    memchr.c       qsort.c        strtol.c
-       alloca.c       memcmp.c       stpcpy.c       strtoul.c
-       getdelim.c     memcpy.c       strcasecmp.c
-       getline.c      memmem.c       strncasecmp.c
-       getopt.c       memmove.c      strpbrk.c
-
-       src:
-       Makefile.am     error.c         lexer.c         sfm-write.c
-       Makefile.in     expr-evl.c      list.c          show.c
-       arena.c         expr-opt.c      list.q          som-frnt.c
-       ascii.c         expr-prs.c      log.c           som-high.c
-       autorecode.c    file-handle.c   loop.c          som-low.c
-       cases.c         file-handle.q   main.c          sort.c
-       cmdline.c       file-type.c     mis-val.c       split-file.c
-       command.c       filename.c      misc.c          stats.c
-       common.c        formats.c       modify-vars.c   str.c
-       compute.c       freq.c          numeric.c       sysfile-info.c
-       count.c         frequencies.c   output.c        temporary.c
-       crosstabs.c     frequencies.g   postscript.c    title.c
-       crosstabs.q     frequencies.q   print.c         val-labs.c
-       data-in.c       get.c           recode.c        var-labs.c
-       data-list.c     getline.c       rename-vars.c   vars-atr.c
-       data-out.c      glob.c          repeat.c        vars-prs.c
-       descript.c      groff-font.c    sample.c        vector.c
-       descript.q      hash.c          sel-if.c        version.c
-       dfm.c           heap.c          set.c           vfm.c
-       display.c       include.c       set.q           weight.c
-       do-if.c         inpt-pgm.c      sfm-read.c
-
-       sysdeps:
-       BorlndC4.0  DJGPP2.0    Windows
-
-       sysdeps/BorlndC4.0:
-       Makefile     _write.c     conf.h
-       _read.c      compile.bat  config.h
-
-       sysdeps/DJGPP2.0:
-       Makefile     compile.bat  conf.h       config.h
-
-       sysdeps/Windows:
-       con32s.c
-
-       tests:
-       Makefile.am         expression.stat     reread.data
-       Makefile.in         fall92.data         reread.stat
-       autorecode.stat     fall92.stat         sample.stat
-       begin-data.stat     file-label.stat     show-check-msg
-       bignum.data         file-type.stat      sort.data
-       bignum.stat         filter.stat         sort.stat
-       bug.stat            gengarbage.c        split-file.stat
-       compute.stat        input-program.stat  sysfile-info.stat
-       count.stat          list.data           temporary.stat
-       data-formats.stat   list.stat           time-date.stat
-       data-list.data      loop.stat           vector.stat
-       data-list.stat      modify-vars.stat    weighting.data
-       descript.stat       print.stat          weighting.stat
-       do-if.stat          process-if.stat
-       do-repeat.stat      recode.stat
-
-       util:
-       Makefile.am  Makefile.in  q2c.c        reconfigure
-
-    Old configuration:
-
-       ANNOUNCE.html   count.c         hash.h          sample.c
-       AUTHORS.html    crosstabs.q     heap.c          sel-if.c
-       AVLLIB.COPYING  data-in.c       heap.h          set.q
-       BUGS.html       data-list.c     include.c       settings.h
-       COPYING         data-out.c      inpt-pgm.c      sfm-read.c
-       ChangeLog       debian          install-sh      sfm-write.c
-       INSTALL         descript.q      julcal.c        sfm.h
-       LANGUAGE.html   devices         julcal.h        sfmP.h
-       Makefile.am     dfm.c           lexer.c         show.c
-       NEWS            dfm.h           list.q          som-frnt.c
-       PATCHLEVEL      display.c       log.c           som-high.c
-       README.html     do-if.c         log.h           som-low.c
-       THANKS.html     do-ifP.h        loop.c          som.h
-       TODO            environment     main.c          somP.h
-       _read.c         error.c         makeb40.bat     sort.c
-       _write.c        error.h         makedj2.bat     split-file.c
-       acconfig.h      expr-evl.c      makefile.b40    stamp-h.in
-       alloca.c        expr-opt.c      makefile.dj2    stats.c
-       approx.h        expr-prs.c      mdate-sh        stats.h
-       arena.c         expr.h          memcmp.c        stpcpy.c
-       arena.h         exprP.h         mis-val.c       str.c
-       ascii.c         fiasco.texi     misc.c          str.h
-       autorecode.c    file-handle.h   misc.h          sysfile-info.c
-       avl.c           file-handle.q   mkinstalldirs   temporary.c
-       avl.h           file-type.c     modify-vars.c   test
-       cases.c         filename.c      numeric.c       texinfo.tex
-       cmdline.c       filename.h      output.c        title.c
-       command.c       font.h          output.h        tokens.h
-       common.c        formats.c       papersize       val-labs.c
-       common.h        freq.c          postscript.c    var-labs.c
-       compute.c       frequencies.g   prefh.orig      var.h
-       con32s.c        frequencies.q   print.c         vars-atr.c
-       confh.b40       get.c           ps-fontmap      vars-prs.c
-       confh.dj2       getline.c       ps-prologue     vector.c
-       confh.in        getline.h       q2c.c           version.c
-       confh.tmp.in    getopt.c        qsort.c         version.h
-       config.guess    getopt.h        recode.c        vfm.c
-       config.sub      getopt1.c       reconfigure     vfmP.h
-       configh.b40     glob.c          reject          weight.c
-       configh.dj2     groff-font.c    rename-vars.c
-       configure.in    hash.c          repeat.c
-
-       debian:
-       changelog  control    postinst   rules
-       conffiles  copyright  postrm
-
-       test:
-       autorecode.stat     fall92.data         recode.stat
-       begin-data.stat     fall92.stat         reread.data
-       bignum.data         file-label.stat     reread.stat
-       bignum.stat         file-type.stat      sample.stat
-       bug.stat            filter.stat         sort.stat
-       compute.stat        gengarbage.c        split-file.stat
-       count.stat          gengarbage.pl       sysfile-info.stat
-       data-formats.stat   input-program.stat  temporary.stat
-       data-list.data      list.data           time-date.stat
-       data-list.stat      list.stat           vector.stat
-       descript.stat       loop.stat           weighting.data
-       do-if.stat          modify-vars.stat    weighting.stat
-       do-repeat.stat      print.stat
-       expression.stat     process-if.stat
-
-Mon Mar 24 21:47:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: @ALLOCA@ is on list of source files instead of
-       alloca.c.  Added $(srcdir)/ to version.c reference.  Changed to
-       pkgdatadir (/usr/share) for pkgsysconfdir, from pkglibdir
-       (/usr/lib).  Removed some of extra distfiles.  Added bogus `check'
-       target.
-
-       * Made transition release x1.
-
-Sun Mar  2 20:51:28 1997  Ben Pfaff  <blp@gnu.org>
-
-       No longer uses debmake:
-       
-       * Makefile.am: Installs documentation according to Debian policy
-       manual.  New targets `private-uninstall', `install-data-hook' to
-       help implement this.  `debian' target also revised.
-       
-       * configure.in: Sets up for Debian installation depending on
-       DEBIAN environment variable.  Also, improved & fixed (hopefully)
-       the scheme for detecting patchlevel.
-       
-       * Made patchlevel 193.
-
-Wed Feb 19 21:30:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 192.
-
-Sun Feb 16 20:57:20 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 191.
-       
-Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Removed `descript.g' from sources.
-
-       * Made patchlevel 190.
-       
-Fri Feb 14 23:32:58 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-       
-       * configure.in: Fixed test for max number of digits in an `int' to
-       use char[] rather than int[].
-
-       * Made patchlevel 189.
-       
-Tue Feb  4 15:15:50 1997  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Fixed some problems with `--with-checker' flag and
-       with detection of available libraries; no longer any lines longer
-       than 79 characters.
-
-       * Made patchlevel 188.
-       
-Wed Jan 22 21:54:00 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add sysfile-info.c to sources.
-
-       * TODO: Moved some notes to different files where they are more
-       appropriate.
-
-       * prefh.orig: (macros STORE_2 and LOAD_2) Always load/store as
-       little-endian.
-
-       * Made patchlevel 187.
-
-Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added rename-vars.c to sources.  Added to distclean
-       files.
-
-       * TODO: Updates.
-
-       * Made patchlevel 186.
-
-Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Most files have updated copyright notices for 1997.
-
-       * Makefile.am: Added modify-vars.c to source files.  Also changed
-       `lynx' to $(HTML_FORMATTER), etc.  Changed messages.
-
-       * TODO: Updates.
-
-       * Made patchlevel 185.
-
-Sat Jan 11 15:44:15 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: By default, now installs config files in pkglibdir,
-       generally /usr/local/lib/fiasco.
-
-       * TODO: Updated.
-
-       * prefh.orig: Added `/etc/fiasco' to config paths.  Removed
-       $ARCH/$VER dirs from include paths. 
-
-       * Made patchlevel 184.
-
-Fri Jan 10 20:22:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * debian/changelog, debian/control, debian/copyright, debian/dirs,
-       debian/info, debian/menu, debian/rules: Added Debian GNU/Linux
-       control files.
-       
-       * Makefile.am: Added sfmP.h to source files.  Added several files
-       to the list of distfiles.   dist-hook now copies debian control
-       files.  New targets `debian', `debian-clean', `debian-clean-full'.
-
-       * confh.in: Defines PATCHLEVEL.
-
-       * configure.in: Adds the current patchlevel to the version
-       number.  Versions are now of the form `1.2.3pl456'.  Determines
-       the patchlevel based on directory name and contents of file
-       PATCHLEVEL.
-
-       * reconfigure: Passes automake `--strictness=foreign'.
-
-       * Made patchlevel 183.
-
-Thu Jan  2 19:08:23 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 182.
-
-Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-       
-       * Made patchlevel 181.
-       
-Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: New target for test/sort.data.
-
-       * Made patchlevel 180.
-       
-Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 179.
-
-Tue Dec 24 20:42:32 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 178.
-
-Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added heap.c, heap.h to source files.  Added
-       new html files to distfiles & maintainer-clean files.
-
-       * configure.in: Tests for presence of getpid(), sys/types.h.
-
-       * prefh.orig: #defines mkdir() for MS-DOS compatibility.
-
-       * Made patchlevel 177.
-
-Sat Dec 21 21:51:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added README.html, LANGUAGE.html to list of
-       distfiles.  Added README, LANGUAGE to list of maintainer-clean
-       files.  Added .html to suffixes.  Added .html implicit rule that
-       calls `lynx -dump -nolist'.
-
-       * Made patchlevel 176.
-       
-Tue Dec 17 18:57:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 175.
-       
-Sun Dec 15 15:32:16 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added vfmP.c, qsort, sort.c to list of source
-       files.
-
-       * prefh.orig: Subtle changes to MAX_WORKSPACE, ALWAYS_PAGE,
-       NEVER_PAGE, DEMAND_PAGE macro meanings.
-
-       * Made patchlevel 174.
-       
-Sat Dec 14 10:35:30 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 173.
-       
-Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added autorecode.c to source files.
-
-       * prefh.orig: Fixed path GROFF_FONT_PATH.
-
-       * Made patchlevel 172.
-       
-Fri Dec  6 23:53:47 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-       
-       * Made patchlevel 171.
-       
-Wed Dec  4 21:34:17 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 170.
-       
-Sun Dec  1 17:19:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 169.
-       
-Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added `set.q' to list of source files.
-
-       * Made patchlevel 168.
-
-Thu Nov 28 19:46:10 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 167.
-
-Wed Nov 27 23:18:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added `sfm-write.c' to list of source files.
-
-       * confh.in: New #defines RELEASE_NO, SUB_RELEASE_NO, and
-       SPEC_RELEASE_NO for each part of a version number of form 1.2.3.
-
-       * configure.in: Computes RELEASE_NO, etc., by breaking apart
-       VERSION.
-
-       * prefh.orig: (defn of int32, flt64) Formatting fixes.
-       (FLT64_MAX) New define.
-
-       * Made patchlevel 166.
-       
-Sun Nov 24 14:53:53 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Wow, it's been almost two weeks since the last update, hard to
-       believe.
-
-       * All source files: Updated e-mail address.
-       
-       * prefh.orig: local_alloc() calls xmalloc() under Checker because
-       Checker can keep track of heap blocks much more accurately.
-
-       * Made patchlevel 165.
-       
-Mon Nov 11 15:34:09 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 164.
-       
-Thu Nov  7 20:52:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 163.
-       
-Thu Nov  7 17:29:16 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 162.
-       
-Thu Nov  7 15:48:52 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 161.
-       
-Tue Nov  5 18:34:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 160.
-       
-Mon Nov  4 22:03:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added get.c.
-
-       * TODO: Updated.
-
-       * Made patchlevel 159.
-       
-Sun Nov  3 12:24:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added sfm.h, sfm-read.c to source files.
-
-       * Made patchlevel 158.
-       
-Wed Oct 30 17:13:08 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added dist-zip target to AUTOMAKE_OPTIONS.
-
-       * acconfig.h: Added FPREP_* defines.
-
-       * configure.in: Added checks for the sizes of floating-point
-       types.  Added a test for the internal floating-point
-       representation of the host architecture.
-
-       * prefh.orig: Renamed `ATTRIBUTION' macro as `__attribute__'.  All
-       references changed.  Defines `flt64' 64-bit floating-point for use
-       with system files.
-       [FPREP==FPREP_IEEE754 && __GNUC__ && (ENDIAN==BIG ||
-       ENDIAN==LITTLE] Defines SECOND_LOWEST_VALUE macro.
-       
-       * Made patchlevel 157.
-
-Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Checks sizes of short, int, long, long long.
-
-       * prefh.orig: Defines new type int32 for use with system
-       files.
-
-       * Made patchlevel 156.
-       
-Sat Oct 26 20:46:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 155.
-
-Sat Oct 26 10:39:25 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 154.
-       
-Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added back in these files: recode.c, sample.c,
-       sel-if.c.  Also added files somP.h, hash.c that should've been
-       there anyway.
-
-       * TODO: Updated.
-
-       * configure.in: Checks for strncasecmp in place of strcasecmp.
-
-       * Made patchlevel 153.
-       
-Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * Made patchlevel 152.
-       
-Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Organized.
-
-       * Made patchlevel 151.
-       
-Tue Oct 22 17:27:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Culled old notes.
-
-       * Made patchlevel 150.
-
-Mon Oct 21 20:39:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 149.
-       
-Sun Oct 20 13:45:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added back in `numeric.c', `print.c', `title.c'.
-       Defined ETAGS_ARGS.
-
-       * Made patchlevel 148.
-       
-Sun Oct 20 09:04:15 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 147.
-       
-Fri Oct 18 19:46:49 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 146.
-       
-Sun Sep 29 19:37:03 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 145.
-       
-Sat Sep 28 21:28:07 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added to DISTCLEANFILES. 
-   
-       * Made patchlevel 144.
-       
-Fri Sep 27 20:08:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 143.
-       
-Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added list.c back into the list of source files.
-
-       * Made patchlevel 142.
-       
-Wed Sep 25 19:36:11 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Updated for new files.
-
-       * Made patchlevel 141.
-               
-Tue Sep 24 18:39:09 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 140.
-
-Sat Sep 21 23:16:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 139.
-
-Fri Sep 20 22:52:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 138.
-       
-Thu Sep 12 18:40:33 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 137.
-
-Wed Sep 11 22:01:41 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Added timestamp.
-
-       * prefh.orig: Removed `/usr/local/share/fiasco' and
-       `/usr/share/fiasco' from CONFIG_PATH as per the Linux FSSTND,
-       which specifies that programs should never give an explicit
-       `/usr(/local)/share' path.
-
-       * Made patchlevel 136.
-
-Tue Sep 10 21:39:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added `display.c' back in.
-
-       * TODO: Addition.
-
-       * Made patchlevel 135.
-       
-Mon Sep  9 21:43:13 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added `split-file.c' back into the project.
-
-       * Made patchlevel 134.
-       
-Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Updated.
-
-       * prefh.orig: (local_strdup) Moved to misc.h.
-
-       * Made patchlevel 133. 
-       
-Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Changed `prologue.ps' references to `ps-prologue'.
-
-       * Made patchlevel 132.
-       
-Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prefh.orig: New i18n defines.
-
-       * This patchlevel doesn't even compile.
-
-       * Made patchlevel 131.
-       
-Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: Addition.
-
-       * Made patchlevel 130.
-               
-Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 129.
-       
-Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: New target "private-install" to install config files
-       to $HOME/.fiasco.
-
-       * configure.in: Now that I have made a less-bogus Checker
-       distribution, removed `-b i486-linuxaout -V 2.6.3' from
-       AC_ARG_WITH(checker, ...).
-
-       * Made patchlevel 127 somewhere in there.
-       
-       * Made patchlevel 128.
-       
-Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Changed DISTCLEANFILES.
-
-       * Does not compile.
-       
-       * Made patchlevel 126.
-       
-Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
-
-       * reconfigure: Calls `autoheader' twice: once at the beginning,
-       once after make maintainer-clean.
-
-       * Made patchlevel 125. 
-       
-Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
-
-       * reconfigure: `autoheader' now first operation performed.
-
-       * Made patchlevel 124.
-       
-Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added postscript.c to list of source files.
-
-       * configh.in: Removed since autoheader can regenerate it.
-
-       * configure.in: Improved tests for (ncurses or termcap) and
-       (history and/or readline) libraries and associated headers.  Added
-       check for strcasecmp().  Changed default gcc CFLAGS.
-
-       * prefh.orig: Removed `.' from GROFF_FONT_PATH.
-       (local_alloc, local_free) New functions.
-
-       * reconfigure: Added call to autoheader.
-
-       * Made patchlevel 123.
-       
-Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * There were some problems with the patchfiles so I had to merge
-       what was previously patchlevels 121 and 122; now everything from
-       what was previously 122 is called 121.  Oh well, just don't let it
-       happen often.
-
-       * This patchlevel does not compile.
-
-       * configure: No longer included in patches to save lotsa space
-       when configure.in changes.
-
-       * configure.in: Changed the technique for detecting libraries.
-
-       * prefh.orig: Style changes; handles changed configure.in.
-
-       * Made patchlevel 122 (second edition).
-
-Tue Jul 23 21:48:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 121.
-       
-Wed Jul 17 21:23:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 120.
-
-Tue Jul 16 22:10:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 119.
-
-Sun Jul 14 15:45:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 118.
-
-Fri Jul 12 22:03:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added list.c to sources.
-       
-       * Made patchlevel 117.
-       
-Sat Jul  6 22:22:25 1996  Ben Pfaff  <blp@gnu.org>
-
-       * configure.in: Removed reference to `malloc.h'.
-       
-       * Made patchlevel 116.
-       
-Fri Jul  5 20:16:19 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 115.
-
-Thu Jul  4 20:20:24 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prefh.orig: Changes to CONFIG_PATH, INCLUDE_PATH,
-       GROFF_FONT_PATH.
-
-       * Makefile.am: pkgdata_DATA file `output' changed to `devices'.
-       
-Thu Jul  4 00:35:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * TODO: doc fix.
-       
-       * Made patchlevel 114.
-       
-Tue Jul  2 22:13:23 1996  Ben Pfaff  <blp@gnu.org>
-
-       * reconfigure: (new file) Runs all the programs necessary to
-       create a Makefile that includes dependencies.
-
-       * Made patchlevel 113.
-       
-Mon Jul  1 22:13:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Made patchlevel 112.
-
-Mon Jul  1 13:00:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Most files: Changed references from `stat' (the original, rather
-       dull old name for this project) to `Fiasco' (the creative, rather
-       funny new name for this project).
-       
-       * Made patchlevel 111.
-       
-Sat Jun 29 17:40:47 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prefh.orig: changed default file search paths
-       
-       * Made patchlevel 110.
-
-Fri Jun 28 11:59:48 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Added automake support; removed GNUmakefile and GNUmakefile.in.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/INSTALL b/INSTALL
index c07faa27841a284c8231fded9edd970e8755c0bd..e687c55114b6d45690a3a48965225dcf92a6bbb7 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -108,6 +108,23 @@ release.
   1. `cd' to the directory containing the package's source code and type
      `./configure' to configure the package for your system.
 
+     You may invoke `configure' with --help to see what options are
+     available.  The most common of these are listed under "Optional
+     Features", below.
+
+     It is best to build and install PSPP in directories whose names do
+     not contain unusual characters such as spaces or single-quotes, due
+     to limitations of the tools involved in the build process.
+
+     If you installed some of the libraries that PSPP uses in a
+     non-standard location (on many systems, anywhere other than
+     /usr), you may need to provide some special flags to `configure'
+     to tell it where to find them.  For example, on GNU/Linux, if you
+     installed some libraries in /usr/local, then you need to invoke
+     it with at least the following options:
+
+       ./configure LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib' CPPFLAGS='-I/usr/local/include'
+
      Running `configure' takes awhile.  While running, it prints some
      messages telling which features it is checking for.
 
index 806fc2a9768ae596613e1afebcdf2ec951e0bebb..23305294af2176bedbc9b08ed4256e6f9aa5a308 100644 (file)
@@ -27,14 +27,26 @@ all_q_sources =
 pkgsysconfdir = $(sysconfdir)/@PACKAGE@
 
 
-EXTRA_DIST = ONEWS config.rpath pspp-mode.el
+EXTRA_DIST = OChangeLog ONEWS config.rpath pspp-mode.el
 
 CLEANFILES = 
 ACLOCAL_AMFLAGS = -I m4 -I gl/m4
 noinst_LIBRARIES=
+noinst_LTLIBRARIES=
 noinst_PROGRAMS=
 check_PROGRAMS=
 bin_PROGRAMS=
+DIST_HOOKS =
+PHONY =
+
+DIST_HOOKS += generate-changelog
+generate-changelog:
+       if test -d $(top_srcdir)/.git; then                     \
+         $(top_srcdir)/gitlog-to-changelog --since=2008-07-27  \
+           > $(distdir)/cl-t;                                  \
+         rm -f $(distdir)/ChangeLog;                           \
+         mv $(distdir)/cl-t $(distdir)/ChangeLog;              \
+       fi
 
 include $(top_srcdir)/lib/automake.mk
 include $(top_srcdir)/doc/automake.mk
@@ -47,3 +59,7 @@ include $(top_srcdir)/tests/automake.mk
 if WITH_GUI_TOOLS
 include $(top_srcdir)/glade/automake.mk
 endif
+
+PHONY += $(DIST_HOOKS)
+dist-hook: $(DIST_HOOKS)
+.PHONY: $(PHONY)
diff --git a/NEWS b/NEWS
index 874106d6cf5d8517ddc505ec6d37867f6115fe17..1070638b4e641a102031b3df2946015ca7966847 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,71 @@
 PSPP NEWS -- history of user-visible changes.
-Time-stamp: <2008-06-04 21:27:06 blp>
-Copyright (C) 1996-9, 2000 Free Software Foundation, Inc.
+Time-stamp: <2008-10-11 10:04:51 blp>
+Copyright (C) 1996-9, 2000, 2008 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
 
+Changes from 0.6.1 to 0.7.0:
+
+  * Custom variable and data file attributes are now supported.
+    Commands VARIABLE ATTRIBUTE and DATAFILE ATTRIBUTE have been added
+    for setting and clear attributes.  Support for attributes has also
+    been added to commands that read and write system files, such as
+    SAVE and GET, as well as to the DISPLAY command.
+
+Changes from 0.6.0 to 0.6.1:
+
+  * Statistical bug fixes:
+
+    - Report correct standardized regression coefficients in linear
+      regression output (bug #23567).
+
+  * Bug fixes that affect PSPP and PSPPIRE:
+
+    - Avoid crash with pie charts (bug #24014).
+
+    - Don't append % to count totals (bug #24003).
+
+    - Don't crash on bad input (bug #24031).
+
+    - Don't crash if "end data." is not left aligned (bug #24115).
+
+    - Change default workspace value to 64 MB, to avoid unnecessary
+      disk accesses on modern machines.
+
+  * PSPPIRE bug fixes:
+
+    - Add ".sav" or ".por" suffix to filename when saving with Save_As
+      (bug #23137).
+
+    - Make it possible to reopen the output window on Windows (bug
+      #24033).
+
+    - A POSIX regular expression library is now included and used
+      automatically if the host does not have one or has one that is
+      inadequate.
+
+  * Build fixes and changes:
+
+    - Work around bug in GSL that prevented build with recent GCC
+      versions without manually adding -fgnu89-inline to CFLAGS.
+
+    - Also warn about missing prerequisites as we encounter them (bug
+      #24445).
+
+    - Distribute necessary files to allow users working from the
+      distributed tarball to configure with --enable-gui-tools.
+
+    - Append $(EXEEXT_FOR_BUILD) to output file name when building
+      q2c, fixing build problems on Windows.
+
+    - GSL 1.8 or later is now required.
+
+    - Build errors with --enable-relocatable were fixed.
+
+  * The German translations were removed, since native German speakers
+    found them too poor to be useful.
+
 Changes from 0.4.0 to 0.6.0:
 
   * The PSPP license is now version 3 or later of the GNU General
diff --git a/OChangeLog b/OChangeLog
new file mode 100644 (file)
index 0000000..bcf78ac
--- /dev/null
@@ -0,0 +1,2406 @@
+2008-06-13  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Fix typo in AC_PREREQ command name.  Thanks to
+       Stepan Kasal <kasal@ucw.cz> for reporting the problem.
+
+2008-06-04  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Update version number to 0.6.0 in preparation for
+       release.
+
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Don't depend on memmem module, because
+       PSPP does not use memmem any longer.  Use
+       unilbrk/ulc-width-linebreaks module instead of the linebreak
+       module, because the latter was split up into multiple modules and
+       that's the one we actually need.
+
+2008-05-09  John Darrington <john@darrington.wattle.id.au>
+
+       * INSTALL: For obscure reasons gettext 0.17 requires that 
+       the string 'GNU pspp' occurs in some file in the root 
+       directory. Otherwise make distcheck fails with a very non-intuitive 
+       error message.  So for want of somewhere better I added it 
+       in INSTALL.
+
+       But since this string now appears in this ChangeLog file, it
+       could be taken out of INSTALL ...
+
+2008-04-19  John Darrington <john@darrington.wattle.id.au>
+
+       * configure.ac : Improve checking of ncurses availability.
+
+2008-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Properly report required version of libglade.
+       Thanks to unknown-1 <pspp@sjpaes.nl> for reporting this bug.
+
+2008-04-15  John Darrington <john@darrington.wattle.id.au>
+
+       * configure.ac : Replace AC_CHECK_LIB with AC_SEARCH_LIBS as
+       recommended by latest autoconf manual.
+
+2008-02-19  John Darrington <john@darrington.wattle.id.au>
+
+       * configure.ac INSTALL: We now depend on GTK+ 2.12
+
+2007-12-11  John Darrington <john@darrington.wattle.id.au>
+
+       * t-test-independent-samples-dialog.c: Quoted the group values, when
+       the group variable is a string variable.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Add ftello module.
+
+2007-11-05  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: No need for check for off_t or for the size of
+       float or long double any longer, as we don't use the results
+       anymore.  Also, no need to put #include <locale.h> into config.h
+       any longer, as this was only needed for --with-included-gettext,
+       which we have not supported for some time.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * Smake (GNULIB_MODULES): Add fatal-signal, tempname modules.
+
+2007-11-02  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Add isfinite, round modules.
+
+2007-10-12  Ben Pfaff  <blp@gnu.org>
+
+       Use trunc module from gnulib instead of our home-grown solution.
+       Patch #6224.
+
+       * Smake: Add trunc to module list.
+
+       * configure.ac: Don't need to check for trunc function any longer.
+
+2007-10-12  Ben Pfaff  <blp@gnu.org>
+
+       Use fseeko module from gnulib instead of our home-grown solution.
+       Patch #6228.
+
+       * acinclude.m4: Delete PSPP_OFF_T macro.
+
+       * configure.ac: Don't call AC_FUNC_FSEEKO or PSPP_OFF_T.
+
+2007-10-12  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add fprintf-posix, printf-posix, printf-safe,
+       snprintf-posix, sprintf-posix, vasprintf-posxi, vfprintf-posix,
+       vprintf-posix, vsnprintf-posix, and vsprintf-posix modules, which
+       allow us to use C99 format specifiers (e.g. 'z') in *printf.
+       Also, changed many formerly casted arguments in *printf calls to
+       use one of these format specifiers and drop the cast.
+2007-10-11  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Drop alloca, alloca-opt modules as we don't use them
+       anymore.
+
+2007-10-10  Ben Pfaff  <blp@gnu.org>
+
+       * acinclude.m4: Improve formatting.
+
+       * configure.ac: Ditto.  Don't check for headers whose presence is
+       never tested.  Don't use AC_C_CONST (we can assume that "const" is
+       implemented these days).  Don't pass default sizes to
+       AC_CHECK_SIZEOF, since modern Autoconf doesn't need them.  Don't
+       define FPREP_IEEE754, since it was not tested for.  Don't use
+       AC_FUNC_VPRINTF, since we never tested for it.
+
+2007-10-06 John Darrington <john@darrington.wattle.id.au>
+
+       * configure.ac INSTALL: Change libglade version requirement.
+       Thanks to Paul Brown for reporting this issue.
+
+2007-09-30  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Print a message indicating success at the end of
+       the run.
+
+       * INSTALL: Improve instructions.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * acinclude.m4 (PSPP_LC_PAPER): New macro.
+
+       * configure.ac: Use PSPP_LC_PAPER.
+
+2007-08-05  Ben Pfaff  <blp@gnu.org>
+
+       Bug #16189.  Reviewed by Jason Stover.
+       * acinclude.m4: If -lplot doesn't work by itself, also test with
+       typical X11 libraries.
+
+2007-07-27  Ben Pfaff  <blp@gnu.org>
+
+       Bug #19069.
+       * INSTALL: Improve installation instructions.
+       * README: Move prerequisites to INSTALL.
+       Reviewed by Jason Stover.
+
+       * configure.ac: Make PKG_CHECK_MODULES tests more user-friendly,
+       by having them give their errors at the end of the configuration
+       process instead of stopping it in the middle.  Patch #6116.
+       Reviewed by Jason Stover.
+
+2007-06-14  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Use xmalloca instead of xallocsa due to module renaming.
+       Update all uses.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add xallocsa to modules.
+
+2007-04-22  Ben Pfaff  <blp@gnu.org>
+
+       Implement model checker for testing purposes.
+       
+       Patch #5873.
+       
+       * Smake (GNULIB_MODULES): Add crypto/md4, fwriteerror,
+       gettimeofday.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Increment version to 0.4.3 due to snapshot posted
+       to alpha.gnu.org.
+       Suggested by John Darrington.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+
+       Use Gnulib's fpieee module instead of specifying -mieee by hand.
+
+       * Smake: Use fpieee module from Gnulib.
+
+       * configure.ac: Don't enable -mieee.
+
+2007-03-19  Ben Pfaff  <blp@gnu.org>
+
+       Work toward modernizing the build system by updating our Automake
+       and Autoconf dependencies and requiring libintl to be available
+       externally (if desired) instead of including a copy in the
+       distribution.
+
+       * Makefile.am (AUTOMAKE_OPTIONS): Require Automake 1.10 (or
+       later), which works better with systems that have a non-empty
+       $(EXEEXT).
+       (SUBDIRS): Drop intl.
+       (DISTCLEANFILES): Drop intl/plural.c.
+
+       * Throughout Makefile.am and the automake.mk files: Change
+       mkinstalldirs to $(MKDIR_P), to support the corresponding Automake
+       change.
+
+       * Smake (GNULIB_MODULES): Use gettext-h instead of gettext module.
+       (all): Don't create intl directory.
+       (gettextize): Don't use --intl flag.
+
+       * configure.ac: Require Autoconf 2.60 or later.  Use external
+       gettext.  Drop intl/Makefile from config files.
+
+2007-02-25  Ben Pfaff  <blp@gnu.org>
+
+       Thanks to Jason Stover for verifying that this patch helps under
+       NetBSD.
+
+       * acinclude.m4: Rename PSPP_ENABLE_WARNING to PSPP_ENABLE_OPTION,
+       because it's useful for more than warnings.
+
+       * configure.ac: Add PSPP_ENABLE_OPTION(-mieee) to improve IEEE
+       floating-point conformance on Alpha and SH architectures.  Also,
+       check for fpsetmask function (available on BSDs).
+
+Mon Feb 19 10:52:21 2007  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Add dirname module, remove canonicalize
+       module.  Corresponds to changes in src/data/file-name.c.
+
+Sat Feb 17 09:22:32 2007  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Add tmpfile module, which fixes the use
+       of the tmpfile function under Windows.
+
+Fri Feb 16 10:50:38 2007  Ben Pfaff  <blp@gnu.org>
+
+       Better support cross-compiling by using CC_FOR_BUILD and
+       EXEEXT_FOR_BUILD for q2c.
+       
+       * Makefile.am: Add CC_FOR_BUILD, EXEEXT_FOR_BUILD variables.  Use
+       in .q.c rule.
+
+       * acinclude.m4: Add PSPP_CC_FOR_BUILD macro.
+
+       * configure.ac: Call PSPP_CC_FOR_BUILD.
+
+Mon Feb 12 16:39:18 2007  Ben Pfaff  <blp@gnu.org>
+
+       * README: Note that iconv is required.
+
+       * configure.ac: Enforce iconv requirement.
+
+Thu Feb  8 14:56:18 2007  Ben Pfaff  <blp@gnu.org>
+
+       Reduce platform dependence.
+
+       * Makefile.am: Don't add -Dunix or -D__MSDOS__ to compiler command
+       line.  Add $(top_builddir)/intl to include path to fix building
+       with the included libintl.
+
+       * Smake (GNULIB_MODULES): Add `canonicalize', `sys_stat',
+       `mkstemp' modules.  Remove `stat-macros' module, which is no
+       longer what we want, because what we want is provided by sys_stat
+       now, and remove its inclusions.  Remove `strstr' module, which is
+       no longer in gnulib.  Remove `readlink', `xreadlink', because we
+       no longer use either function.
+
+       * configure.ac: Move gl_EARLY before AC_PROG_CC, where the gnulib
+       manual says it should be.  Check for presence of execl, fork,
+       and popen.  Drop check for unix versus msdos as host OS.
+
+Sat Nov  4 15:59:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Check for the "round" function added in C99.
+
+Tue Oct 31 19:55:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Add `mempcpy' module.
+
+Tue Oct 31 19:29:05 2006  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Drop tests for strchr, strrchr because now we
+       assume a C89 compliant library.  (Gnulib makes this assumption so
+       we might as well too.)
+
+Sun Oct 29 14:08:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake (GNULIB_MODULES): Remove `restrict' from modules, because
+       recent gnulib doesn't have such a module.
+
+Mon Jul 17 18:23:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add --doc-base=gl/doc to gnulib-tool invocation, which is
+       required by recent gnulib.
+
+Sun Jul 16 19:51:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add xsize to GNULIB_MODULES.
+
+Wed Jul 12 13:41:18 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add check_PROGRAMS and define to empty.
+
+Sat Jul  1 15:32:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add noinst_PROGRAMS and define to empty.
+
+Tue May  9 20:46:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add stdarg to GNULIB_MODULES.
+
+Sun May  7 09:27:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * po/en_GB.po : Removed.  Now that messages talking about coloUrs have 
+       been removed, it does nothing.
+
+Tue May  2 10:43:30 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * Bumped the minor version number from 0.4.1 to 0.4.2 to reflect 
+        changes to system file format.
+
+Mon Apr 24 14:12:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add exit to GNULIB_MODULES.
+
+Sun Apr 23 20:34:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add linebreak to GNULIB_MODULES.
+
+Sat Apr 15 21:45:40 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of src/libpspp/debug-print.h and all its uses.  (There
+       were few real users, but many inclusions of its header file.)
+
+Sat Apr 15 19:51:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of our own int32 type in favor of the standard int32_t
+       type.
+       
+       * configure.ac: Don't need to check the sizes of integer types
+       anymore.
+
+Sat Apr 15 19:13:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac, acinclude.m4: Complain about missing prerequisites
+       in a group at the end of configuration, not piecemeal.  This
+       should make building PSPP less frustrating.  Thanks to John
+       Darrington for the suggestion.
+
+Sat Apr 15 18:17:15 2006  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Move code into acinclude.m4 to make the configure
+       script more readable.
+
+       * acinclude.m4: New functions from configure.ac.
+
+Mon Apr  3 11:01:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: (GNULIB_MODULES) Add strsep.
+
+Thu Mar 30 15:50:05 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Enable -Wdeclaration-after-statement warning if
+       available.
+
+       * acinclude.m4: Add macro for checking whether a warning is
+       supported.
+
+Mon Mar 20 16:32:11 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Require "unistd" gnulib module.  Removed tests for
+       HAVE_UNISTD_H from source code.
+
+Sat Mar  4 13:20:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Get rid of pref.h.orig.
+
+       * pref.h.orig: Removed.  Moved SHORT_NAME_LEN, LONG_NAME_LEN to
+       src/data/variable.h.  Removed GLOBAL_DEBUGGING entirely, changing
+       all references to DEBUGGING.  Moved P_tmpdir to
+       src/data/make-file.c.  Moved NO_CHARTS to
+       src/output/charts/automake.mk.
+
+Sat Mar  4 12:58:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Move GCC attribute declarations to
+       new file src/libpspp/compiler.h.
+
+Sat Mar  4 12:27:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Require "intprops" gnulib module.
+
+       * acinclude.m4: Remove BLP_INT_DIGITS.  Now we use the intprops.h
+       header file instead.
+
+       * configure.ac: Don't call BLP_INT_DIGITS.
+
+Sat Mar  4 11:53:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * acinclude.m4: Remove BLP_RANDOM.  Its results were unused.
+       Remove BLP_IS_SPRINTF_GOOD.  We now assume that the system's
+       sprintf() returns the correct value.
+
+       * configure.ac: Don't call those macros.
+
+John Darrington:
+
+       * Deleted Make.build (inserted its contents into Makefile.am).
+       
+       * Moved the version number to 0.4.1
+
+       * Moved lib/linreg/linreg.[ch] and lib/linreg/coefficient.[ch] to
+         src/math/linreg.
+
+       * Moved the psppire gui into src/ui/gui and the gtk_sheet widget 
+          into lib/gtksheet.
+
+       * Replaced recursive automake system with non-recursive one.
+
+       * Moved files into subdirectories. See src/ChangeLog for details.
+
+Sat Feb 11 21:57:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: (GNULIB_MODULES) Add memcasecmp.
+
+       * configure.ac: Remove existing checks for readline, replacing
+       them by a call to PSPP_READLINE.
+
+       * acinclude.m4: Add PSPP_READLINE macro based on gnulib test for
+       readline.  However, we only accept a readline installation if (1)
+       the header files are in the normal readline/ directory and (2) the
+       history library is also available.  If both criteria are met, we
+       declare HAVE_READLINE.  This reduces the #ifdefs to actually use
+       readline to something manageable.
+
+       * pref.h.orig: Move DIR_SEPARATOR, PATH_DELIMITER definitions to
+       src/filename.h.
+
+Wed Jan 25 21:48:20 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: (po/POTFILE.in) Exclude dotfiles.
+
+Sat Nov 27 20:29:19 2005 Jason Stover <jason@sakla.net>
+
+       * Binary encoding for categorical variables.
+       * Routines for design matrices.
+       
+Thu Oct 20 18:19:58 2005  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Improve error messages.  Thanks to Jaap-Andre de
+       Hoop <j.dehoop@data-assist.nl>.
+
+Wed Oct 12 20:33:07 2005 Jason Stover <jstover@sdf.lonestar.org>
+
+       * regression.q: Initial version of the REGRESSION procedure.
+       
+Sun Sep 25 16:11:09 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Handles `examples' as a subdirectory instead of a
+       dist-hook.  The dist-hook copied examples/CVS into the
+       distribution.  Thanks to James R. Van Zandt <jrvz@comcast.net> for
+       reporting the problem.
+
+Mon Sep 19 10:24:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Add `check' target for convenience.  Add
+       --tests-base=tests to gnulib-tool invocation to compensate for
+       bug.
+
+Sat Sep 17 15:57:32 2005 Jason Stover <jason@sakla.net>
+
+       Added lib/linreg for procedures that use ordinary least squares.
+       
+Sat Sep 17 11:01:44 2005  Ben Pfaff  <blp@gnu.org>
+
+       Adapt to newer versions of gnulib.
+
+       * Smake: Put gnulib options directly on its command line, instead
+       of embedding them in configure.ac.
+
+       * configure.ac: Remove gnulib option commands.
+
+Fri Aug  3 07:22:28 2005  Ben Pfaff  <blp@gnu.org>
+
+       * PSPP 0.4.0 released.
+
+Sun Jul 31 10:49:47 2005  Ben Pfaff  <blp@gnu.org>
+
+       Adopt use of gnulib for portability.
+
+       * Makefile.am: Add gl to SUBDIRS.  Add gl/m4 to aclocal include
+       path.  Get rid of pkgdocdir data.  Move noinst_DATA to EXTRA_DIST.
+
+       * README.CVS: Add instructions for fetching gnulib.
+
+       * Smake: Rewrite to run gnulib-tool.  Avoid use of gettextize in
+       normal case (it was unmaintainable).  Just use autoreconf
+       --install to do most of the work.  Rewrite rule for POTFILES.in
+       for non-GNU make compatibility.
+
+       * configure.ac: Add gnulib commands.  Specify gettext version
+       0.14.5 to placate autopoint.  Check that off_t is an integer type,
+       because Solaris can sometimes declare it as a struct.  Drop
+       explicit checks for gnulib-supported functionality.  Fix typo in
+       msdos check.
+
+       * pref.h.orig: Define __attribute__ to avoid wart in gnulib.
+       Don't #include <libintl> and define gettext, _, N_, because gnulib
+       wants to do the same thing.
+
+Sun Jul 24 20:31:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Don't detect libgmp anymore, because we eliminated
+       the dependency.
+
+       * NEWS: Update.
+
+Mon Jul  4 17:59:54 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add pspp-mode.el to EXTRA_DIST.
+
+Wed May  4 08:49:13 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * README.CVS Smake: Added a CONFIGUREFLAGS variable.
+       * INSTALL: Mentioned build dependencies.
+
+Mon May  2 22:37:39 2005  Ben Pfaff  <blp@gnu.org>
+
+       * INSTALL: Mention dependencies.  Thanks to Jaap-Andre de Hoop
+       <j.dehoop@data-assist.nl> for the suggestion.
+
+       * NEWS, README: Update.
+
+Sun May  1 15:00:09 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * pspp-mode.el: Now supports syntax highlighting, indentation and
+       generally works a lot better.
+
+Thu Apr 28 10:24:47 WST 2005 John Darrington <john@darrington.wattle.id.au> 
+
+       * Changed all copyright notices to contain the FSF's new address.
+
+Thu Apr 14 2005 John Darrington
+
+       * AUTHORS:  Added note about the long variable names extension.
+
+       * pref.h.orig: Added definitions for variable names lengths.
+
+Thu Mar  3 22:06:19 WST 2005 John Darrington <john@darrington.wattle.id.au> 
+
+       * configure.ac: Added AC_PROG_RANLIB --- needed by autoconf 1.9
+
+Mon Feb 28 23:16:58 2005  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Check for perl.  Check for bool.  Substitute
+       makefiles in src/expressions.  Don't substitute makefile in
+       deleted directory lib/julcal.
+
+       * pref.h.orig: (macro MALLOC_LIKE) New macro.
+       (macro flt64) Moved to src/sfmP.h.
+       (macro FLT64_MAX) Moved to src/sfmP.h.
+
+Mon Feb 21 15:04:55 WST 2005 John Darrington <john@darrington.wattle.id.au> 
+
+       * configure.ac: Added a --without-valgrind option to cope with
+       building on machines with a broken valgrind installation
+
+Fri Jan  7 08:01:02 WST 2005 John Darrington <john@darrington.wattle.id.au> 
+
+       * configure.ac pref.h.orig: Compilation with libplot is now optional
+       by sacrificing the chart features.
+
+Sun Nov 28 19:24:02 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Smake: Change -a to -pR in cp invocations for SUSv3 compliance.
+
+Mon May 31 17:21:25 2004  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Check for large file support.  Get rid of
+       posix_fadvise check--for some reason glibc 2.3.2 segfaults when I
+       call it and I just couldn't figure out what was going on.
+
+Sun May 30 18:19:03 2004  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Check for valgrind/valgrind.h.
+
+Mon Mar 29 15:22:48 2004  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * configure.ac: Check for posix_fadvise.
+
+Tue Mar 23 14:21:12 WAST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * Removed dcdflib and replaced with a dependency upon the
+        GNU Scientific library instead.
+
+Sat Mar 20 13:55:36 2004  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+Wed Feb 11 23:54:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Don't meddle with __WIN32__, __MSDOS, __DJGPP__,
+       __CYGWIN32__, __unix__, or unix anymore, and deal with some of the
+       consequences.  Declare ATTRIBUTE instead of meddling withe
+       __attribute__.  Declare UNUSED instead of unused.  Add macros
+       NO_RETURN, PRINTF_FORMAT, SCANF_FORMAT.  Reformat gettext, N_, _
+       macros.  Move alloca()-related stuff to src/alloc.h and simplify.
+       Get rid of PAGED_STACK entirely.  Remove mkdir macro definition.
+       Get rid of obsolete "procedure-specific options".
+
+2004-01-23  gettextize  <bug-gnu-gettext@gnu.org>
+
+       * Makefile.am (SUBDIRS): Remove intl.
+       * configure.ac (AC_CONFIG_FILES): Remove intl/Makefile.
+
+Tue Dec 30 22:23:40 WST 2003 John Darrington <john@darrington.wattle.id.au> 
+       
+       * Fixed floating point rounding bug in percentiles calculation
+
+Sat Dec 27 16:16:49 2003  Ben Pfaff  <blp@gnu.org>
+
+       * configure.ac: Add -Wmissing-prototypes flag to gcc.
+
+       * TODO: Updated.
+
+Wed Dec 17 12:19:40 WAST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * Added an --enable-debug flag to configure
+
+2003-12-13  gettextize  <bug-gnu-gettext@gnu.org>
+
+       * Makefile.am (EXTRA_DIST): Add mkinstalldirs.
+       * configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
+
+
+Thu Dec 11 19:35:32 WST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * Removed autogenerated files from the CVS archive
+
+        * removed the included getopt.c as it failed to build under some
+        systems.
+
+Thu Dec 11 00:12:19 2003  Ben Pfaff  <blp@gnu.org>
+
+       * Update build system to Autoconf 2.58, Automake 1.7, gettext
+       0.12.1.
+
+2003-12-08  gettextize  <bug-gnu-gettext@gnu.org>
+
+       * Makefile.am (SUBDIRS): Add m4.
+       (ACLOCAL_AMFLAGS): New variable.
+       (EXTRA_DIST): Add config.rpath.
+       * configure.in (AC_CONFIG_FILES): Add po/Makefile.in,
+
+Sun Jan  2 21:24:32 2000  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Require Automake 1.4 or later.  It's been out for
+       almost a year now, so why haven't you installed it? :-)
+
+       * TODO: Updated.
+
+       * configure.in: Updated version number.  Check for libgmp.  Check
+       of fenv.h.  Check for feholdexpect().
+
+       * pref.h.orig: Don't include debug-print.h by default.  Don't
+       disable __attribute ((unused))__ for gcc 2.7.2.  Remove LOAD_2,
+       STORE_2.  Comment fixes.
+
+       * Updated copyright notices in all files.
+
+Fri Mar 12 12:38:55 1999  Ben Pfaff  <blp@gnu.org>
+
+       * Forked 0.3.0.
+
+Tue Mar  9 12:46:31 1999  Ben Pfaff  <blp@gnu.org>
+
+       * Released 0.2.3.
+       
+       * TODO: Updated.
+
+Tue Jan  5 15:18:07 1999  Ben Pfaff  <blp@gnu.org>
+
+       * Released 0.2.2.
+
+       * TODO: Update from Zvi Grauer <z.grauer@sims.csuohio.edu>.
+
+Thu Nov 19 12:34:55 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Released 0.2.1.
+
+Sun Aug  9 11:11:32 1998  Ben Pfaff  <blp@gnu.org>
+
+       * LANGUAGE: Updated.
+
+Sat Aug  8 00:19:08 1998  Ben Pfaff  <blp@gnu.org>
+
+       * LANGUAGE: Updated.
+
+       * examples/: New directory.
+
+       * Made patchlevel 95.
+
+Tue Aug  4 23:47:31 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Bump version to 0.1.22 (0.2.0 release candidate).
+
+       * configure.in: Remove --enable-Werror, new option
+       --enable-debugging.  New gcc option -Wpointer-arith.
+
+       * pref.h.orig: Don't enable debugging by default (now a configure
+       option).  Use __inline__ instead of inline with gcc (partial -ansi
+       -pedantic support).
+       (macro local_strdup) Removed.
+
+       * Made patchlevel 94.
+       
+Wed Jul 29 22:03:11 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Bump version to 0.1.21 (0.2.0 release candidate).
+
+       * debian/: Removed.
+
+       * Makefile.am: Don't copy debian/ into distribution.
+       
+       * pref.h.orig: Only enable `unused' attribute if gcc 2.8.0 or
+       later is used.
+
+Sun Jul  5 14:20:04 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bump version to 0.1.20 (0.2.0 release candidate).
+
+       * Made patchlevel 93.
+
+Sun Jul  5 00:13:58 1998  Ben Pfaff  <blp@gnu.org>
+
+       * README: Updated.
+
+       * TODO: Updated.
+
+       * configure.in: Remove -Wno-unused from default gcc flags.
+
+       * pref.h.orig: Add new #define, `unused', which under gcc expands
+       to an explanation to the compiler that a function argument is
+       unused, and expands to the null string under other compilers.
+
+Mon Jun  1 14:33:02 1998  Ben Pfaff  <blp@gnu.org>
+
+       * LANGUAGE: Updated.
+
+       * configure.in: Bump version to 0.1.19.
+
+       * Made patchlevel 92.
+
+Sun May 31 00:55:13 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+               
+       * configure.in: Generate Makefiles for lib/gmp/{,mpn,mpf}/.
+
+       * Made patchlevel 91.
+
+Fri May 29 21:43:09 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * LANGUAGE: Updated.
+
+       * unconfigure: Remove TeX cruft from doc/.
+       
+       * Made patchlevel 90.
+
+Mon May 25 12:41:54 1998  Ben Pfaff  <blp@gnu.org>
+
+       * BUGS: Updated.
+
+       * LANGUAGE: Updated.
+
+       * TODO: Updated.
+
+       * configure.in: Bumped version number up to 0.1.18.
+
+       * Made patchlevel 89.
+
+Sun May 24 22:39:55 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 88.
+
+Sat May 23 23:21:43 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * configure.in: Remove gamma from replaceable functions.
+
+       * Made patchlevel 87.
+
+Fri May 22 00:02:33 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Add gamma to list of functions with replacements.
+
+       * Made patchlevel 86.   
+
+Wed May 20 00:00:12 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 85.
+
+Sat May 16 19:38:49 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 84.
+
+Tue May 12 16:13:48 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * unconfigure: Don't delete Makefile.in under intl/.
+       
+       * Made patchlevel 83.
+
+Thu May  7 23:16:26 1998  Ben Pfaff  <blp@gnu.org>
+
+       * unconfigure: Add some more files to reap.
+
+       * Made patchlevel 82.
+
+Tue May  5 13:17:59 1998  Ben Pfaff  <blp@gnu.org>
+
+       * acconfig.h: Add HAVE_GOOD_RANDOM definition.
+
+       * acinclude.m4: New macro BLP_RANDOM.
+
+       * configure.in: Use new BLP_RANDOM macro.
+
+       * unconfigure: New file.
+       
+       * Made patchlevel 81.
+       
+Fri Apr 24 12:42:14 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Remove bad comment.
+
+       * AUTHORS: Removed Brad Appleton.
+       
+       * TODO: Updated.
+
+       * configure.in: Remove `satisfy automake' bit.  Don't generate
+       avllib Makefile, since we don't use avllib anymore.
+
+       * pref.h.orig: Define PSPP.
+
+       * Made patchlevel 80.
+
+Wed Apr 15 12:59:39 1998  Ben Pfaff  <blp@gnu.org>
+
+       * AUTHORS, BUGS, LANGUAGE, README, THANKS: No longer generated
+       from HTML.  This caused a lot of deletions from the Makefile.am.
+
+       * TODO: Updated.
+       
+       * Made patchlevel 79.
+       
+Tue Apr 14 00:48:00 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * configure.in: Check for unistd.h.  Fix AC_LN_S (should have been
+       AC_PROG_LN_S).
+
+       * Made patchlevel 78.  Must have missed 77 in there somewhere :-)
+       
+Mon Mar  9 15:40:40 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 76.
+
+       * configure.in: Bumped version up to 0.1.16.
+
+1998-03-05  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bumped version up to 0.1.15.
+
+1998-02-23  Ben Pfaff  <blp@gnu.org>
+
+       * acinclude.m4: Add BLP_INT_DIGITS and BLP_IS_SPRINTF_GOOD macros.
+
+       * configure.in: Those macros came from here.  Better modularity
+       this way.  Bump version up to 0.1.14.
+
+       * pref.h.orig: (macros CONFIG_PATH, INCLUDE_PATH, GROFF_FONT_PATH)
+       Removed.
+       
+       * Made patchlevel 75.
+
+1998-02-23  Ben Pfaff  <blp@gnu.org>
+
+       * acconfig.h: Hard-code PACKAGE and GNU_PACKAGE as "PSPP" and "GNU
+       PSPP" respectively.
+
+       * configure.in: Call the package pspp instead of PSPP.  Don't
+       define PACKAGE and GNU_PACKAGE symbols.  Add replacement function
+       for strtok_r.
+
+       * TODO: Updated.
+       
+       * Made patchlevel 74.
+
+1998-02-16  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Remove a few now-useless targets.
+
+       * TODO: Updated.
+
+       * configure.in: Bump version up to 0.1.13.
+
+       * reconfigure: Don't assume . is in PATH.
+
+       * Made patchlevel 73.
+
+Fri Feb 13 15:35:03 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bump version up to 0.1.12.
+
+       * TODO: Updated.
+
+       * pref.h.orig: Make __unix equivalent to unix and __unix__; don't
+       require any of these to be defined to 1, just defined.  Invert
+       sense of some tests from testing for unix to testing for not being
+       msdog.
+
+       * Made patchlevel 72.
+
+Thu Feb  5 00:22:58 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 71.
+
+       * configure.in: Bump version up to 0.1.11.
+
+Tue Feb  3 16:12:34 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 70.
+
+       * configure.in: Bump version up to 0.1.10.
+
+Fri Jan 23 00:17:18 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 69.
+
+Thu Jan 22 00:35:52 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 68.
+
+Sun Jan 18 00:30:18 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Add ieeefp.h to list of headers to check for.
+
+       * Made patchlevel 67.
+
+Tue Jan 13 23:44:16 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Add sys/wait.h to list of headers to check for.
+
+       * Made patchlevel 66.
+       
+Sun Jan 11 21:30:09 1998  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bump version up to 0.1.9.
+       
+       * pref.h.orig (STORE_2): Fix parentheses.  From Alexandre
+       Oliva <oliva@dcc.unicamp.br>.
+
+       * Made patchlevel 65.
+       
+Sat Jan 10 23:59:06 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 64.
+
+Sat Jan 10 02:10:15 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * pref.h.orig: Comment fixes.
+       (macro second_lowest_flt64) New.
+
+       * Made patchlevel 63.
+
+Thu Jan  8 22:27:03 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+       
+       * Made patchlevel 62.
+
+Mon Jan  5 11:18:37 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 61.
+
+Sun Jan  4 18:10:29 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * pref.h.orig: (local_strdup) [HAVE_ALLOCA && PAGED_STACK &&
+       __GNUC__] Rewritten for space and time efficiency and to evaluate
+       its argument only once.
+
+       * Made patchlevel 60.
+
+Sat Jan  3 16:51:20 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 59.
+
+Fri Jan  2 01:38:37 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * config.sub: Got tired of `i686-unknown-linux: Unknown system',
+       so I made 686 equivalent to 586.
+
+       * pref.h.orig: (macros ASCII_*, HTML_*, PS_*) Removed.
+
+       * Made patchlevel 58.
+
+Thu Jan  1 11:50:47 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 57.
+
+Fri Dec 26 15:43:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 56.
+
+Wed Dec 24 22:34:55 1997  Ben Pfaff  <blp@gnu.org>
+
+       * reconfigure: regularized option syntax.
+
+       * configure.in: Bumped version to 0.1.8.  Changed name from pspp
+       to PSPP.  Added lib/dcdflib/Makefile to list of output files.
+
+       * Made patchlevel 55.
+
+Sun Dec 21 15:58:52 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * acconfig.h: Reformat.
+
+       * configure.in: Bumped version to 0.1.7.
+
+       * Made patchlevel 54.
+
+Fri Dec  5 23:38:12 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Replaced prep.ai.mit.edu with ftp.gnu.org and .gnu.ai.mit.edu
+       with .gnu.org, everywhere.
+
+Fri Dec  5 23:02:40 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Replaced remaining instances of Fiasco with PSPP.
+
+       * Made patchlevel 53.
+
+Fri Dec  5 22:51:18 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Every instance of the name Fiasco, throughout every file,
+       replaced in-place with PSPP, with the exceptions of a few files
+       that had `fiasco' in their names; these were renamed.
+
+       * Made patchlevel 52.
+       
+Fri Dec  5 21:50:52 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: (macros NO_HTML, HTML_DEFAULT_OUTPUT_FILE) New
+       macros.
+
+       * TODO: Updated.
+
+       * Made patchlevel 51.
+
+Tue Dec  2 14:35:12 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * configure.in: Bumped version to 0.1.6.
+
+       * Made patchlevel 50.   
+
+Sat Nov 22 01:20:32 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 49.
+
+Fri Nov 21 00:11:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 48.
+
+Sun Nov 16 01:31:38 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 47.
+
+Fri Nov 14 00:17:48 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 46.
+
+       * configure.in: Bumped version to 0.1.5.
+
+Tue Oct 28 16:07:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bumped version to 0.1.4.
+
+       * TODO: Updated.
+
+       * Made patchlevel 45.
+
+Wed Oct  8 15:55:50 1997  Ben Pfaff  <blp@gnu.org>
+
+       * intl: Upgraded from sources to gettext-0.10.32.
+
+       * configure.in: Bumped version to 0.1.3.
+
+       * Made patchlevel 44.
+       
+Tue Oct  7 20:21:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (dist-hook) Use $(top_srcdir).
+
+       * pref.h.orig: (MAX_WORKSPACE) Enlarge to 4 MB (from 1 MB).
+
+       * Made patchlevel 43.
+       
+Sun Oct  5 15:52:37 1997  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Bumped version to 0.1.2.
+       (strerror) Replace instead of check.  From Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       * pref.h.orig: Include `debug-print' instead of
+       `src/debug-print.h'.
+
+       * Made patchlevel 42.
+
+Sat Oct  4 16:19:44 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Comment fixes.
+       (local_strdup) [HAVE_ALLOCA && PAGED_STACK &&
+       __GNUC__] Use local_alloc() instead of alloca(), as local_alloc()
+       isn't simply an alias for alloca().
+
+       * configure.in: Bumped version to 0.1.1.
+
+       * Made patchlevel 41.
+
+Sat Oct  4 02:13:00 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 40.
+
+Sun Sep 21 00:07:09 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 39.
+
+Thu Sep 18 21:42:27 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: (CONFIG_PATH) [unix] Add /usr/local/etc/fiasco,
+       /usr/etc/fiasco to search path.
+
+       * Made patchlevel 38.
+               
+Wed Aug 20 14:20:06 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (noinst_DATA) Removed ANNOUNCE, HELP-WANTED.
+       (EXTRA_DIST) Removed ANNOUNCE, FAQ, HELP-WANTED, mk-web-dist.
+       (MAINTAINERCLEANFILES) Removed ANNOUNCE, FAQ, HELP-WANTED.
+
+       * Made patchlevel 37.
+
+Wed Aug 20 12:48:25 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (doc/ANNOUNCE.html, ANNOUNCE, FAQ, doc/FAQ.html,
+       HELP-WANTED) Removed.
+       (docfiles) Removed ANNOUNCE, FAQ, HELP-WANTED.
+
+       * mk-web-dist: Removed.
+
+       * Made patchlevel 36.
+
+Mon Aug 18 18:06:12 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * pref.h.orig: (macro DEFAULT_COMPAT) Removed.
+
+       * Made patchlevel 35.
+
+Sun Aug 17 22:48:36 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 34.
+
+Sat Aug 16 10:48:29 1997  Ben Pfaff  <blp@gnu.org>
+
+       * In many files, in this directory and others, messages were
+       rephrased to eliminate or reduce usage of certain deprecated terms
+       at suggestion of rms.
+       
+       * Makefile.am: (EXTRA_DIST) Removed unix2dos.pl.
+       (MAINTAINERCLEANFILES) Removed doc/ANNOUNCE.html, doc/README.html.
+       (docfiles-recursive) Removed.
+
+       * TODO: Updated.
+
+       * mk-web-dist: Doesn't produce any distributions at all, just a
+       webpage.  Doesn't configure the distribution.  Changed list of
+       files installed.
+
+       * pref.h.orig: s/VER_PCP40/VER_PC/; s/VER_WIN61/VER_WND/;
+       s/VER_X40/VER_X/; All references changed.
+
+       * Made patchlevel 33.
+
+Thu Aug 14 22:02:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Comment fixes.  Uses $(VERSION) instead of contents
+       of VERSION file.
+       (EXTRA_DIST) Remove fiasco.ide, mk-bc5-dist.
+       (docfiles-recursive) Works if doc/Makefile doesn't exist.
+       (DIST_BC5_ROOT) Renamed DISTBC5_DISTROOT.
+       (DISTBC5_BC5ROOT) New var.
+       (dist-bc5) Passes $(DISTBC5_BC5ROOT).
+
+       * TODO: Update.
+
+       * acinclude.m4: Remove blp_VERSION_CHEAT kluge.
+
+       * configure.in: Don't use blp_VERSION_CHEAT kluge.
+
+       * mk-web-dist, reconfigure: Extract version number from
+       configure.in.
+
+       * pref.h.orig: (CONFIG_PATH, INCLUDE_PATH, GROFF_FONT_PATH)
+       [__MSDOS__] Fixed bad use of backslashes.
+
+       * reconfigure: Pass $VERSION to Makefile.
+
+       * Made patchlevel 32.
+
+Thu Aug 14 11:49:35 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST, docfiles) Add ONEWS.
+       (docfiles) Depends on docfiles-recursive.
+       (docfiles-recursive) New target, call make for `docfiles' target
+       in doc directory.
+       (dist-bc5) Adds `foo' second arg to mk-bc5-dist.
+       (.PHONY) Add docfiles.
+
+       * mk-bc5-dist: Checks that it is passed a second arg of `foo'.
+
+       * reconfigure: Changed == operators to = as arguments to `test'.
+       No longer uses bash -v switch.
+
+       * mk-distribution: Renamed mk-web-dist, all references changed.
+       Now takes several options, added help.  No longer uses -uv
+       options.
+
+       * Made patchlevel 31.
+
+Tue Aug  5 13:56:39 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (MAINTAINERCLEANFILES) Add HELP-WANTED.
+       (EXTRA_DIST) Add ONEWS.
+
+       * Made patchlevel 30.
+
+Sun Aug  3 11:30:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (noinst_data, docfiles) Added HELP-WANTED.
+       (EXTRA_DIST) Added configure, mk-bc5-dist, unix2dos.pl,
+       HELP-WANTED.
+       (HELP-WANTED) Generated from doc/HELP-WANTED.html.
+       (dist-bc5) New target.
+
+       * TODO: Updated.
+
+       * mk-distribution: Fixed bugs, added HELP-WANTED.
+
+       * reconfigure: When invoking Makefile.am, pass
+       top_srcdir=. explicitly.
+
+       * unix2dos.pl: New file.
+
+       * Made patchlevel 29.
+
+Thu Jul 17 21:49:13 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 28.
+
+Thu Jul 17 01:43:25 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Remove inactive .html suffix rule.
+       New rules to generate doc/ANNOUNCE.html and doc/README.html from
+       corresponding .in files.
+       (EXTRA_DIST) Add VERSION, fiasco.ide, mk-distribution.
+       (MAINTAINERCLEANFILES) Add doc/ANNOUNCE.html, doc/README.html.
+
+       * acinclude.m4: (blp_VERSION_CHEAT) New macro.
+
+       * configure.in: Forces _GNU_SOURCES not only to be defined, but to
+       a value of 1.  Substitutes VERSION from the new file VERSION.
+       Removed DEBIAN reference.  Checks for sys/mman.h header.
+
+       * pref.h.orig: (macro gettext) Don't put parentheses in the
+       expansion.
+       (macro N_) Same.
+
+       * reconfigure: Sets -ev in shell.  Doesn't try to pass
+       --include-deps to configure (it's an automake flag!).  Moved `make
+       docfiles'.
+
+       * sysdeps/borlandc4.0/README, sysdeps/borlandc4.0/_read.c,
+       sysdeps/borlandc4.0/_write.c, sysdeps/borlandc4.0: Removed.
+
+       * VERSION: New file.
+
+       * fiasco.ide: New file.
+
+       * mk-distribution: New file.
+
+       * Made patchlevel 27.
+       
+Fri Jul 11 23:00:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updates.
+
+       * Made patchlevel 26.
+
+Fri Jul 11 14:08:21 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: __CYGWIN32__ is a form of __unix__.
+
+       * reconfigure: Add -k for make maintainer-clean.
+
+       * Made patchlevel 25.
+
+Thu Jul 10 22:13:07 1997  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Add "-D_GNU_SOURCE" to CPPFLAGS to force GNU
+       glibc extensions to be detected.
+
+       * Made patchlevel 24.
+
+Sun Jul  6 19:13:07 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Include "src/debug-print.h" instead of
+       "debug-print.h".
+       (macros local_alloc, local_free) More robust under Checker: put
+       their allocations in namespace different from malloc()/free().
+
+       * Made patchlevel 23.
+
+Sat Jul  5 23:42:14 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updates.
+
+       * Made patchlevel 22.
+
+Fri Jul  4 13:20:47 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Removed orphaned-rules.
+       (docfiles) Removed ChangeLog, COPYING.
+       (html, maintainer-clean-hook, install-data-hook) Removed.
+
+       * reconfigure: Added --help option.  Calls configure again even if
+       --no-include-deps.
+
+       * Made patchlevel 21.
+
+Wed Jun 25 22:47:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Require Automake 1.2.
+       (dist-hook) Don't copy config dir.
+       (EXTRA_DIST, MAINTAINERCLEANFILES) Add FAQ.
+       (docfiles) Made a variable as well as a target; added ChangeLog,
+       COPYING, FAQ, INSTALL, TODO.
+       (html, maintainer-clean-hook, install-data-hook, debian,
+       debian-clean, debian-clean-full) New targets.
+
+       * orphaned-rules: Removed.
+
+       * configure.in: Bumped up to version 0.1.0.
+
+       * reconfigure: New options --enable-nls, --no-include-deps.
+       Comment fixes.
+
+       * Made patchlevel 20.
+
+Sun Jun 22 22:10:27 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 19.
+
+Sun Jun 15 16:44:14 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Comment fixes.  Includes debug-print.h.
+       (DEMAND_PAGE, ALWAYS_PAGE, NEVER_PAGE) Removed.
+
+       * Made patchlevel 18.
+
+Sun Jun  8 01:25:40 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 17.
+
+Fri Jun  6 22:41:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updates.
+
+       * pref.h.orig: Reformatted macros.
+       [!ENABLE_NLS] Defines gettext() as a trivial substitution to allow
+       gcc to give warnings on printf().
+
+       * Made patchlevel 16.
+       
+Thu Jun  5 23:01:49 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 15.
+
+Tue Jun  3 23:24:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: AUTOMAKE_OPTIONS changed from `foreign 1.1l' to
+       `gnits 1.1p'.  SUBDIRS reordered.  New target `docfiles'.
+
+       * TODO: Updates.
+
+       * configure.in: Removed AM_MAINTAINER_MODE.  Added
+       --enable-Werror, which is implied by --with-checker.
+
+       * reconfigure: Moved `aclocal' from beginning to just before
+       cleaning `autoheader'.  Removed --enable-maintainer-mode.  Added
+       --disable-nls.  Added `make docfiles' to placate autoheader.
+       Added `aclocal' before first real `autoheader'.  Uses `make
+       mostlyclean' instead of `make depend'.
+
+       * Made patchlevel 14.
+
+Mon Jun  2 14:21:54 1997  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Removed comment that screwed things up.
+
+       * reconfigure: Added `aclocal' at beginning.
+
+       * Made patchlevel 13.
+
+Sun Jun  1 23:25:39 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add intl, po to SUBDIRS.  Add aclocal.m4,
+       config.h.in to MAINTAINERCLEANFILES.
+
+       * acconfig.h: Add HAVE_LC_MESSAGES, ENABLE_NLS, HAVE_CATGETS,
+       HAVE_GETTEXT, HAVE_STPCPY.
+
+       * configure.in: Reordered to placate autoheader.  Added
+       AC_ISC_POSIX, AM_PROG_CC_STDC.  Added internationalization:
+       ALL_LINGUAS="", AM_GNU_GETTEXT, AC_LINK_FILES(...).  Added
+       po/Makefile.in, intl/Makefile to generated files list.  Generates
+       po/Makefile from po/Makefile.in.  Comment fix.
+
+       * pref.h.orig: Uncommented i18n support.
+
+       * acinclude.m4: New file.
+
+       * ABOUT-NLS: New file.
+
+       * intl/: New directory, taken from gettext-0.10.27.
+
+       * missing: New file, taken from automake-1.1p.
+
+       * po/: New directory.
+
+       * Made patchlevel 12.
+
+Sun Jun  1 17:28:27 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 11.
+
+Sun Jun  1 11:58:43 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: Removed DEFAULT_VER_PCP40, DEFAULT_VER_WIN61,
+       DEFAULT_VER_X40.  Added a macro DEFAULT_COMPAT that takes one of
+       the VER_* enums as a value.
+       (HISTORY_FILE) Changed the definition to "~/.fiasco_history".
+
+       * Made patchlevel 10.
+
+Fri May 30 19:40:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * pref.h.orig: [__MSDOS__] Reordered INCLUDE_PATH.
+
+       * Made patchlevel 9.
+
+Sun May 25 22:32:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * acconfig.h: For support of glibc 2, define _GNU_SOURCE.
+
+       * Made patchlevel 8.
+
+Mon May  5 21:58:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 7. 
+
+Fri May  2 22:27:36 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 6.
+
+Thu May  1 15:34:01 1997  Ben Pfaff  <blp@gnu.org>
+
+       * All files: Changed copyright from `Ben Pfaff' to `Free Software
+       Foundation, Inc'.
+
+       * Made patchlevel 5.
+
+Thu May  1 15:00:51 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 4.
+
+Sat Apr 26 11:34:05 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ChangeLog: Split into one ChangeLog per directory.
+
+       * Made patchlevel 3.
+
+Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Update.
+
+       * Made patchlevel 2.
+
+Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Removed `include', `util' from SUBDIRS; added
+       `config'.  Includes `config' directory in distributions.  Added
+       `private-install', `private-uninstall' targets.
+
+       * configure.in: AC_INIT tests for src/q2c.c now.  Removed
+       redundant AC_PROG_MAKE_SET call.  Removed include/Makefile,
+       util/Makefile from generated files list; added config/Makefile.
+
+       * include/approx.h, include/arena.h, include/common.h,
+       include/dfm.h, include/do-ifP.h, include/error.h, include/expr.h,
+       include/exprP.h, include/file-handle.h, include/filename.h,
+       include/font.h, include/getline.h, include/getopt.h,
+       include/hash.h, include/heap.h, include/log.h, include/misc.h,
+       include/output.h, include/settings.h, include/sfm.h,
+       include/sfmP.h, include/som.h, include/somP.h, include/stat.h,
+       include/stats.h, include/str.h, include/tokens.h, include/var.h,
+       include/version.h, include/vfmP.h: Moved into src/ directory.
+
+       * include/Makefile.am, include/: Removed.
+
+       * util/Makefile.am: Removed.
+
+       * util/q2c.c: Moved to src/.
+
+       * util/reconfigure: Moved to source root.
+
+       * util/: Removed.
+
+       * Made patchlevel 1.
+
+Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Maintainer-cleans generated documentation and
+       Makefile.in.
+
+       * include/Makefile.am, util/Makefile.am: Maintainer-cleans
+       Makefile.in.
+
+       * include/somP.h: (static struct var som) Removed passed_t member.
+
+       * TODO: Updated.
+
+       * configure.in: Fixed source directory for copying pref.h; always
+       updates pref.h or at least touch'es it.
+
+       * pref.h.orig: Made a rather pejorative comment a lot milder so it
+       wouldn't be misinterpreted.
+
+       * Made interim release x3.
+       
+Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
+
+       * All directories now contain new `Makefile.am's, in some cases
+       produced from bits and pieces of the single monolithic old one.
+       
+       * PATCHLEVEL: Removed.
+
+       * acconfig.h: Added GNU_PACKAGE, PACKAGE, PROTOTYPES, VERSION;
+       removed inclusion of conf.h.
+
+       * confh.in: Removed.
+       * confh.tmp.in: Removed.
+       
+       * configure.in: Deepened.  Updated for use with Automake 1.1l.
+       Removed PATCHLEVEL hacks.  Fixed lots of functions in
+       AC_CHECK_FUNCS, AC_REPLACE_FUNCS, and similar.  Only passes
+       `-Werror' to gcc in maintainer mode.  Doesn't output conf.h.
+       Touches pref.h even if it wasn't changed.  
+
+       * aclocal.m4: New file.
+
+       * config.h.in: Renamed from configh.in.
+
+       * pref.h.orig: Renamed from prefh.orig.
+
+       * Made interim release x2.
+       
+Thu Mar 27 01:07:02 1997  Ben Pfaff  <blp@gnu.org>
+
+    Changed the distribution from flat to deep.  New configuration:
+
+       ANNOUNCE        Makefile.in     config.h.in     mkinstalldirs
+       AUTHORS         NEWS            config.sub      orphaned-rules
+       BUGS            README          configure       pref.h
+       COPYING         THANKS          configure.in    pref.h.orig
+       ChangeLog       TODO            debian          src
+       ChangeLog~      acconfig.h      doc             stamp-h.in
+       INSTALL         aclocal.m4      include         sysdeps
+       LANGUAGE        config          install-sh      tests
+       Makefile.am     config.guess    lib             util
+
+       config:
+       devices      environment  papersize    ps-fontmap   ps-prologue
+
+       debian:
+       changelog  control    postinst   rules
+       conffiles  copyright  postrm
+
+       doc:
+       ANNOUNCE.html  Makefile.in    fiasco.info-2  stamp-vti
+       AUTHORS.html   README.html    fiasco.info-3  texinfo.tex
+       BUGS.html      THANKS.html    fiasco.info-4  version.texi
+       LANGUAGE.html  fiasco.info    fiasco.texi
+       Makefile.am    fiasco.info-1  mdate-sh
+
+       include:
+       approx.h       file-handle.h  misc.h         stats.h
+       arena.h        filename.h     output.h       str.h
+       common.h       font.h         settings.h     tokens.h
+       dfm.h          getline.h      sfm.h          var.h
+       do-ifP.h       getopt.h       sfmP.h         version.h
+       error.h        hash.h         som.h          vfmP.h
+       expr.h         heap.h         somP.h
+       exprP.h        log.h          stat.h
+
+       lib:
+       Makefile.am  Makefile.in  avllib       julcal       misc
+
+       lib/avllib:
+       AVLLIB.COPYING  Makefile.in     avl.h
+       Makefile.am     avl.c
+
+       lib/julcal:
+       Makefile.am  Makefile.in  julcal.c     julcal.h
+
+       lib/misc:
+       Makefile.am    getopt1.c      memset.c       strstr.c
+       Makefile.in    memchr.c       qsort.c        strtol.c
+       alloca.c       memcmp.c       stpcpy.c       strtoul.c
+       getdelim.c     memcpy.c       strcasecmp.c
+       getline.c      memmem.c       strncasecmp.c
+       getopt.c       memmove.c      strpbrk.c
+
+       src:
+       Makefile.am     error.c         lexer.c         sfm-write.c
+       Makefile.in     expr-evl.c      list.c          show.c
+       arena.c         expr-opt.c      list.q          som-frnt.c
+       ascii.c         expr-prs.c      log.c           som-high.c
+       autorecode.c    file-handle.c   loop.c          som-low.c
+       cases.c         file-handle.q   main.c          sort.c
+       cmdline.c       file-type.c     mis-val.c       split-file.c
+       command.c       filename.c      misc.c          stats.c
+       common.c        formats.c       modify-vars.c   str.c
+       compute.c       freq.c          numeric.c       sysfile-info.c
+       count.c         frequencies.c   output.c        temporary.c
+       crosstabs.c     frequencies.g   postscript.c    title.c
+       crosstabs.q     frequencies.q   print.c         val-labs.c
+       data-in.c       get.c           recode.c        var-labs.c
+       data-list.c     getline.c       rename-vars.c   vars-atr.c
+       data-out.c      glob.c          repeat.c        vars-prs.c
+       descript.c      groff-font.c    sample.c        vector.c
+       descript.q      hash.c          sel-if.c        version.c
+       dfm.c           heap.c          set.c           vfm.c
+       display.c       include.c       set.q           weight.c
+       do-if.c         inpt-pgm.c      sfm-read.c
+
+       sysdeps:
+       BorlndC4.0  DJGPP2.0    Windows
+
+       sysdeps/BorlndC4.0:
+       Makefile     _write.c     conf.h
+       _read.c      compile.bat  config.h
+
+       sysdeps/DJGPP2.0:
+       Makefile     compile.bat  conf.h       config.h
+
+       sysdeps/Windows:
+       con32s.c
+
+       tests:
+       Makefile.am         expression.stat     reread.data
+       Makefile.in         fall92.data         reread.stat
+       autorecode.stat     fall92.stat         sample.stat
+       begin-data.stat     file-label.stat     show-check-msg
+       bignum.data         file-type.stat      sort.data
+       bignum.stat         filter.stat         sort.stat
+       bug.stat            gengarbage.c        split-file.stat
+       compute.stat        input-program.stat  sysfile-info.stat
+       count.stat          list.data           temporary.stat
+       data-formats.stat   list.stat           time-date.stat
+       data-list.data      loop.stat           vector.stat
+       data-list.stat      modify-vars.stat    weighting.data
+       descript.stat       print.stat          weighting.stat
+       do-if.stat          process-if.stat
+       do-repeat.stat      recode.stat
+
+       util:
+       Makefile.am  Makefile.in  q2c.c        reconfigure
+
+    Old configuration:
+
+       ANNOUNCE.html   count.c         hash.h          sample.c
+       AUTHORS.html    crosstabs.q     heap.c          sel-if.c
+       AVLLIB.COPYING  data-in.c       heap.h          set.q
+       BUGS.html       data-list.c     include.c       settings.h
+       COPYING         data-out.c      inpt-pgm.c      sfm-read.c
+       ChangeLog       debian          install-sh      sfm-write.c
+       INSTALL         descript.q      julcal.c        sfm.h
+       LANGUAGE.html   devices         julcal.h        sfmP.h
+       Makefile.am     dfm.c           lexer.c         show.c
+       NEWS            dfm.h           list.q          som-frnt.c
+       PATCHLEVEL      display.c       log.c           som-high.c
+       README.html     do-if.c         log.h           som-low.c
+       THANKS.html     do-ifP.h        loop.c          som.h
+       TODO            environment     main.c          somP.h
+       _read.c         error.c         makeb40.bat     sort.c
+       _write.c        error.h         makedj2.bat     split-file.c
+       acconfig.h      expr-evl.c      makefile.b40    stamp-h.in
+       alloca.c        expr-opt.c      makefile.dj2    stats.c
+       approx.h        expr-prs.c      mdate-sh        stats.h
+       arena.c         expr.h          memcmp.c        stpcpy.c
+       arena.h         exprP.h         mis-val.c       str.c
+       ascii.c         fiasco.texi     misc.c          str.h
+       autorecode.c    file-handle.h   misc.h          sysfile-info.c
+       avl.c           file-handle.q   mkinstalldirs   temporary.c
+       avl.h           file-type.c     modify-vars.c   test
+       cases.c         filename.c      numeric.c       texinfo.tex
+       cmdline.c       filename.h      output.c        title.c
+       command.c       font.h          output.h        tokens.h
+       common.c        formats.c       papersize       val-labs.c
+       common.h        freq.c          postscript.c    var-labs.c
+       compute.c       frequencies.g   prefh.orig      var.h
+       con32s.c        frequencies.q   print.c         vars-atr.c
+       confh.b40       get.c           ps-fontmap      vars-prs.c
+       confh.dj2       getline.c       ps-prologue     vector.c
+       confh.in        getline.h       q2c.c           version.c
+       confh.tmp.in    getopt.c        qsort.c         version.h
+       config.guess    getopt.h        recode.c        vfm.c
+       config.sub      getopt1.c       reconfigure     vfmP.h
+       configh.b40     glob.c          reject          weight.c
+       configh.dj2     groff-font.c    rename-vars.c
+       configure.in    hash.c          repeat.c
+
+       debian:
+       changelog  control    postinst   rules
+       conffiles  copyright  postrm
+
+       test:
+       autorecode.stat     fall92.data         recode.stat
+       begin-data.stat     fall92.stat         reread.data
+       bignum.data         file-label.stat     reread.stat
+       bignum.stat         file-type.stat      sample.stat
+       bug.stat            filter.stat         sort.stat
+       compute.stat        gengarbage.c        split-file.stat
+       count.stat          gengarbage.pl       sysfile-info.stat
+       data-formats.stat   input-program.stat  temporary.stat
+       data-list.data      list.data           time-date.stat
+       data-list.stat      list.stat           vector.stat
+       descript.stat       loop.stat           weighting.data
+       do-if.stat          modify-vars.stat    weighting.stat
+       do-repeat.stat      print.stat
+       expression.stat     process-if.stat
+
+Mon Mar 24 21:47:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: @ALLOCA@ is on list of source files instead of
+       alloca.c.  Added $(srcdir)/ to version.c reference.  Changed to
+       pkgdatadir (/usr/share) for pkgsysconfdir, from pkglibdir
+       (/usr/lib).  Removed some of extra distfiles.  Added bogus `check'
+       target.
+
+       * Made transition release x1.
+
+Sun Mar  2 20:51:28 1997  Ben Pfaff  <blp@gnu.org>
+
+       No longer uses debmake:
+       
+       * Makefile.am: Installs documentation according to Debian policy
+       manual.  New targets `private-uninstall', `install-data-hook' to
+       help implement this.  `debian' target also revised.
+       
+       * configure.in: Sets up for Debian installation depending on
+       DEBIAN environment variable.  Also, improved & fixed (hopefully)
+       the scheme for detecting patchlevel.
+       
+       * Made patchlevel 193.
+
+Wed Feb 19 21:30:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 192.
+
+Sun Feb 16 20:57:20 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 191.
+       
+Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Removed `descript.g' from sources.
+
+       * Made patchlevel 190.
+       
+Fri Feb 14 23:32:58 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+       
+       * configure.in: Fixed test for max number of digits in an `int' to
+       use char[] rather than int[].
+
+       * Made patchlevel 189.
+       
+Tue Feb  4 15:15:50 1997  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Fixed some problems with `--with-checker' flag and
+       with detection of available libraries; no longer any lines longer
+       than 79 characters.
+
+       * Made patchlevel 188.
+       
+Wed Jan 22 21:54:00 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add sysfile-info.c to sources.
+
+       * TODO: Moved some notes to different files where they are more
+       appropriate.
+
+       * prefh.orig: (macros STORE_2 and LOAD_2) Always load/store as
+       little-endian.
+
+       * Made patchlevel 187.
+
+Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added rename-vars.c to sources.  Added to distclean
+       files.
+
+       * TODO: Updates.
+
+       * Made patchlevel 186.
+
+Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Most files have updated copyright notices for 1997.
+
+       * Makefile.am: Added modify-vars.c to source files.  Also changed
+       `lynx' to $(HTML_FORMATTER), etc.  Changed messages.
+
+       * TODO: Updates.
+
+       * Made patchlevel 185.
+
+Sat Jan 11 15:44:15 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: By default, now installs config files in pkglibdir,
+       generally /usr/local/lib/fiasco.
+
+       * TODO: Updated.
+
+       * prefh.orig: Added `/etc/fiasco' to config paths.  Removed
+       $ARCH/$VER dirs from include paths. 
+
+       * Made patchlevel 184.
+
+Fri Jan 10 20:22:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * debian/changelog, debian/control, debian/copyright, debian/dirs,
+       debian/info, debian/menu, debian/rules: Added Debian GNU/Linux
+       control files.
+       
+       * Makefile.am: Added sfmP.h to source files.  Added several files
+       to the list of distfiles.   dist-hook now copies debian control
+       files.  New targets `debian', `debian-clean', `debian-clean-full'.
+
+       * confh.in: Defines PATCHLEVEL.
+
+       * configure.in: Adds the current patchlevel to the version
+       number.  Versions are now of the form `1.2.3pl456'.  Determines
+       the patchlevel based on directory name and contents of file
+       PATCHLEVEL.
+
+       * reconfigure: Passes automake `--strictness=foreign'.
+
+       * Made patchlevel 183.
+
+Thu Jan  2 19:08:23 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 182.
+
+Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+       
+       * Made patchlevel 181.
+       
+Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: New target for test/sort.data.
+
+       * Made patchlevel 180.
+       
+Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 179.
+
+Tue Dec 24 20:42:32 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 178.
+
+Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added heap.c, heap.h to source files.  Added
+       new html files to distfiles & maintainer-clean files.
+
+       * configure.in: Tests for presence of getpid(), sys/types.h.
+
+       * prefh.orig: #defines mkdir() for MS-DOS compatibility.
+
+       * Made patchlevel 177.
+
+Sat Dec 21 21:51:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added README.html, LANGUAGE.html to list of
+       distfiles.  Added README, LANGUAGE to list of maintainer-clean
+       files.  Added .html to suffixes.  Added .html implicit rule that
+       calls `lynx -dump -nolist'.
+
+       * Made patchlevel 176.
+       
+Tue Dec 17 18:57:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 175.
+       
+Sun Dec 15 15:32:16 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added vfmP.c, qsort, sort.c to list of source
+       files.
+
+       * prefh.orig: Subtle changes to MAX_WORKSPACE, ALWAYS_PAGE,
+       NEVER_PAGE, DEMAND_PAGE macro meanings.
+
+       * Made patchlevel 174.
+       
+Sat Dec 14 10:35:30 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 173.
+       
+Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added autorecode.c to source files.
+
+       * prefh.orig: Fixed path GROFF_FONT_PATH.
+
+       * Made patchlevel 172.
+       
+Fri Dec  6 23:53:47 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+       
+       * Made patchlevel 171.
+       
+Wed Dec  4 21:34:17 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 170.
+       
+Sun Dec  1 17:19:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 169.
+       
+Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added `set.q' to list of source files.
+
+       * Made patchlevel 168.
+
+Thu Nov 28 19:46:10 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 167.
+
+Wed Nov 27 23:18:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added `sfm-write.c' to list of source files.
+
+       * confh.in: New #defines RELEASE_NO, SUB_RELEASE_NO, and
+       SPEC_RELEASE_NO for each part of a version number of form 1.2.3.
+
+       * configure.in: Computes RELEASE_NO, etc., by breaking apart
+       VERSION.
+
+       * prefh.orig: (defn of int32, flt64) Formatting fixes.
+       (FLT64_MAX) New define.
+
+       * Made patchlevel 166.
+       
+Sun Nov 24 14:53:53 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Wow, it's been almost two weeks since the last update, hard to
+       believe.
+
+       * All source files: Updated e-mail address.
+       
+       * prefh.orig: local_alloc() calls xmalloc() under Checker because
+       Checker can keep track of heap blocks much more accurately.
+
+       * Made patchlevel 165.
+       
+Mon Nov 11 15:34:09 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 164.
+       
+Thu Nov  7 20:52:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 163.
+       
+Thu Nov  7 17:29:16 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 162.
+       
+Thu Nov  7 15:48:52 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 161.
+       
+Tue Nov  5 18:34:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 160.
+       
+Mon Nov  4 22:03:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added get.c.
+
+       * TODO: Updated.
+
+       * Made patchlevel 159.
+       
+Sun Nov  3 12:24:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added sfm.h, sfm-read.c to source files.
+
+       * Made patchlevel 158.
+       
+Wed Oct 30 17:13:08 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added dist-zip target to AUTOMAKE_OPTIONS.
+
+       * acconfig.h: Added FPREP_* defines.
+
+       * configure.in: Added checks for the sizes of floating-point
+       types.  Added a test for the internal floating-point
+       representation of the host architecture.
+
+       * prefh.orig: Renamed `ATTRIBUTION' macro as `__attribute__'.  All
+       references changed.  Defines `flt64' 64-bit floating-point for use
+       with system files.
+       [FPREP==FPREP_IEEE754 && __GNUC__ && (ENDIAN==BIG ||
+       ENDIAN==LITTLE] Defines SECOND_LOWEST_VALUE macro.
+       
+       * Made patchlevel 157.
+
+Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Checks sizes of short, int, long, long long.
+
+       * prefh.orig: Defines new type int32 for use with system
+       files.
+
+       * Made patchlevel 156.
+       
+Sat Oct 26 20:46:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 155.
+
+Sat Oct 26 10:39:25 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 154.
+       
+Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added back in these files: recode.c, sample.c,
+       sel-if.c.  Also added files somP.h, hash.c that should've been
+       there anyway.
+
+       * TODO: Updated.
+
+       * configure.in: Checks for strncasecmp in place of strcasecmp.
+
+       * Made patchlevel 153.
+       
+Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * Made patchlevel 152.
+       
+Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Organized.
+
+       * Made patchlevel 151.
+       
+Tue Oct 22 17:27:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Culled old notes.
+
+       * Made patchlevel 150.
+
+Mon Oct 21 20:39:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 149.
+       
+Sun Oct 20 13:45:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added back in `numeric.c', `print.c', `title.c'.
+       Defined ETAGS_ARGS.
+
+       * Made patchlevel 148.
+       
+Sun Oct 20 09:04:15 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 147.
+       
+Fri Oct 18 19:46:49 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 146.
+       
+Sun Sep 29 19:37:03 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 145.
+       
+Sat Sep 28 21:28:07 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added to DISTCLEANFILES. 
+   
+       * Made patchlevel 144.
+       
+Fri Sep 27 20:08:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 143.
+       
+Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added list.c back into the list of source files.
+
+       * Made patchlevel 142.
+       
+Wed Sep 25 19:36:11 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Updated for new files.
+
+       * Made patchlevel 141.
+               
+Tue Sep 24 18:39:09 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 140.
+
+Sat Sep 21 23:16:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 139.
+
+Fri Sep 20 22:52:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 138.
+       
+Thu Sep 12 18:40:33 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 137.
+
+Wed Sep 11 22:01:41 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Added timestamp.
+
+       * prefh.orig: Removed `/usr/local/share/fiasco' and
+       `/usr/share/fiasco' from CONFIG_PATH as per the Linux FSSTND,
+       which specifies that programs should never give an explicit
+       `/usr(/local)/share' path.
+
+       * Made patchlevel 136.
+
+Tue Sep 10 21:39:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added `display.c' back in.
+
+       * TODO: Addition.
+
+       * Made patchlevel 135.
+       
+Mon Sep  9 21:43:13 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added `split-file.c' back into the project.
+
+       * Made patchlevel 134.
+       
+Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Updated.
+
+       * prefh.orig: (local_strdup) Moved to misc.h.
+
+       * Made patchlevel 133. 
+       
+Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Changed `prologue.ps' references to `ps-prologue'.
+
+       * Made patchlevel 132.
+       
+Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prefh.orig: New i18n defines.
+
+       * This patchlevel doesn't even compile.
+
+       * Made patchlevel 131.
+       
+Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: Addition.
+
+       * Made patchlevel 130.
+               
+Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 129.
+       
+Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: New target "private-install" to install config files
+       to $HOME/.fiasco.
+
+       * configure.in: Now that I have made a less-bogus Checker
+       distribution, removed `-b i486-linuxaout -V 2.6.3' from
+       AC_ARG_WITH(checker, ...).
+
+       * Made patchlevel 127 somewhere in there.
+       
+       * Made patchlevel 128.
+       
+Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Changed DISTCLEANFILES.
+
+       * Does not compile.
+       
+       * Made patchlevel 126.
+       
+Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
+
+       * reconfigure: Calls `autoheader' twice: once at the beginning,
+       once after make maintainer-clean.
+
+       * Made patchlevel 125. 
+       
+Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
+
+       * reconfigure: `autoheader' now first operation performed.
+
+       * Made patchlevel 124.
+       
+Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added postscript.c to list of source files.
+
+       * configh.in: Removed since autoheader can regenerate it.
+
+       * configure.in: Improved tests for (ncurses or termcap) and
+       (history and/or readline) libraries and associated headers.  Added
+       check for strcasecmp().  Changed default gcc CFLAGS.
+
+       * prefh.orig: Removed `.' from GROFF_FONT_PATH.
+       (local_alloc, local_free) New functions.
+
+       * reconfigure: Added call to autoheader.
+
+       * Made patchlevel 123.
+       
+Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * There were some problems with the patchfiles so I had to merge
+       what was previously patchlevels 121 and 122; now everything from
+       what was previously 122 is called 121.  Oh well, just don't let it
+       happen often.
+
+       * This patchlevel does not compile.
+
+       * configure: No longer included in patches to save lotsa space
+       when configure.in changes.
+
+       * configure.in: Changed the technique for detecting libraries.
+
+       * prefh.orig: Style changes; handles changed configure.in.
+
+       * Made patchlevel 122 (second edition).
+
+Tue Jul 23 21:48:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 121.
+       
+Wed Jul 17 21:23:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 120.
+
+Tue Jul 16 22:10:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 119.
+
+Sun Jul 14 15:45:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 118.
+
+Fri Jul 12 22:03:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added list.c to sources.
+       
+       * Made patchlevel 117.
+       
+Sat Jul  6 22:22:25 1996  Ben Pfaff  <blp@gnu.org>
+
+       * configure.in: Removed reference to `malloc.h'.
+       
+       * Made patchlevel 116.
+       
+Fri Jul  5 20:16:19 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 115.
+
+Thu Jul  4 20:20:24 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prefh.orig: Changes to CONFIG_PATH, INCLUDE_PATH,
+       GROFF_FONT_PATH.
+
+       * Makefile.am: pkgdata_DATA file `output' changed to `devices'.
+       
+Thu Jul  4 00:35:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * TODO: doc fix.
+       
+       * Made patchlevel 114.
+       
+Tue Jul  2 22:13:23 1996  Ben Pfaff  <blp@gnu.org>
+
+       * reconfigure: (new file) Runs all the programs necessary to
+       create a Makefile that includes dependencies.
+
+       * Made patchlevel 113.
+       
+Mon Jul  1 22:13:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Made patchlevel 112.
+
+Mon Jul  1 13:00:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Most files: Changed references from `stat' (the original, rather
+       dull old name for this project) to `Fiasco' (the creative, rather
+       funny new name for this project).
+       
+       * Made patchlevel 111.
+       
+Sat Jun 29 17:40:47 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prefh.orig: changed default file search paths
+       
+       * Made patchlevel 110.
+
+Fri Jun 28 11:59:48 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Added automake support; removed GNUmakefile and GNUmakefile.in.
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
diff --git a/README b/README
index 07aae20ac94ee36dd7992d094043419af862dc19..02e81d77e9525093cc3252d38903717b6252b9eb 100644 (file)
--- a/README
+++ b/README
@@ -21,12 +21,6 @@ at http://savannah.gnu.org/projects/pspp
 
 The following miscellaneous notes apply to this release:
 
-       * If you use GCC 4.3 or later to compile PSPP, along with any
-         version of the GNU Scientific Library (GSL) released as of
-         this writing (June 2008), then you will need to specify the
-         -fgnu89-inline flag to the compiler on the "configure"
-         command line: "./configure CFLAGS=-fgnu89-inline".
-
        * On a few operating systems, such as OpenBSD, some of the
           tests may fail with messages similar to: 'Warning: cannot
           create a convertor for "646" to "UTF-8"'.  These test
diff --git a/Smake b/Smake
index aa05962fb63a502bbfaf5ebbc11bcd48fb1cf4b6..7905c430fe28401c4e5f454a0e4c3218d3a8f283 100644 (file)
--- a/Smake
+++ b/Smake
@@ -5,6 +5,7 @@ GNULIB = ../gnulib
 GNULIB_TOOL = $(GNULIB)/gnulib-tool
 
 GNULIB_MODULES = \
+       argp \
        assert \
        byteswap \
        c-ctype \
@@ -27,7 +28,10 @@ GNULIB_MODULES = \
        getopt \
        gettext-h \
        gettimeofday \
+       gitlog-to-changelog \
        isfinite \
+       isinf \
+       isnan \
        intprops \
        inttostr \
        localcharset \
@@ -43,6 +47,7 @@ GNULIB_MODULES = \
        printf-posix \
        printf-safe \
        progname \
+       regex \
        relocatable-prog \
        round \
        snprintf \
@@ -82,12 +87,13 @@ GNULIB_MODULES = \
        xvasprintf
 
 all: po/POTFILES.in
+       test -e ChangeLog || touch ChangeLog
        test -d m4 || mkdir m4
        echo '*' > m4/.cvsignore
        touch m4/Makefile.am
        $(GNULIB_TOOL) --import --no-changelog --m4-base=gl/m4 \
                --source-base=gl --lib=libgl --tests-base=tests \
-               --doc-base=gl/doc --import $(GNULIB_MODULES)
+               --doc-base=gl/doc --aux-dir=. --import $(GNULIB_MODULES)
        echo '*' > gl/.cvsignore
        echo '*' > gl/m4/.cvsignore
        libtoolize --force --automake
index cbf927aad0cf60cec556282c0f52b9c562ad81fc..75fcb0d023d5e547b559afa9e7c9bf6a82f85694 100644 (file)
@@ -5,9 +5,11 @@ dnl with or without modifications, as long as this notice is preserved.
 
 dnl Prerequisites.
 
-dnl Instead of giving an error about each prerequisite as we encounter it, 
-dnl group them all together at the end of the run, to be user-friendly.
-AC_DEFUN([PSPP_REQUIRED_PREREQ], [pspp_required_prereqs="$pspp_required_prereqs
+dnl Summarize all the missing prerequisites at the end of the run to
+dnl increase user-friendliness.
+AC_DEFUN([PSPP_REQUIRED_PREREQ], 
+  [AC_MSG_WARN([You must install $1 before building PSPP.])
+pspp_required_prereqs="$pspp_required_prereqs
        $1"])
 AC_DEFUN([PSPP_OPTIONAL_PREREQ], [pspp_optional_prereqs="$pspp_optional_prereqs
        $1"])
@@ -68,10 +70,10 @@ AC_DEFUN([PSPP_LIBPLOT],
   fi
 ])
 
-dnl Check whether a C compiler option is accepted.
-dnl If so, add it to CFLAGS.
-dnl Example: PSPP_ENABLE_OPTION(-Wdeclaration-after-statement)
-AC_DEFUN([PSPP_ENABLE_OPTION],
+dnl PSPP_CHECK_CC_OPTION([OPTION], [ACTION-IF-ACCEPTED], [ACTION-IF-REJECTED])
+dnl Check whether the given C compiler OPTION is accepted.
+dnl If so, execute ACTION-IF-ACCEPTED, otherwise ACTION-IF-REJECTED.
+AC_DEFUN([PSPP_CHECK_CC_OPTION],
 [
   m4_define([pspp_cv_name], [pspp_cv_[]m4_translit([$1], [-], [_])])dnl
   AC_CACHE_CHECK([whether $CC accepts $1], [pspp_cv_name], 
@@ -80,10 +82,19 @@ AC_DEFUN([PSPP_ENABLE_OPTION],
      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,)], [pspp_cv_name[]=yes], [pspp_cv_name[]=no])
      CFLAGS="$pspp_save_CFLAGS"])
   if test $pspp_cv_name = yes; then
-    CFLAGS="$CFLAGS $1"
+    m4_if([$2], [], [;], [$2])
+  else
+    m4_if([$3], [], [:], [$3])
   fi
 ])
 
+dnl PSPP_ENABLE_OPTION([OPTION])
+dnl Check whether the given C compiler OPTION is accepted.
+dnl If so, add it to CFLAGS.
+dnl Example: PSPP_ENABLE_OPTION([-Wdeclaration-after-statement])
+AC_DEFUN([PSPP_ENABLE_OPTION], 
+  [PSPP_CHECK_CC_OPTION([$1], [CFLAGS="$CFLAGS $1"])])
+
 dnl Check for readline and history libraries.
 
 dnl Modified for PSPP, based on readline.m4 serial 3 from
@@ -205,4 +216,70 @@ AC_DEFUN([PSPP_LC_PAPER],
   fi
 ])
 
+
+# PSPP_LINK2_IFELSE(SOURCE1, SOURCE2, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# -------------------------------------------------------------
+# Based on AC_LINK_IFELSE, but tries to link both SOURCE1 and SOURCE2
+# into a program.
+#
+# Test that resulting file is executable; see the problem reported by mwoehlke
+# in <http://lists.gnu.org/archive/html/bug-coreutils/2006-10/msg00048.html>.
+# But skip the test when cross-compiling, to prevent problems like the one
+# reported by Chris Johns in
+# <http://lists.gnu.org/archive/html/autoconf/2007-03/msg00085.html>.
+#
+m4_define([PSPP_LINK2_IFELSE],
+[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl
+mv conftest.$ac_ext conftest1.$ac_ext
+m4_ifvaln([$2], [AC_LANG_CONFTEST([$2])])dnl
+mv conftest.$ac_ext conftest2.$ac_ext
+rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext
+pspp_link2='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest1.$ac_ext conftest2.$ac_ext $LIBS >&5'
+AS_IF([_AC_DO_STDERR($pspp_link2) && {
+        test -z "$ac_[]_AC_LANG_ABBREV[]_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+        test "$cross_compiling" = yes ||
+        AS_TEST_X([conftest$ac_exeext])
+       }],
+      [$3],
+      [echo "$as_me: failed source file 1 of 2 was:" >&5
+sed 's/^/| /' conftest1.$ac_ext >&5
+echo "$as_me: failed source file 2 of 2 was:" >&5
+sed 's/^/| /' conftest2.$ac_ext >&5
+       $4])
+dnl Delete also the IPA/IPO (Inter Procedural Analysis/Optimization)
+dnl information created by the PGI compiler (conftest_ipa8_conftest.oo),
+dnl as it would interfere with the next link command.
+rm -rf conftest.dSYM conftest1.dSYM conftest2.dSYM
+rm -f core conftest.err conftest1.err conftest2.err
+rm -f conftest1.$ac_objext conftest2.$ac_objext conftest*_ipa8_conftest*.oo
+rm -f conftest$ac_exeext
+rm -f m4_ifval([$1], [conftest1.$ac_ext]) m4_ifval([$2], [conftest1.$ac_ext])[]dnl
+])# PSPP_LINK2_IFELSE
+
+# GSL uses "extern inline" without determining whether the compiler uses
+# GCC inline rules or C99 inline rules.  If it uses the latter then GSL
+# will be broken without passing -fgnu89-inline to GCC.
+AC_DEFUN([PSPP_GSL_NEEDS_FGNU89_INLINE],
+[# GSL only uses "inline" at all if HAVE_INLINE is defined as a macro.
+ # In turn, gnulib's gl_INLINE is one macro that does that.  We need to
+ # make sure that it has run by the time we run this test, otherwise we'll
+ # get a false result.
+ AC_REQUIRE([gl_INLINE])
+ PSPP_CHECK_CC_OPTION(
+   [-fgnu89-inline],
+   [AC_CACHE_CHECK([whether GSL needs -fgnu89-inline to link],
+                   pspp_cv_gsl_needs_fgnu89_inline, [
+                   PSPP_LINK2_IFELSE(
+                     [AC_LANG_PROGRAM([#include <gsl/gsl_math.h>
+                                      ], [GSL_MAX_INT(1,2);])],
+                     [AC_LANG_SOURCE([#include <gsl/gsl_math.h>
+                                      void x (void) {}])],
+                     [pspp_cv_gsl_needs_fgnu89_inline=no],
+                     [pspp_cv_gsl_needs_fgnu89_inline=yes])])
+     if test "$pspp_cv_gsl_needs_fgnu89_inline" = "yes"; then
+        CFLAGS="$CFLAGS -fgnu89-inline"
+     fi])
+])
 dnl acinclude.m4 ends here
diff --git a/config/ChangeLog b/config/ChangeLog
deleted file mode 100644 (file)
index dbf6c3a..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-2007-09-25  Ben Pfaff  <blp@gnu.org>
-
-       * devices (tty-ascii): Set length and width to "auto", so that
-       they reflect the current size of the terminal window as it
-       changes.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * papersize: Removed.
-
-       * automake.mk (dist_pkgsysconf_DATA): Remove papersize.
-
-2007-08-26  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Change raw-ascii from screen to listing device (because
-       that's how it's used).
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Add tty and listing devices that use VT100 (and xterm)
-       line-drawing characters.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Add an "interactive" category that defaults to
-       tty-ascii.  Make the tty-ascii device more user-friendly.
-
-Tue Apr  4 20:20:49 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Fix bugs in installation targets.
-
-Mon Apr  3 11:01:16 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: (pkgsysconf_DATA) Add AFM files in config/psfonts.
-       Remove config/html-prologue, config/ps-prologue.
-
-       * html-prologue: Removed.
-
-       * ps-prologue: Removed.
-
-       * psfonts/Courier-Bold.afm, psfonts/Courier-BoldOblique.afm,
-       psfonts/Courier-Oblique.afm, psfonts/Courier.afm,
-       psfonts/Helvetica-Bold.afm, psfonts/Helvetica-BoldOblique.afm,
-       psfonts/Helvetica-Oblique.afm, psfonts/Helvetica.afm,
-       psfonts/Times-Bold.afm, psfonts/Times-BoldItalic.afm,
-       psfonts/Times-Italic.afm, psfonts/Times-Roman.afm: New files.
-
-Sat Feb 11 21:58:29 2006  Ben Pfaff  <blp@gnu.org>
-
-       * html-prologue: Don't use ${source-file}, which is no longer
-       supported.
-
-Tue Dec 30 22:37:04 2003  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Add "squeeze=on top-margin=0 bottom-margin=0" to
-       raw-ascii to make test output more readable.
-
-Sun May 24 22:40:13 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: Add %%DocumentMedia: comment.
-
-Wed May 20 00:02:51 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: Comment out misleading Bounding-Box comment for
-       now.  SF arguments rearranged.  BP removed.
-
-Wed Apr 15 13:00:46 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (private-install) Make it work for separate source
-       and build directories.
-
-       * ps-prologue: New TL macro for a thick line.  New thick-width arg
-       to BP.
-
-Sun Jan  4 18:11:11 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: Minor reorganization.  New GB macro to draw a gray
-       box.
-
-Wed Dec 24 22:35:13 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Added devicetype options and documentation for them.
-
-Fri Dec  5 21:51:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pkgsysconf_DATA) Add html-prologue.
-       (EXTRA_DIST) Add html-prologue.
-
-       * devices: Add `html' device.  Add `listing', `screen', and
-       `printer' flags to devices as appropriate.
-
-       * html-prologue: New file.
-
-       * ps-prologue: Comment fixes.
-
-Thu Sep 18 21:31:02 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pkgsysconfdir) Changed from $(pkgdatadir) to
-       $(sysconfdir)/$(PACKAGE).
-
-Thu Aug 14 22:05:54 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices: (tty) Define as null instead of not defining.
-
-Sun Aug  3 11:33:28 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices: tty-ascii has no bold or italic by default.
-
-Wed Jun 25 22:50:19 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) New target.
-
-Mon May  5 21:56:54 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices, papersize, ps-prologue: Comment fixes.
-
-Fri May  2 22:05:44 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Removed ps-fontmap.
-
-       * ps-fontmap: Removed.
-
-       * ps-prologue: Added comments.  Fixed DSC comments.
-       (BP) Two new arguments; fixed problem with SF argument conflict
-       with SF function.
-
-Thu May  1 14:57:52 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: (BP) New argument, SF or scale factor.
-       
-Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: New file.
-       
-       * environment: Comment fix.
-
-Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Added ml520 and ml520-ul printer devices.
-
-Sat Jan 11 15:44:15 1997  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Default listing device is list-ascii, not list-ibmpc.
-
-Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Changed default devices.
-
-Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: Added `!encodings' line to cause encodings to be
-       output.
-       (T) Fixed.  Yes, really this time.
-
-Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ps-prologue: (T) Now works correctly.
-       (SF) Parameters changed to: size in psus, target font name,
-       encoding, PostScript font name.
-
-Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: Renamed ps-prologue, all references changed.
-       (T) New definition.
-
-       * ps-encodings: New PostScript configuration file (not present in
-       distribution).
-
-Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: One minor comment change.
-
-Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: Portions other than DSC comments are essentially
-       completely new.
-
-Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * devices: Added PostScript driver.
-
-Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: Calls `setlinecap' in setup code.
-
-Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: DSC comment changes.  New call to `setlinewidth' in
-       setup code.
-
-Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
-
-       * prologue.ps: Changes to scaling & translating code.
-
-Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * environment: New file.  Yet another new time- and memory-hogging
-       redundant config file; why not?
-       
-       * papersize: Comment changes.
-
-       * prologue.ps: Changed vars from $varname$ to ${varname} format.
-       Miscellaneous changes.
-
-       * ps-fontmap: Comment changes.  Fixed ZC family.
-
-Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ps-fontmap: New configuration file.  Added to Makefile.am.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/config/OChangeLog b/config/OChangeLog
new file mode 100644 (file)
index 0000000..dbf6c3a
--- /dev/null
@@ -0,0 +1,217 @@
+2007-09-25  Ben Pfaff  <blp@gnu.org>
+
+       * devices (tty-ascii): Set length and width to "auto", so that
+       they reflect the current size of the terminal window as it
+       changes.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * papersize: Removed.
+
+       * automake.mk (dist_pkgsysconf_DATA): Remove papersize.
+
+2007-08-26  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Change raw-ascii from screen to listing device (because
+       that's how it's used).
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Add tty and listing devices that use VT100 (and xterm)
+       line-drawing characters.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Add an "interactive" category that defaults to
+       tty-ascii.  Make the tty-ascii device more user-friendly.
+
+Tue Apr  4 20:20:49 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Fix bugs in installation targets.
+
+Mon Apr  3 11:01:16 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: (pkgsysconf_DATA) Add AFM files in config/psfonts.
+       Remove config/html-prologue, config/ps-prologue.
+
+       * html-prologue: Removed.
+
+       * ps-prologue: Removed.
+
+       * psfonts/Courier-Bold.afm, psfonts/Courier-BoldOblique.afm,
+       psfonts/Courier-Oblique.afm, psfonts/Courier.afm,
+       psfonts/Helvetica-Bold.afm, psfonts/Helvetica-BoldOblique.afm,
+       psfonts/Helvetica-Oblique.afm, psfonts/Helvetica.afm,
+       psfonts/Times-Bold.afm, psfonts/Times-BoldItalic.afm,
+       psfonts/Times-Italic.afm, psfonts/Times-Roman.afm: New files.
+
+Sat Feb 11 21:58:29 2006  Ben Pfaff  <blp@gnu.org>
+
+       * html-prologue: Don't use ${source-file}, which is no longer
+       supported.
+
+Tue Dec 30 22:37:04 2003  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Add "squeeze=on top-margin=0 bottom-margin=0" to
+       raw-ascii to make test output more readable.
+
+Sun May 24 22:40:13 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: Add %%DocumentMedia: comment.
+
+Wed May 20 00:02:51 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: Comment out misleading Bounding-Box comment for
+       now.  SF arguments rearranged.  BP removed.
+
+Wed Apr 15 13:00:46 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (private-install) Make it work for separate source
+       and build directories.
+
+       * ps-prologue: New TL macro for a thick line.  New thick-width arg
+       to BP.
+
+Sun Jan  4 18:11:11 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: Minor reorganization.  New GB macro to draw a gray
+       box.
+
+Wed Dec 24 22:35:13 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Added devicetype options and documentation for them.
+
+Fri Dec  5 21:51:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pkgsysconf_DATA) Add html-prologue.
+       (EXTRA_DIST) Add html-prologue.
+
+       * devices: Add `html' device.  Add `listing', `screen', and
+       `printer' flags to devices as appropriate.
+
+       * html-prologue: New file.
+
+       * ps-prologue: Comment fixes.
+
+Thu Sep 18 21:31:02 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pkgsysconfdir) Changed from $(pkgdatadir) to
+       $(sysconfdir)/$(PACKAGE).
+
+Thu Aug 14 22:05:54 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices: (tty) Define as null instead of not defining.
+
+Sun Aug  3 11:33:28 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices: tty-ascii has no bold or italic by default.
+
+Wed Jun 25 22:50:19 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) New target.
+
+Mon May  5 21:56:54 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices, papersize, ps-prologue: Comment fixes.
+
+Fri May  2 22:05:44 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Removed ps-fontmap.
+
+       * ps-fontmap: Removed.
+
+       * ps-prologue: Added comments.  Fixed DSC comments.
+       (BP) Two new arguments; fixed problem with SF argument conflict
+       with SF function.
+
+Thu May  1 14:57:52 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: (BP) New argument, SF or scale factor.
+       
+Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: New file.
+       
+       * environment: Comment fix.
+
+Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Added ml520 and ml520-ul printer devices.
+
+Sat Jan 11 15:44:15 1997  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Default listing device is list-ascii, not list-ibmpc.
+
+Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Changed default devices.
+
+Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: Added `!encodings' line to cause encodings to be
+       output.
+       (T) Fixed.  Yes, really this time.
+
+Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ps-prologue: (T) Now works correctly.
+       (SF) Parameters changed to: size in psus, target font name,
+       encoding, PostScript font name.
+
+Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: Renamed ps-prologue, all references changed.
+       (T) New definition.
+
+       * ps-encodings: New PostScript configuration file (not present in
+       distribution).
+
+Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: One minor comment change.
+
+Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: Portions other than DSC comments are essentially
+       completely new.
+
+Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * devices: Added PostScript driver.
+
+Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: Calls `setlinecap' in setup code.
+
+Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: DSC comment changes.  New call to `setlinewidth' in
+       setup code.
+
+Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
+
+       * prologue.ps: Changes to scaling & translating code.
+
+Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * environment: New file.  Yet another new time- and memory-hogging
+       redundant config file; why not?
+       
+       * papersize: Comment changes.
+
+       * prologue.ps: Changed vars from $varname$ to ${varname} format.
+       Miscellaneous changes.
+
+       * ps-fontmap: Comment changes.  Fixed ZC family.
+
+Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ps-fontmap: New configuration file.  Added to Makefile.am.
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index ba01a397f3809bde328cc03786a8010cf768b37b..88b63ac1b0bc59a9f449c18165a235b4cc186f01 100644 (file)
@@ -18,3 +18,5 @@ dist_psfonts_DATA = \
        config/psfonts/Helvetica.afm \
        config/psfonts/Times-Roman.afm \
        config/psfonts/Courier.afm
+
+EXTRA_DIST += config/OChangeLog
index a028fcbf5d8c09fc0611298a8329aeb0df85c13a..b00a75b14770f824c13737d9182307a347c02546 100644 (file)
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
 
 dnl Initialize.
 AC_PREREQ(2.60)
-AC_INIT([pspp],[0.6.0],[bug-gnu-pspp@gnu.org])
+AC_INIT([pspp],[0.7.0],[bug-gnu-pspp@gnu.org])
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE
 
@@ -121,14 +121,15 @@ AM_CONDITIONAL(GNM_SUPPORT, test x"$gnm_support" = x"yes")
 
 AC_ARG_WITH(
   gui_tools,
-  [AS_HELP_STRING([--with-gui-tools], [build the gui developer tools])])
+  [AS_HELP_STRING([--with-gui-tools], [build the gui developer tools.  For DEVELOPERS only! There is no reason why users will need this flag.])])
 if test x"$with_gui_tools" = x"yes" ; then 
        PKG_CHECK_MODULES(GLADE_UI, gladeui-1.0)
 fi
 AM_CONDITIONAL(WITH_GUI_TOOLS, test x"$with_gui_tools" = x"yes")
 
 AC_SEARCH_LIBS([cblas_dsdot], [gslcblas],,[PSPP_REQUIRED_PREREQ([libgslcblas])])
-AC_SEARCH_LIBS([gsl_cdf_chisq_Q], [gsl],,[PSPP_REQUIRED_PREREQ([libgsl (version 1.4 or later)])])
+AC_SEARCH_LIBS([gsl_cdf_binomial_P], [gsl],,[PSPP_REQUIRED_PREREQ([libgsl (version 1.8 or later)])])
+PSPP_GSL_NEEDS_FGNU89_INLINE
 
 dnl Recent versions of GNU ncurses install the curses header files into
 dnl /usr/include/ncurses, and provide a 'ncurses5-config' program which
diff --git a/doc/ChangeLog b/doc/ChangeLog
deleted file mode 100644 (file)
index f1270cf..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Make install-data-hook depend on yelp-check if the
-       GUI is configured.
-
-2008-05-08 John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk: Compress the info files, because later
-       versions of yelp seem to crash otherwise.
-
-2008-03-11  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.texi (REGRESSION): Fixed use of @dots in @math
-       command. Reported by John Darrington.
-
-2008-03-11  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.texi: Made more consistent use of math mode for
-       description of linear regression. Added reference to the mean of
-       the error terms being 0.
-
-2008-03-09  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.texi (REGRESSION): Removed references to subcommand EXPORT.
-
-2008-02-06 John Darrington <john@darrington.wattle.id.au>
-
-       * files.texi: Document the /BSIZE subcommand to the PSQL
-       reader.
-
-2008-02-04 John Darrington <john@darrington.wattle.id.au>
-
-       * files.texi data-io.texi: Document the GET DATA TYPE=PSQL
-       option.  Thanks to Ben Pfaff for reviewing this text.
-
-
-2007-11-10  Ben Pfaff  <blp@gnu.org>
-
-       * not-implemented.texi: Fix @include command so that it works
-       consistently, by using a file name relative to Makefile.am's
-       srcdir instead of relative to doc.
-
-2007-11-10  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6262: New developers guide (currently incomplete).
-
-       * automake.mk: Add definitions for new manual.
-
-       * pspp.texinfo: Now this is the PSPP Users Guide instead of just
-       the PSPP manual.  Remove development chapters.
-
-       * pspp-dev.texinfo: New file.
-
-       * data-file-format.texi: Move to dev/system-file-format.texi.
-
-       * portable-file-format.texi: Move to dev/.
-
-       * q2c.texi: Move to dev/
-
-       * dev/concepts.texi: New file.
-
-       * dev/data.texi: New file.
-
-       * dev/intro.texi: New file.
-
-       * dev/output.texi: New file.
-
-       * dev/syntax.texi: New file.
-
-2007-10-19 John Darrington <john@darrington.wattle.id.au>
-
-       * statistics.texi: Changed /CONTRASTS to /CONTRAST in ONEWAY which
-       is what the command accepts. 
-       
-
-2007-07-28 John Darrington <john@darrington.wattle.id.au>
-
-       * statistics.texi: Made the documentation for T-TEST match 
-       the behaviour.
-
-2007-07-17  Ben Pfaff  <blp@gnu.org>
-
-       * get-commands.pl: Use strict and all warnings.  Simplify
-       parsing.  Add "@c End:" line to output to suppress Emacs warning.
-       From bug #19335.  Reviewed by John Darrington.
-
-2007-06-05  Ben Pfaff  <blp@gnu.org>
-
-       * Removed next, prev, up node names from @node lines, to make
-         structural changes to the manual easier.  (These node names are
-         not needed by makeinfo.)
-
-2007-03-31 John Darrington <john@darrington.wattle.id.au>
-       
-       * transformation.texi: SORT CASES: elaborated on the (D) (A) flags.
-       
-2007-03-01  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Fix "make distcheck" by distributing doc/ni.texi,
-       even though it's generated.  Reviewed by John Darrington.
-       (doc_pspp_TEXINFOS): Add doc/ni.texi.
-       (nodist_doc_pspp_TEXINFOS): Remove.
-       (am__TEXINFO_TEX_DIR) Removed (was just a kluge anyhow).
-       ($(INFO_DEPS)): Removed.
-       ($(HTML_DEPS)): Removed.
-       (CLEANFILES): Removed.
-       
-Wed Dec 20 18:45:31 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * statistics.texi: Added documentation for the NPAR TESTS command.
-
-Thu Nov 30 22:20:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       * statistics.texi: Document charts supported by FREQUENCIES.
-       Fixes bug #18297.  Thanks to Mohammed Babekir Elmalik Abdalmajid
-       for reporting this bug.
-
-Tue Nov 28 17:33:31 WST 2006 <john@darrington.wattle.id.au>
-
-       * get-commands.pl: Fixed generation of ni.texi, which was broken
-       after commands.def was reorganised.
-
-       * not-implemented.texi language.texi regression.texi 
-          statistics.texi: Added some indeces.
-
-       * license.texi: Added information from GPL.
-
-Sat Oct  7 11:02:44 WST 2006 <john@darrington.wattle.id.au>
-
-       * Added documentation for RANK.
-
-Tue May  2 10:43:06 WST 2006 <john@darrington.wattle.id.au>
-
-       * data-file-format.texi: Updated information about the case_size 
-       value.  Added description of Record Type 7, subtype 14.
-
-2006-04-28  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.texi: Added description of the RESID and PRED
-       keywords to the SAVE subcommand.
-
-       * statistics.texi: Added REGRESSION node.
-
-2006-04-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.texi: Initial description of the SAVE subcommand.
-
-Sun Apr 16 19:12:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Consistently write "file name" as two words, in accordance with
-       the GNU standards.
-
-Wed Feb 15 21:53:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-file-format.texi: Fix values for "measure" in Auxiliary
-       Variable Parameter Record.  Thanks to Oliver Bock <oliver@g7.org>
-       for reporting this bug.  Fixes bug #15763.
-
-Tue Feb 14 21:34:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-file-format.texi: Fix description of "count" in Auxiliary
-       Variable Parameter Record.  Thanks to Oliver Bock <oliver@g7.org>
-       for reporting this bug.  Fixes bug #15756. 
-
-Sun Sep 25 16:10:36 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Make ni.texi a prereq for HTML output.  Thanks to
-       James R. Van Zandt <jrvz@comcast.net> for reporting the problem.
-
-Sun Jul 24 18:47:02 2005  Ben Pfaff  <blp@gnu.org>
-
-       * portable-file-format.texi: Describe author field.
-
-Sat May  7 17:26:39 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * Makefile.am: Made ni.texi a nodist file
-
-Wed May  4 08:30:24 2005  Ben Pfaff  <blp@gnu.org>
-
-       * language.texi: Proofreading from Jason Stover
-       <jstover@sdf.lonestar.org>.
-
-Tue May  3 16:22:29 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * get-commands.pl: New file to generate ni.texi
-
-       * not-implemented.texi Makefile.am: List of not implemented commands 
-       now generated from src/command.def
-
-Sun May  1 23:20:42 2005  Ben Pfaff  <blp@gnu.org>
-
-       * language.texi: Revised lots of text to catch up with changes
-       that have been in for a long time, and for style.
-
-Sun May  1 15:17:42 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * configuration.texi: Removed manpage(x) style references, because 
-       RMS doesn't like them.
-
-Wed Apr 27 07:44:57 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * utilities.texi: Added the ECHO command.
-
-Fri Apr 15 18:35:42 2005  Ben Pfaff  <blp@gnu.org>
-
-       * pspp.texinfo: Change manual license to GNU FDL, pursuant to
-       advice in maintainers' guide.
-
-Thur Apr 14 2005 John Darrington
-
-       * variables.texi: Corrected the entry for VARIABLE LABELS
-
-       * data-file-format.texi: Added documentation about the Long Variable 
-         Names record.
-       
-Thu Mar  3 22:06:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * expressions.texi:  corrected some mismatched parentheses.
-
-Mon Feb 28 23:19:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions.texi: Revise.  Describe new functions.
-
-Sat Jan  8 16:46:28 2005  Ben Pfaff  <blp@gnu.org>
-
-       * credits.texi: Removed.
-
-       * bugs.texi: Rewrote.  Moved known bugs to savannah website.
-
-       * not-implemented.texi: AGGREGATE and AUTORECODE are implemented.
-
-Tue Nov 16 13:18:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
-       
-       * statistics.texi Added documentation about the EXAMINE cmd
-
-Tue Nov 16 13:18:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * utilities.texi Added documentation for the PERMISSIONS command.
-
-       * pspp.texinfo Makefile.am  @included version.texi (Autogenerated) to 
-       keep the EDITION, VERSION and UPDATED flags up to date.
-
-Tue Nov  9 09:38:43 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * Made Makefile.am aware of pspp.texi dependencies
-
-Fri Nov  5 17:46:46 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * Added a note to the about SPLIT requiring adjacent cases.
-
-Sat Oct 30 17:32:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * Started this changelog
-
-       * Removed the monolithic pspp.texi file and replaced with  *.texi
-       wrapped by a single pspp.texinfo file
-
-       * Minor corrections to the documentation where I noticed it needed
-       them.
diff --git a/doc/OChangeLog b/doc/OChangeLog
new file mode 100644 (file)
index 0000000..f1270cf
--- /dev/null
@@ -0,0 +1,259 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Make install-data-hook depend on yelp-check if the
+       GUI is configured.
+
+2008-05-08 John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk: Compress the info files, because later
+       versions of yelp seem to crash otherwise.
+
+2008-03-11  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.texi (REGRESSION): Fixed use of @dots in @math
+       command. Reported by John Darrington.
+
+2008-03-11  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.texi: Made more consistent use of math mode for
+       description of linear regression. Added reference to the mean of
+       the error terms being 0.
+
+2008-03-09  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.texi (REGRESSION): Removed references to subcommand EXPORT.
+
+2008-02-06 John Darrington <john@darrington.wattle.id.au>
+
+       * files.texi: Document the /BSIZE subcommand to the PSQL
+       reader.
+
+2008-02-04 John Darrington <john@darrington.wattle.id.au>
+
+       * files.texi data-io.texi: Document the GET DATA TYPE=PSQL
+       option.  Thanks to Ben Pfaff for reviewing this text.
+
+
+2007-11-10  Ben Pfaff  <blp@gnu.org>
+
+       * not-implemented.texi: Fix @include command so that it works
+       consistently, by using a file name relative to Makefile.am's
+       srcdir instead of relative to doc.
+
+2007-11-10  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6262: New developers guide (currently incomplete).
+
+       * automake.mk: Add definitions for new manual.
+
+       * pspp.texinfo: Now this is the PSPP Users Guide instead of just
+       the PSPP manual.  Remove development chapters.
+
+       * pspp-dev.texinfo: New file.
+
+       * data-file-format.texi: Move to dev/system-file-format.texi.
+
+       * portable-file-format.texi: Move to dev/.
+
+       * q2c.texi: Move to dev/
+
+       * dev/concepts.texi: New file.
+
+       * dev/data.texi: New file.
+
+       * dev/intro.texi: New file.
+
+       * dev/output.texi: New file.
+
+       * dev/syntax.texi: New file.
+
+2007-10-19 John Darrington <john@darrington.wattle.id.au>
+
+       * statistics.texi: Changed /CONTRASTS to /CONTRAST in ONEWAY which
+       is what the command accepts. 
+       
+
+2007-07-28 John Darrington <john@darrington.wattle.id.au>
+
+       * statistics.texi: Made the documentation for T-TEST match 
+       the behaviour.
+
+2007-07-17  Ben Pfaff  <blp@gnu.org>
+
+       * get-commands.pl: Use strict and all warnings.  Simplify
+       parsing.  Add "@c End:" line to output to suppress Emacs warning.
+       From bug #19335.  Reviewed by John Darrington.
+
+2007-06-05  Ben Pfaff  <blp@gnu.org>
+
+       * Removed next, prev, up node names from @node lines, to make
+         structural changes to the manual easier.  (These node names are
+         not needed by makeinfo.)
+
+2007-03-31 John Darrington <john@darrington.wattle.id.au>
+       
+       * transformation.texi: SORT CASES: elaborated on the (D) (A) flags.
+       
+2007-03-01  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Fix "make distcheck" by distributing doc/ni.texi,
+       even though it's generated.  Reviewed by John Darrington.
+       (doc_pspp_TEXINFOS): Add doc/ni.texi.
+       (nodist_doc_pspp_TEXINFOS): Remove.
+       (am__TEXINFO_TEX_DIR) Removed (was just a kluge anyhow).
+       ($(INFO_DEPS)): Removed.
+       ($(HTML_DEPS)): Removed.
+       (CLEANFILES): Removed.
+       
+Wed Dec 20 18:45:31 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * statistics.texi: Added documentation for the NPAR TESTS command.
+
+Thu Nov 30 22:20:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       * statistics.texi: Document charts supported by FREQUENCIES.
+       Fixes bug #18297.  Thanks to Mohammed Babekir Elmalik Abdalmajid
+       for reporting this bug.
+
+Tue Nov 28 17:33:31 WST 2006 <john@darrington.wattle.id.au>
+
+       * get-commands.pl: Fixed generation of ni.texi, which was broken
+       after commands.def was reorganised.
+
+       * not-implemented.texi language.texi regression.texi 
+          statistics.texi: Added some indeces.
+
+       * license.texi: Added information from GPL.
+
+Sat Oct  7 11:02:44 WST 2006 <john@darrington.wattle.id.au>
+
+       * Added documentation for RANK.
+
+Tue May  2 10:43:06 WST 2006 <john@darrington.wattle.id.au>
+
+       * data-file-format.texi: Updated information about the case_size 
+       value.  Added description of Record Type 7, subtype 14.
+
+2006-04-28  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.texi: Added description of the RESID and PRED
+       keywords to the SAVE subcommand.
+
+       * statistics.texi: Added REGRESSION node.
+
+2006-04-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.texi: Initial description of the SAVE subcommand.
+
+Sun Apr 16 19:12:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Consistently write "file name" as two words, in accordance with
+       the GNU standards.
+
+Wed Feb 15 21:53:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-file-format.texi: Fix values for "measure" in Auxiliary
+       Variable Parameter Record.  Thanks to Oliver Bock <oliver@g7.org>
+       for reporting this bug.  Fixes bug #15763.
+
+Tue Feb 14 21:34:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-file-format.texi: Fix description of "count" in Auxiliary
+       Variable Parameter Record.  Thanks to Oliver Bock <oliver@g7.org>
+       for reporting this bug.  Fixes bug #15756. 
+
+Sun Sep 25 16:10:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Make ni.texi a prereq for HTML output.  Thanks to
+       James R. Van Zandt <jrvz@comcast.net> for reporting the problem.
+
+Sun Jul 24 18:47:02 2005  Ben Pfaff  <blp@gnu.org>
+
+       * portable-file-format.texi: Describe author field.
+
+Sat May  7 17:26:39 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * Makefile.am: Made ni.texi a nodist file
+
+Wed May  4 08:30:24 2005  Ben Pfaff  <blp@gnu.org>
+
+       * language.texi: Proofreading from Jason Stover
+       <jstover@sdf.lonestar.org>.
+
+Tue May  3 16:22:29 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * get-commands.pl: New file to generate ni.texi
+
+       * not-implemented.texi Makefile.am: List of not implemented commands 
+       now generated from src/command.def
+
+Sun May  1 23:20:42 2005  Ben Pfaff  <blp@gnu.org>
+
+       * language.texi: Revised lots of text to catch up with changes
+       that have been in for a long time, and for style.
+
+Sun May  1 15:17:42 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * configuration.texi: Removed manpage(x) style references, because 
+       RMS doesn't like them.
+
+Wed Apr 27 07:44:57 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * utilities.texi: Added the ECHO command.
+
+Fri Apr 15 18:35:42 2005  Ben Pfaff  <blp@gnu.org>
+
+       * pspp.texinfo: Change manual license to GNU FDL, pursuant to
+       advice in maintainers' guide.
+
+Thur Apr 14 2005 John Darrington
+
+       * variables.texi: Corrected the entry for VARIABLE LABELS
+
+       * data-file-format.texi: Added documentation about the Long Variable 
+         Names record.
+       
+Thu Mar  3 22:06:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * expressions.texi:  corrected some mismatched parentheses.
+
+Mon Feb 28 23:19:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions.texi: Revise.  Describe new functions.
+
+Sat Jan  8 16:46:28 2005  Ben Pfaff  <blp@gnu.org>
+
+       * credits.texi: Removed.
+
+       * bugs.texi: Rewrote.  Moved known bugs to savannah website.
+
+       * not-implemented.texi: AGGREGATE and AUTORECODE are implemented.
+
+Tue Nov 16 13:18:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
+       
+       * statistics.texi Added documentation about the EXAMINE cmd
+
+Tue Nov 16 13:18:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * utilities.texi Added documentation for the PERMISSIONS command.
+
+       * pspp.texinfo Makefile.am  @included version.texi (Autogenerated) to 
+       keep the EDITION, VERSION and UPDATED flags up to date.
+
+Tue Nov  9 09:38:43 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * Made Makefile.am aware of pspp.texi dependencies
+
+Fri Nov  5 17:46:46 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * Added a note to the about SPLIT requiring adjacent cases.
+
+Sat Oct 30 17:32:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * Started this changelog
+
+       * Removed the monolithic pspp.texi file and replaced with  *.texi
+       wrapped by a single pspp.texinfo file
+
+       * Minor corrections to the documentation where I noticed it needed
+       them.
index 0ebd8fc56dbf8db410895939e1d398a7a5183df2..3445379a1ca756e00e62751623ab4759cdf12dc0 100644 (file)
@@ -60,3 +60,6 @@ install-data-hook:: $(YELP_CHECK)
 uninstall-hook::
        rm -f $(DESTDIR)$(infodir)/pspp.info-[0-9].gz
        rm -f $(DESTDIR)$(infodir)/pspp.info.gz
+
+EXTRA_DIST += doc/OChangeLog
+CLEANFILES += pspp-dev.dvi
index b6a3a6d2a4a5754f7962ca8ceb21bbd45cbc7a0f..335d6c46030060d8d4ed8cd04a4dfc02ec17366a 100644 (file)
@@ -25,6 +25,7 @@ actually be read until a procedure is executed.
 @menu
 * BEGIN DATA::                  Embed data within a syntax file.
 * CLOSE FILE HANDLE::           Close a file handle.
+* DATAFILE ATTRIBUTE::          Set custom attributes on data files.
 * DATA LIST::                   Fundamental data reading command.
 * END CASE::                    Output the current case.
 * END FILE::                    Terminate the current input program.
@@ -89,6 +90,52 @@ DATA} and @cmd{END DATA}, cannot be closed.  Attempts to close it with
 
 @cmd{CLOSE FILE HANDLE} is a PSPP extension.
 
+@node DATAFILE ATTRIBUTE
+@section DATAFILE ATTRIBUTE
+@vindex DATAFILE ATTRIBUTE
+
+@display
+DATAFILE ATTRIBUTE
+         ATTRIBUTE=name('value') [name('value')]@dots{}
+         ATTRIBUTE=name@b{[}index@b{]}('value') [name@b{[}index@b{]}('value')]@dots{}
+         DELETE=name [name]@dots{}
+         DELETE=name@b{[}index@b{]} [name@b{[}index@b{]}]@dots{}
+@end display
+
+@cmd{DATAFILE ATTRIBUTE} adds, modifies, or removes user-defined
+attributes associated with the active file.  Custom data file
+attributes are not interpreted by PSPP, but they are saved as part of
+system files and may be used by other software that reads them.
+
+Use the ATTRIBUTE subcommand to add or modify a custom data file
+attribute.  Specify the name of the attribute as an identifier
+(@pxref{Tokens}), followed by the desired value, in parentheses, as a
+quoted string.  Attribute names that begin with @code{$} are reserved
+for PSPP's internal use, and attribute names that begin with @code{@@}
+or @code{$@@} are not displayed by most PSPP commands that display
+other attributes.  Other attribute names are not treated specially.
+
+Attributes may also be organized into arrays.  To assign to an array
+element, add an integer array index enclosed in square brackets
+(@code{[} and @code{]}) between the attribute name and value.  Array
+indexes start at 1, not 0.  An attribute array that has a single
+element (number 1) is not distinguished from a non-array attribute.
+
+Use the DELETE subcommand to delete an attribute.  Specify an
+attribute name by itself to delete an entire attribute, including all
+array elements for attribute arrays.  Specify an attribute name
+followed by an array index in square brackets to delete a single
+element of an attribute array.  In the latter case, all the array
+elements numbered higher than the deleted element are shifted down,
+filling the vacated position.
+
+To associate custom attributes with particular variables, instead of
+with the entire active file, use @cmd{VARIABLE ATTRIBUTE} instead.
+
+@cmd{DATAFILE ATTRIBUTE} takes effect immediately.  It is not affected
+by conditional and looping structures such as @cmd{DO IF} or
+@cmd{LOOP}.
+
 @node DATA LIST
 @section DATA LIST
 @vindex DATA LIST
index 70fa385c7525efea051a5bfb90fbf046bdb7e14b..3e764c8ce714099f1becf877c927681911b23a54 100644 (file)
@@ -96,6 +96,7 @@ Each type of record is described separately below.
 * Variable Display Parameter Record::
 * Long Variable Names Record::
 * Very Long String Record::
+* Data File and Variable Attributes Records::
 * Miscellaneous Informational Records::
 * Dictionary Termination Record::
 * Data Record::
@@ -791,6 +792,85 @@ After the last tuple, there may be a single byte 00, or @{00, 09@}.
 The total length is @code{count} bytes.
 @end table
 
+@node Data File and Variable Attributes Records
+@section Data File and Variable Attributes Records
+
+The data file and variable attributes records represent custom
+attributes for the system file or for individual variables in the
+system file, as defined on the DATAFILE ATTRIBUTE (@pxref{DATAFILE
+ATTRIBUTE,,,pspp, PSPP Users Guide}) and VARIABLE ATTRIBUTE commands
+(@pxref{VARIABLE ATTRIBUTE,,,pspp, PSPP Users Guide}), respectively.
+
+@example
+/* @r{Header.} */
+int32               rec_type;
+int32               subtype;
+int32               size;
+int32               count;
+
+/* @r{Exactly @code{count} bytes of data.} */
+char                attributes[];
+@end example
+
+@table @code
+@item int32 rec_type;
+Record type.  Always set to 7.
+
+@item int32 subtype;
+Record subtype.  Always set to 17 for a data file attribute record or
+to 18 for a variable attributes record.
+
+@item int32 size;
+The size of each element in the @code{attributes} member. Always set to 1.
+
+@item int32 count;
+The total number of bytes in @code{attributes}.
+
+@item char attributes[];
+The attributes, in a text-based format.
+
+In record type 17, this field contains a single attribute set.  An
+attribute set is a sequence of one or more attributes concatenated
+together.  Each attribute consists of a name, which has the same
+syntax as a variable name, followed by, inside parentheses, a sequence
+of one or more values.  Each value consists of a string enclosed in
+single quotes (@code{'}) followed by a line feed (byte 0x0a).  A value
+may contain single quote characters, which are not themselves escaped
+or quoted or required to be present in pairs.  There is no apparent
+way to embed a line feed in a value.  There is no distinction between
+an attribute with a single value and an attribute array with one
+element.
+
+In record type 18, this field contains a sequence of one or more
+variable attribute sets.  If more than one variable attribute set is
+present, each one after the first is delimited from the previous by
+@code{/}.  Each variable attribute set consists of a variable name,
+followed by @code{:}, followed by an attribute set with the same
+syntax as on record type 17.
+
+The total length is @code{count} bytes.
+@end table
+
+@subheading Example
+
+A system file produced with the following VARIABLE ATTRIBUTE commands
+in effect:
+
+@example
+VARIABLE ATTRIBUTE VARIABLES=dummy ATTRIBUTE=fred[1]('23') fred[2]('34').
+VARIABLE ATTRIBUTE VARIABLES=dummy ATTRIBUTE=bert('123').
+@end example
+
+@noindent
+will contain a variable attribute record with the following contents:
+
+@example
+00000000  07 00 00 00 12 00 00 00  01 00 00 00 22 00 00 00  |............"...|
+00000010  64 75 6d 6d 79 3a 66 72  65 64 28 27 32 33 27 0a  |dummy:fred('23'.|
+00000020  27 33 34 27 0a 29 62 65  72 74 28 27 31 32 33 27  |'34'.)bert('123'|
+00000030  0a 29                                             |.)              |
+@end example
+
 @node Miscellaneous Informational Records
 @section Miscellaneous Informational Records
 
index 30a023aeb90d3a22793169e4a4cce20edaaed77a..ae10ec7aa1dbbc49383e9914320cb3bc2ba37f24 100644 (file)
@@ -39,25 +39,46 @@ Only variables with names that exist in both the active file and the
 system file are considered.  Variables with the same name but different
 types (numeric, string) will cause an error message.  Otherwise, the
 system file variables' attributes will replace those in their matching
-active file variables, as described below.
+active file variables:
 
+@itemize @bullet
+@item
 If a system file variable has a variable label, then it will replace the
 active file variable's variable label.  If the system file variable does
 not have a variable label, then the active file variable's variable
-label, if any, will be retained.
+label, if any, will be retained.  
+
+@item
+If the system file variable has custom attributes (@pxref{VARIABLE
+ATTRIBUTE}), then those attributes replace the active file variable's
+custom attributes.  If the system file variable does not have custom
+attributes, then the active file variable's custom attributes, if any,
+will be retained.
 
+@item
 If the active file variable is numeric or short string, then value
 labels and missing values, if any, will be copied to the active file
 variable.  If the system file variable does not have value labels or
 missing values, then those in the active file variable, if any, will not
 be disturbed.
+@end itemize
 
-Finally, weighting of the active file is updated (@pxref{WEIGHT}).  If
-the active file has a weighting variable, and the system file does not,
-or if the weighting variable in the system file does not exist in the
-active file, then the active file weighting variable, if any, is
-retained.  Otherwise, the weighting variable in the system file becomes
-the active file weighting variable.
+In addition to properties of variables, some properties of the active
+file dictionary as a whole are updated:
+
+@itemize @bullet
+@item
+If the system file has custom attributes (@pxref{DATAFILE ATTRIBUTE}),
+then those attributes replace the active file variable's custom
+attributes.
+
+@item
+If the active file has a weighting variable (@pxref{WEIGHT}), and the
+system file does not, or if the weighting variable in the system file
+does not exist in the active file, then the active file weighting
+variable, if any, is retained.  Otherwise, the weighting variable in
+the system file becomes the active file weighting variable.
+@end itemize
 
 @cmd{APPLY DICTIONARY} takes effect immediately.  It does not read the
 active
index b5f157e6656e4c96af00bda27437ef1a95e70b5a..d761935861c545f11d2fd9228d27d18fa2548b5b 100644 (file)
@@ -7,12 +7,12 @@
 @cindex options, command-line
 @example
 pspp [ -B @var{dir} | --config-dir=@var{dir} ] [ -o @var{device} | --device=@var{device} ]
-       [ -d @var{var}[=@var{value}] | --define=@var{var}[=@var{value}] ] [-u @var{var} | --undef=@var{var} ]
-       [ -f @var{file} | --out-file=@var{file} ] [ -p | --pipe ] [ -I- | --no-include ]
+       [ -a @{compatible|enhanced@} | --algorithm=@{compatible|enhanced@}]
+       [ -x @{compatible|enhanced@} | --syntax=@{compatible|enhanced@}]
+       [ -I- | --no-include ]
        [ -I @var{dir} | --include=@var{dir} ] [ -i | --interactive ] 
-       [ -n | --edit | --dry-run | --just-print | --recon ] 
        [ -r | --no-statrc ] [ -h | --help ] [ -l | --list ] 
-       [ -c @var{command} | --command @var{command} ] [ -s | --safer ]
+       [ -s | --safer ]
        [ --testing-mode ] [ -V | --version ] [ -v | --verbose ] 
        [ @var{key}=@var{value} ] @var{file}@enddots{}
 @end example
@@ -101,19 +101,6 @@ Input and output options affect how PSPP reads input and writes
 output.  These are the input and output options:
 
 @table @code
-@item -f @var{file}
-@itemx --out-file=@var{file}
-
-This overrides the output file name for devices designated as listing
-devices.  If a file named @var{file} already exists, it is overwritten.
-
-@item -p
-@itemx --pipe
-
-Allows PSPP to be used as a filter by causing the syntax file to be
-read from stdin and output to be written to stdout.  Conflicts with the
-@code{-f @var{file}} and @code{--file=@var{file}} options.
-
 @item -I-
 @itemx --no-include
 
@@ -127,12 +114,6 @@ configuring}.
 Appends directory @var{dir} to the path that is searched for include
 files in PSPP syntax files.
 
-@item -c @var{command}
-@itemx --command=@var{command}
-
-Execute literal command @var{command}.  The command is executed before
-startup syntax files, if any.
-
 @item --testing-mode
 
 Invoke heuristics to assist with testing PSPP.  For use by @code{make
@@ -158,16 +139,6 @@ mode, rather than the default batch mode.  @xref{Tokenizing lines}, for
 information on the differences between batch mode and interactive mode
 command interpretation.
 
-@item -n
-@itemx --edit
-@itemx --dry-run
-@itemx --just-print
-@itemx --recon
-
-Only the syntax of any syntax file specified or of commands entered at
-the command line is checked.  Transformations are not performed and
-procedures are not executed.  Not yet implemented.
-
 @item -r
 @itemx --no-statrc
 
index 1345433613d3f24e7c7b26cdac457f7132761834..ed1123dbb68ea9a433a5394767655497f843749e 100644 (file)
@@ -497,6 +497,11 @@ they are displayed.  Example: a width of 8, with 2 decimal places.
 @item Write format
 Similar to print format, but used by the @cmd{WRITE} command
 (@pxref{WRITE}).
+
+@cindex custom attributes
+@item Custom attributes
+User-defined associations between names and values.  @xref{VARIABLE
+ATTRIBUTE}.
 @end table
 
 @node System Variables
index 28398fb75e4a5c8abf82085a557715b6049bd796..89e5e83c56862dcf4dce5804d073ed7ae2652907 100644 (file)
@@ -14,6 +14,7 @@ far.
 * ONEWAY::                      One way analysis of variance.
 * RANK::                        Compute rank scores.
 * REGRESSION::                  Linear regression.
+* RELIABILITY::                 Reliability analysis.
 @end menu
 
 @node DESCRIPTIVES
@@ -232,7 +233,7 @@ EXAMINE
         /PLOT=@{BOXPLOT, NPPLOT, HISTOGRAM, ALL, NONE@}
         /CINTERVAL n
         /COMPARE=@{GROUPS,VARIABLES@}
-        /ID=@{case_number, var_name@}
+        /ID=var_name
         /@{TOTAL,NOTOTAL@}
         /PERCENTILE=[value_list]=@{HAVERAGE, WAVERAGE, ROUND, AEMPIRICAL, EMPIRICAL @}
         /MISSING=@{LISTWISE, PAIRWISE@} [@{EXCLUDE, INCLUDE@}] 
@@ -271,6 +272,12 @@ If /COMPARE=VARIABLES is specified, then one plot per factor is produced, each
 each containing one boxplot per dependent variable.
 If the /COMPARE subcommand is ommitted, then PSPP uses the default value of 
 /COMPARE=GROUPS.
+The ID subcommand also pertains to boxplots.  If given, it must
+specify a variable name.   Outliers and extreme cases plotted in
+boxplots will be labelled with the case from that variable.  Numeric or
+string variables are permissible.  If the ID subcommand is not given,
+then the casenumber will be used for labelling.
 
 The CINTERVAL subcommand specifies the confidence interval to use in
 calculation of the descriptives command.  The default it 95%.
@@ -499,6 +506,8 @@ NPAR TESTS
      [ /STATISTICS=@{DESCRIPTIVES@} ]
 
      [ /MISSING=@{ANALYSIS, LISTWISE@} @{INCLUDE, EXCLUDE@} ]
+
+     [ /METHOD=EXACT [ TIMER [(n)] ] ]
 @end display
 
 NPAR TESTS performs nonparametric tests. 
@@ -508,10 +517,21 @@ One or more tests may be specified by using the corresponding subcommand.
 If the /STATISTICS subcommand is also specified, then summary statistics are 
 produces for each variable that is the subject of any test.
 
+Certain tests may take a long time to execute, if an exact figure is required.
+Therefore, by default asymptotic approximations are used unless the
+subcommand /METHOD=EXACT is specified.  
+Exact tests give more accurate results, but may take an unacceptably long 
+time to perform.  If the TIMER keyword is used, it sets a maximum time,
+after which the test will be abandoned, and a warning message printed.
+The time, in minutes, should be specified in parentheses after the TIMER keyword.
+If the TIMER keyword is given without this figure, then a default value of 5 minutes 
+is used.
+
 
 @menu
 * BINOMIAL::                Binomial Test
 * CHISQUARE::               Chisquare Test
+* WILCOXON::                Wilcoxon Signed Ranks Test
 @end menu
 
 
@@ -591,6 +611,34 @@ sum of the frequencies need not be 1.
 If no /EXPECTED subcommand is given, then then equal frequencies 
 are expected.
 
+@node WILCOXON
+@subsection Wilcoxon
+@comment  node-name,  next,  previous,  up
+@vindex WILCOXON
+@cindex wilcoxon matched pairs signed ranks test
+
+@display
+     [ /WILCOXON varlist [ WITH varlist [ (PAIRED) ]]]
+@end display
+
+The wilcoxon subcommand tests for differences between means of the 
+variables listed.  The test does not make any assumptions about the
+variances of the samples.
+
+If the @code{WITH} keyword is omitted, then tests for all
+combinations of the listed variables are performed.
+If the @code{WITH} keyword is given, and the @code{(PAIRED)} keyword
+is also given, then the number of variables preceding @code{WITH}
+must be the same as the number following it.
+In this case, tests for each respective pair of variables are
+performed.
+If the @code{WITH} keyword is given, but the
+@code{(PAIRED)} keyword is omitted, then tests for each combination
+of variable preceding @code{WITH} against variable following
+@code{WITH} are performed.
+
+If the number of observations is large, and exact tests have been
+requested. then the test may take a very long time to complete.
 
 @node T-TEST
 @comment  node-name,  next,  previous,  up
@@ -831,3 +879,50 @@ user-missing are to be excluded from the rank scores. A setting of
 INCLUDE means they are to be included.  The default is EXCLUDE.
 
 @include regression.texi
+
+
+@node RELIABILITY
+@section RELIABILITY
+
+@vindex RELIABILITY
+@display
+RELIABILITY
+        /VARIABLES=var_list
+        /SCALE (@var{name}) = @{var_list, ALL@}
+        /MODEL=@{ALPHA, SPLIT[(N)]@}
+        /SUMMARY=@{TOTAL,ALL@}
+        /MISSING=@{EXCLUDE,INCLUDE@}
+@end display
+
+@cindex Cronbach's Alpha
+The @cmd{RELIABILTY} command performs reliablity analysis on the data.
+
+The VARIABLES subcommand is required. It determines the set of variables 
+upon which analysis is to be performed.
+
+The SCALE subcommand determines which variables reliability is to be 
+calculated for.  If it is omitted, then analysis for all variables named
+in the VARIABLES subcommand will be used.
+Optionally, the @var{name} parameter may be specified to set a string name 
+for the scale.
+
+The MODEL subcommand determines the type of analysis. If ALPHA is specified, 
+then Cronbach's Alpha is calculated for the scale.  If the model is SPLIT, 
+then the variables  are divided into 2 subsets.  An optional parameter 
+@var{N} may be given, to specify how many variables to be in the first subset.
+If @var{N} is omitted, then it defaults to one half of the variables in the 
+scale, or one half minus one if there are an odd number of variables.
+The default model is ALPHA.
+
+By default, any cases with user missing, or system missing values for 
+any variables given 
+in the VARIABLES subcommand will be omitted from analysis.
+The MISSING subcommand determines whether user missing values are to 
+be included or excluded in the analysis.
+
+The SUMMARY subcommand determines the type of summary analysis to be performed.
+Currently there is only one type: SUMMARY=TOTAL, which displays per-item
+analysis tested against the totals.
+
+
+
index 27bbb2da8d039204be8c27f9b996f867b9ba6511..2a52ad17f72049b8fe4b036836a4bcd3bb3c7454 100644 (file)
@@ -83,7 +83,7 @@ list.
 Each set must have exactly as many source variables as aggregation
 variables.  Each aggregation variable receives the results of applying
 the specified aggregation function to the corresponding source
-variable.  The MEAN, SD, and SUM aggregation functions may only be
+variable.  The MEAN, MEDIAN, SD, and SUM aggregation functions may only be
 applied to numeric variables.  All the rest may be applied to numeric
 and short and long string variables.
 
@@ -128,6 +128,9 @@ dictionary information from the source variable.
 Arithmetic mean.  Limited to numeric values.  The default format is
 F8.2.
 
+@item MEDIAN(var_name)
+The median value.  Limited to numeric values.  The default format is F8.2.
+
 @item MIN(var_name)
 Minimum value.  The aggregation variable receives the complete
 dictionary information from the source variable.
index 314c435e37d1a1985202f4738ea5bf007815ad24..d825b9abc4a5e0e6a676ecd2c258bbb5f7d06e77 100644 (file)
@@ -334,6 +334,7 @@ SET
         /MXERRS=max_errs
         /MXWARNS=max_warnings
         /PROMPT='prompt'
+        /WORKSPACE=workspace_size
 
 (program execution)
         /MEXPAND=@{ON,OFF@}
@@ -390,7 +391,6 @@ SET
         /SCRIPTTAB='c'
         /TB1=@{'xxx','xxxxxxxxxxx'@}
         /TBFONTS='string'
-        /WORKSPACE=workspace_size
         /XSORT=@{YES,NO@}
 @end display
 
@@ -414,10 +414,13 @@ default.  Any real value may be assigned.
 
 @item DECIMAL
 @anchor{SET DECIMAL}
-The default DOT setting causes the decimal point character to be
-@samp{.} and the grouping character to be @samp{,}.  A setting of COMMA
+This value may be set to DOT or COMMA.
+Setting it to DOT causes the decimal point character to be
+@samp{.} and the grouping character to be @samp{,}.
+Setting it to COMMA
 causes the decimal point character to be @samp{,} and the grouping
 character to be @samp{.}.
+The default value is determined from the system locale.
 
 @item FORMAT
 Allows the default numeric input/output format to be specified.  The
@@ -554,6 +557,17 @@ RANDOM, which will obtain an initial seed from the current time of day.
 
 @item UNDEFINED
 Currently not used.
+
+@item WORKSPACE
+The maximum amount of memory that PSPP will use to store data being processed.
+If memory in excess of the workspace size is required, then PSPP will start
+to use temporary files to store the data.
+Setting a higher value will, in general, mean procedures will run faster, 
+but may cause other applications to run slower.
+On platforms without virtual memory management, setting a very large workspace
+may cause PSPP to abort.
+@cindex workspace
+@cindex memory, amount used to store cases
 @end table
 
 Data output subcommands affect the format of output data.  These
index a66e423292054adf60892eb059449e8db7dff2a1..95a5b67b6ff6c5aa9fa91db119aeb408cdd2fb98 100644 (file)
@@ -7,8 +7,7 @@ several utility functions for examining and adjusting them.
 @menu
 * ADD VALUE LABELS::            Add value labels to variables.
 * DELETE VARIABLES::            Delete variables.
-* DISPLAY::                     Display variable names & descriptions.
-* DISPLAY VECTORS::             Display a list of vectors.
+* DISPLAY::                     Display information about the active file.
 * FORMATS::                     Set print and write formats.
 * LEAVE::                       Don't clear variables between cases.
 * MISSING VALUES::              Set missing values for variables.
@@ -18,6 +17,7 @@ several utility functions for examining and adjusting them.
 * RENAME VARIABLES::            Rename variables.
 * VALUE LABELS::                Set value labels for variables.
 * STRING::                      Create new string variables.
+* VARIABLE ATTRIBUTE::          Set custom attributes on variables.
 * VARIABLE LABELS::             Set variable labels for variables.
 * VARIABLE ALIGNMENT::          Set the alignment for display.
 * VARIABLE WIDTH::              Set the display width.
@@ -61,15 +61,26 @@ effect, it causes the temporary transformations to become permanent.
 @vindex DISPLAY
 
 @display
-DISPLAY @{NAMES,INDEX,LABELS,VARIABLES,DICTIONARY,SCRATCH@}
-        [SORTED] [var_list]
+DISPLAY [SORTED] NAMES [[/VARIABLES=]var_list].
+DISPLAY [SORTED] INDEX [[/VARIABLES=]var_list].
+DISPLAY [SORTED] LABELS [[/VARIABLES=]var_list].
+DISPLAY [SORTED] VARIABLES [[/VARIABLES=]var_list].
+DISPLAY [SORTED] DICTIONARY [[/VARIABLES=]var_list].
+DISPLAY [SORTED] SCRATCH [[/VARIABLES=]var_list].
+DISPLAY [SORTED] ATTRIBUTES [[/VARIABLES=]var_list].
+DISPLAY [SORTED] @@ATTRIBUTES [[/VARIABLES=]var_list].
+DISPLAY [SORTED] VECTORS.
 @end display
 
-@cmd{DISPLAY} displays requested information on variables.  Variables can
-optionally be sorted alphabetically.  The entire dictionary or just
-specified variables can be described.
+@cmd{DISPLAY} displays information about the active file.  A variety
+of different forms of information can be requested.
 
-One of the following keywords can be present:
+The following keywords primarily cause information about variables to
+be displayed.  With these keywords, by default information is
+displayed about all variable in the active file, in the order that
+variables occur in the active file dictionary.  The SORTED keyword
+causes output to be sorted alphabetically by variable name.  The
+VARIABLES subcommand limits output to the specified variables.
 
 @table @asis
 @item NAMES
@@ -91,23 +102,24 @@ Variable names, positions, print and write formats, missing values,
 variable labels, and value labels are displayed.
 
 @item SCRATCH
-Varible names are displayed, for scratch variables only (@pxref{Scratch
+Variable names are displayed, for scratch variables only (@pxref{Scratch
 Variables}).
-@end table
 
-If SORTED is specified, then the variables are displayed in ascending
-order based on their names; otherwise, they are displayed in the order
-that they occur in the active file dictionary.
+@item ATTRIBUTES
+Datafile and variable attributes are displayed, except that attributes
+whose names begin with @code{@@} or @code{$@@} are omitted.
 
-@node DISPLAY VECTORS
-@section DISPLAY VECTORS
-@vindex DISPLAY VECTORS
+@itemx @@ATTRIBUTES
+All datafile and variable attributes are displayed.
+@end table
 
-@display
-DISPLAY VECTORS.
-@end display
+With the @code{VECTOR} keyword, @cmd{DISPLAY} lists all the currently
+declared vectors.  If the SORTED keyword is given, the vectors are
+listed in alphabetical order; otherwise, they are listed in textual
+order of definition within the PSPP syntax file.
 
-@cmd{DISPLAY VECTORS} lists all the currently declared vectors.
+For related commands, see @ref{DISPLAY DOCUMENTS} and @ref{DISPLAY
+FILE LABEL}.
 
 @node FORMATS
 @section FORMATS
@@ -357,6 +369,60 @@ implicitly derived from the specified output formats.
 Created variables are initialized to spaces.
 
 
+@node VARIABLE ATTRIBUTE
+@section VARIABLE ATTRIBUTE
+@vindex VARIABLE ATTRIBUTE
+
+@display
+VARIABLE ATTRIBUTE
+         VARIABLES=var_list
+         ATTRIBUTE=name('value') [name('value')]@dots{}
+         ATTRIBUTE=name@b{[}index@b{]}('value') [name@b{[}index@b{]}('value')]@dots{}
+         DELETE=name [name]@dots{}
+         DELETE=name@b{[}index@b{]} [name@b{[}index@b{]}]@dots{}
+@end display
+
+@cmd{VARIABLE ATTRIBUTE} adds, modifies, or removes user-defined
+attributes associated with variables in the active file.  Custom
+variable attributes are not interpreted by PSPP, but they are saved as
+part of system files and may be used by other software that reads
+them.
+
+The required VARIABLES subcommand must come first.  Specify the
+variables to which the following ATTRIBUTE or DELETE subcommand
+should apply.
+
+Use the ATTRIBUTE subcommand to add or modify custom variable
+attributes.  Specify the name of the attribute as an identifier
+(@pxref{Tokens}), followed by the desired value, in parentheses, as a
+quoted string.  The specified attributes are then added or modified in
+the variables specified on VARIABLES.  Attribute names that begin with
+@code{$} are reserved for PSPP's internal use, and attribute names
+that begin with @code{@@} or @code{$@@} are not displayed by most PSPP
+commands that display other attributes.  Other attribute names are not
+treated specially.
+
+Attributes may also be organized into arrays.  To assign to an array
+element, add an integer array index enclosed in square brackets
+(@code{[} and @code{]}) between the attribute name and value.  Array
+indexes start at 1, not 0.  An attribute array that has a single
+element (number 1) is not distinguished from a non-array attribute.
+
+Use the DELETE subcommand to delete an attribute from the variable
+specified on VARIABLES.  Specify an attribute name by itself to delete
+an entire attribute, including all array elements for attribute
+arrays.  Specify an attribute name followed by an array index in
+square brackets to delete a single element of an attribute array.  In
+the latter case, all the array elements numbered higher than the
+deleted element are shifted down, filling the vacated position.
+
+To associate custom attributes with the entire active file, instead of
+with particular variables, use @cmd{DATAFILE ATTRIBUTE} instead.
+
+@cmd{VARIABLE ATTRIBUTE} takes effect immediately.  It is not affected
+by conditional and looping structures such as @cmd{DO IF} or
+@cmd{LOOP}.
+
 @node VARIABLE LABELS
 @section VARIABLE LABELS
 @vindex VARIABLE LABELS
diff --git a/examples/ChangeLog b/examples/ChangeLog
deleted file mode 100644 (file)
index 4fd9e0d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Tue Apr  4 20:19:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add missing \ to definition.
-
-Sun Aug  9 11:16:13 1998  Ben Pfaff  <blp@gnu.org>
-
-       * descriptives.stat: Renamed descript.stat.
-
-Sat Aug  8 00:28:24 1998  Ben Pfaff  <blp@gnu.org>
-
-       * New directory.
-
-       * descriptives.stat: New file.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/examples/OChangeLog b/examples/OChangeLog
new file mode 100644 (file)
index 0000000..4fd9e0d
--- /dev/null
@@ -0,0 +1,19 @@
+Tue Apr  4 20:19:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add missing \ to definition.
+
+Sun Aug  9 11:16:13 1998  Ben Pfaff  <blp@gnu.org>
+
+       * descriptives.stat: Renamed descript.stat.
+
+Sat Aug  8 00:28:24 1998  Ben Pfaff  <blp@gnu.org>
+
+       * New directory.
+
+       * descriptives.stat: New file.
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index 641e4288205e782db619235fdf3fd5c96e833350..cdbec4bbf35bcf6542c806dc2f1651d8f9695182 100644 (file)
@@ -4,3 +4,5 @@ EXTRA_DIST += \
        examples/descript.stat \
        examples/regress.stat \
        examples/regress_categorical.stat
+
+EXTRA_DIST += examples/OChangeLog
diff --git a/glade/ChangeLog b/glade/ChangeLog
deleted file mode 100644 (file)
index b6ac4bb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-2007-11-21 John Darrington <john@darrington.wattle.id.au>
-
-       * icons/22x22/psppire-acr.png icons/16x16/psppire-acr.png: New files.
-       * automake.mk: Install the new icons.
-
-2007-10-19 John Darrington <john@darrington.wattle.id.au>
-
-       * acr.c (new file)
-       * psppire.xml: Added entry for PsppireAcr widget
-
-2007-09-26  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (libglade_psppire_la_CFLAGS): Enable VPATH build by
-       using $(top_srcdir) in -I directive.
-
-4/4/2007 John Darrington <john@darrington.wattle.id.au>
-
-  * Seperated psppire-buttonbox into psppire-vbuttonbox and psppire-buttonbox
-
-Sat Mar 31 07:09:33 WST 2007 John Darrington <john@darrington.wattle.id.au>
-       
-  * Added icons directory and its contents.
-
-  * Re-wrote psppire.xml to work with glade 3.2.0, and to know about the
-    keypad widget. 
diff --git a/glade/OChangeLog b/glade/OChangeLog
new file mode 100644 (file)
index 0000000..b6ac4bb
--- /dev/null
@@ -0,0 +1,25 @@
+2007-11-21 John Darrington <john@darrington.wattle.id.au>
+
+       * icons/22x22/psppire-acr.png icons/16x16/psppire-acr.png: New files.
+       * automake.mk: Install the new icons.
+
+2007-10-19 John Darrington <john@darrington.wattle.id.au>
+
+       * acr.c (new file)
+       * psppire.xml: Added entry for PsppireAcr widget
+
+2007-09-26  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (libglade_psppire_la_CFLAGS): Enable VPATH build by
+       using $(top_srcdir) in -I directive.
+
+4/4/2007 John Darrington <john@darrington.wattle.id.au>
+
+  * Seperated psppire-buttonbox into psppire-vbuttonbox and psppire-buttonbox
+
+Sat Mar 31 07:09:33 WST 2007 John Darrington <john@darrington.wattle.id.au>
+       
+  * Added icons directory and its contents.
+
+  * Re-wrote psppire.xml to work with glade 3.2.0, and to know about the
+    keypad widget. 
index 6021eecd2acc0419649d11703c419db3082d196c..7827516e3b9e3517aa33e44614eb16b958f856d8 100644 (file)
@@ -46,3 +46,5 @@ libglade_psppire_la_CFLAGS = $(GLADE_UI_CFLAGS) $(GLADE_CFLAGS) \
        -I $(top_srcdir)/src/ui/gui -DDEBUGGING
 
 libglade_psppire_la_LIBADD = gl/libgl.la
+
+EXTRA_DIST += glade/OChangeLog
diff --git a/lib/ChangeLog b/lib/ChangeLog
deleted file mode 100644 (file)
index 44bff7c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-Sun Jul 31 11:29:04 2005  Ben Pfaff  <blp@gnu.org>
-
-       * misc/: Removed in favor of gnulib.
-
-       * Makefile.am: (SUBDIRS) Removed misc.
-
-Wed Mar  9 09:53:50 2005  Ben Pfaff  <blp@gnu.org>
-
-       * gsl-extras/: New directory.
-
-       * Makefile.am: (SUBDIRS) Add gsl-extras.
-
-Mon Feb 28 23:20:05 2005  Ben Pfaff  <blp@gnu.org>
-
-       * julcal/: Removed directory.
-
-       * Makefile.am: (SUBDIRS) Removed julcal.
-       (DIST_SUBDIRS) Removed.
-
-Sun Jan  2 21:31:48 2000  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (SUBDIRS) Only include gmp if libgmp not installed
-       on this system already.
-
-Sun May 31 00:55:51 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (SUBDIRS) Add gmp.
-
-       * gmp/: New subdirectory, containing a subset of GNU libgmp2 just
-       big enough to support mpf_init_set_d(), mpf_get_str(), and
-       mpf_clear().
-
-Fri Apr 24 12:52:07 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (SUBDIRS) Remove avllib.
-
-       * avllib/: Removed.
-
-Wed Dec 24 22:36:50 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (SUBDIRS) Add dcdflib.
-
-       * dcdflib: New subdirectory.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/lib/OChangeLog b/lib/OChangeLog
new file mode 100644 (file)
index 0000000..28c767b
--- /dev/null
@@ -0,0 +1,54 @@
+2008/07/20 John Darrington <john@darrington.wattle.id.au>
+
+       * Removed gsl-extras.  Functionality now
+       available in gsl.
+
+Sun Jul 31 11:29:04 2005  Ben Pfaff  <blp@gnu.org>
+
+       * misc/: Removed in favor of gnulib.
+
+       * Makefile.am: (SUBDIRS) Removed misc.
+
+Wed Mar  9 09:53:50 2005  Ben Pfaff  <blp@gnu.org>
+
+       * gsl-extras/: New directory.
+
+       * Makefile.am: (SUBDIRS) Add gsl-extras.
+
+Mon Feb 28 23:20:05 2005  Ben Pfaff  <blp@gnu.org>
+
+       * julcal/: Removed directory.
+
+       * Makefile.am: (SUBDIRS) Removed julcal.
+       (DIST_SUBDIRS) Removed.
+
+Sun Jan  2 21:31:48 2000  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (SUBDIRS) Only include gmp if libgmp not installed
+       on this system already.
+
+Sun May 31 00:55:51 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (SUBDIRS) Add gmp.
+
+       * gmp/: New subdirectory, containing a subset of GNU libgmp2 just
+       big enough to support mpf_init_set_d(), mpf_get_str(), and
+       mpf_clear().
+
+Fri Apr 24 12:52:07 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (SUBDIRS) Remove avllib.
+
+       * avllib/: Removed.
+
+Wed Dec 24 22:36:50 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (SUBDIRS) Add dcdflib.
+
+       * dcdflib: New subdirectory.
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index 3afc9e1ade16d512179cdb68100c04a7ccb02fe6..9197da9742569acb1baed6b933e74a409b3e66f8 100644 (file)
@@ -1,8 +1,10 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
 include $(top_srcdir)/lib/linreg/automake.mk
-include $(top_srcdir)/lib/gsl-extras/automake.mk
+include $(top_srcdir)/lib/misc/automake.mk
 
 if WITHGUI
 include $(top_srcdir)/lib/gtksheet/automake.mk
 endif
+
+EXTRA_DIST += lib/OChangeLog
diff --git a/lib/gsl-extras/.gitignore b/lib/gsl-extras/.gitignore
deleted file mode 100644 (file)
index 282522d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/lib/gsl-extras/ChangeLog b/lib/gsl-extras/ChangeLog
deleted file mode 100644 (file)
index 6e462c6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-Thu Apr 14 10:48:17 2005  Ben Pfaff  <blp@gnu.org>
-
-       * betadistinv.c: Apply patch from Jason Stover
-       <jstover@sdf.lonestar.org> to obtain better initial approximation
-       and tidy up a bit.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/lib/gsl-extras/README b/lib/gsl-extras/README
deleted file mode 100644 (file)
index 275bab1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-The files in this directory are not part of GNU PSPP, but they are
-used with GNU PSPP.  In the future, they will likely become part of
-the GNU Scientific Library.
diff --git a/lib/gsl-extras/automake.mk b/lib/gsl-extras/automake.mk
deleted file mode 100644 (file)
index 7d1ed62..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-## Process this file with automake to produce Makefile.in  -*- makefile -*-
-
-noinst_LIBRARIES += lib/gsl-extras/libgsl-extras.a
-
-lib_gsl_extras_libgsl_extras_a_SOURCES = \
-       lib/gsl-extras/betadistinv.c lib/gsl-extras/binomial.c lib/gsl-extras/geometric.c       \
-       lib/gsl-extras/hypergeometric.c lib/gsl-extras/negbinom.c lib/gsl-extras/poisson.c lib/gsl-extras/gsl-extras.h
-
-EXTRA_DIST += lib/gsl-extras/README
diff --git a/lib/gsl-extras/betadistinv.c b/lib/gsl-extras/betadistinv.c
deleted file mode 100644 (file)
index b6192bf..0000000
+++ /dev/null
@@ -1,686 +0,0 @@
-/* cdf/betadistinv.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/*
- * Invert the Beta distribution.
- *
- * References:
- *
- * Roger W. Abernathy and Robert P. Smith. "Applying Series Expansion
- * to the Inverse Beta Distribution to Find Percentiles of the F-Distribution,"
- * ACM Transactions on Mathematical Software, volume 19, number 4, December 1993,
- * pages 474-480.
- *
- * G.W. Hill and A.W. Davis. "Generalized asymptotic expansions of a
- * Cornish-Fisher type," Annals of Mathematical Statistics, volume 39, number 8,
- * August 1968, pages 1264-1273.
- */
-
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_sf_gamma.h>
-#include <gsl/gsl_cdf.h>
-#include <gsl/gsl_randist.h>
-#include "gsl-extras.h"
-
-#define BETAINV_INIT_ERR .001
-#define BETADISTINV_N_TERMS 3
-#define BETADISTINV_MAXITER 20
-
-static double
-s_bisect (double x, double y)
-{
-  double result = GSL_MIN(x,y) + fabs(x - y) / 2.0;
-  return result;
-}
-static double
-new_guess_P ( double old_guess, double x, double y,
-             double prob, double a, double b)
-{
-  double result;
-  double p_hat;
-  double end_point;
-
-  p_hat = gsl_cdf_beta_P(old_guess, a, b);
-  if (p_hat < prob)
-    {
-      end_point = GSL_MAX(x,y);
-    }
-  else if ( p_hat > prob )
-    {
-      end_point = GSL_MIN(x,y);
-    }
-  else
-    {
-      end_point = old_guess;
-    }
-  result = s_bisect(old_guess, end_point);
-
-  return result;
-}
-
-static double
-new_guess_Q ( double old_guess, double x, double y,
-             double prob, double a, double b)
-{
-  double result;
-  double q_hat;
-  double end_point;
-
-  q_hat = gsl_cdf_beta_Q(old_guess, a, b);
-  if (q_hat >= prob)
-    {
-      end_point = GSL_MAX(x,y);
-    }
-  else if ( q_hat < prob )
-    {
-      end_point = GSL_MIN(x,y);
-    }
-  else
-    {
-      end_point = old_guess;
-    }
-  result = s_bisect(old_guess, end_point);
-
-  return result;
-}
-
-/*
- * The get_corn_fish_* functions below return the first
- * three terms of the Cornish-Fisher expansion
- * without recursion. The recursive functions
- * make the code more legible when higher order coefficients
- * are used, but terms beyond the cubic do not
- * improve accuracy.
- */
-  /*
-   * Linear coefficient for the
-   * Cornish-Fisher expansion.
-   */
-static double
-get_corn_fish_lin (const double x, const double a, const double b)
-{
-  double result;
-
-  result = gsl_ran_beta_pdf (x, a, b);
-  if(result > 0)
-    {
-      result = 1.0 / result;
-    }
-  else
-    {
-      result = GSL_DBL_MAX;
-    }
-
-  return result;
-}
-  /*
-   * Quadratic coefficient for the
-   * Cornish-Fisher expansion.
-   */
-static double
-get_corn_fish_quad (const double x, const double a, const double b)
-{
-  double result;
-  double gam_ab;
-  double gam_a;
-  double gam_b;
-  double num;
-  double den;
-
-  gam_ab =  gsl_sf_lngamma(a + b);
-  gam_a = gsl_sf_lngamma (a);
-  gam_b = gsl_sf_lngamma (b);
-  num = exp(2 * (gam_a + gam_b - gam_ab)) * (1 - a + x * (b + a - 2));
-  den = 2.0 * pow ( x, 2*a - 1 ) * pow ( 1 - x, 2 * b - 1 );
-  if ( fabs(den) > 0.0)
-    {
-      result = num / den;
-    }
-  else
-    {
-      result = 0.0;
-    }
-
-  return result;
-}
-/*
- * The cubic term for the Cornish-Fisher expansion.
- * Theoretically, use of this term should give a better approximation,
- * but in practice inclusion of the cubic term worsens the
- * iterative procedure in gsl_cdf_beta_Pinv and gsl_cdf_beta_Qinv
- * for extreme values of p, a or b.
- */
-#if 0
-static double
-get_corn_fish_cube (const double x, const double a, const double b)
-{
-  double result;
-  double am1 = a - 1.0;
-  double am2 = a - 2.0;
-  double apbm2 = a+b-2.0;
-  double apbm3 = a+b-3.0;
-  double apbm4 = a+b-4.0;
-  double ab1ab2 = am1 * am2;
-  double tmp;
-  double num;
-  double den;
-
-  num =  (am1 - x * apbm2) * (am1 - x * apbm2);
-  tmp = ab1ab2 - x * (apbm2 * ( ab1ab2 * apbm4 + 1) + x * apbm2 * apbm3);
-  num += tmp;
-  tmp = gsl_ran_beta_pdf(x,a,b);
-  den = 2.0 * x * x * (1 - x) * (1 - x) * pow(tmp,3.0);
-  if ( fabs(den) > 0.0)
-    {
-      result = num / den;
-    }
-  else
-    {
-      result = 0.0;
-    }
-
-  return result;
-}
-#endif
-/*
- * The Cornish-Fisher coefficients can be defined recursivley,
- * starting with the nth derivative of s_psi = -f'(x)/f(x),
- * where f is the beta density.
- *
- * The section below was commented out since
- * the recursive generation of the coeficients did
- * not improve the accuracy of the directly coded
- * the first three coefficients.
- */
-#if 0
-static double
-s_d_psi (double x, double a, double b, int n)
-{
-  double result;
-  double np1 = (double) n + 1;
-  double asgn;
-  double bsgn;
-  double bm1 = b - 1.0;
-  double am1 = a - 1.0;
-  double mx = 1.0 - x;
-
-  asgn = (n % 2) ? 1.0:-1.0;
-  bsgn = (n % 2) ? -1.0:1.0;
-  result = gsl_sf_gamma(np1) * ((bsgn * bm1 / (pow(mx, np1)))
-                               + (asgn * am1 / (pow(x,np1))));
-  return result;
-}
-/*
- * nth derivative of a coefficient with respect
- * to x.
- */
-static double
-get_d_coeff ( double x, double a,
-             double b, double n, double k)
-{
-  double result;
-  double d_psi;
-  double k_fac;
-  double i_fac;
-  double kmi_fac;
-  double i;
-
-  if (n == 2)
-    {
-      result = s_d_psi(x, a, b, k);
-    }
-  else
-    {
-      result = 0.0;
-      for (i = 0.0; i < (k+1); i++)
-       {
-         k_fac = gsl_sf_lngamma(k+1.0);
-         i_fac = gsl_sf_lngamma(i+1.0);
-         kmi_fac = gsl_sf_lngamma(k-i+1.0);
-
-         result += exp(k_fac - i_fac - kmi_fac)
-           * get_d_coeff( x, a, b, 2.0, i)
-           * get_d_coeff( x, a, b, (n - 1.0), (k - i));
-       }
-      result += get_d_coeff ( x, a, b, (n-1.0), (k+1.0));
-    }
-
-  return result;
-}
-/*
- * Cornish-Fisher coefficient.
- */
-static double
-get_corn_fish (double c, double x,
-              double a, double b, double n)
-{
-  double result;
-  double dc;
-  double c_prev;
-
-  if(n == 1.0)
-    {
-      result = 1;
-    }
-  else if (n==2.0)
-    {
-      result = s_d_psi(x, a, b, 0);
-    }
-  else
-    {
-      dc = get_d_coeff(x, a, b, (n-1.0), 1.0);
-      c_prev = get_corn_fish(c, x, a, b, (n-1.0));
-      result = (n-1) * s_d_psi(x,a,b,0) * c_prev + dc;
-    }
-  return result;
-}
-#endif
-
-double
-gslextras_cdf_beta_Pinv ( const double p, const double a, const double b)
-{
-  double result;
-  double state;
-  double beta_result;
-  double lower = 0.0;
-  double upper = 1.0;
-  double c1;
-  double c2;
-#if 0
-  double c3;
-#endif
-  double frac1;
-  double frac2;
-  double frac3;
-  double frac4;
-  double p0;
-  double p1;
-  double p2;
-  double tmp;
-  double err;
-  double abserr;
-  double relerr;
-  double min_err;
-  int n_iter = 0;
-
-  if ( p < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0", GSL_EDOM);
-    }
-  if ( p > 1.0 )
-    {
-      GSLEXTRAS_CDF_ERROR("p > 1",GSL_EDOM);
-    }
-  if ( a < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("a < 0", GSL_EDOM );
-    }
-  if ( b < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ( "b < 0", GSL_EDOM );
-    }
-  if ( p == 0.0 )
-    {
-      return 0.0;
-    }
-  if ( p == 1.0 )
-    {
-      return 1.0;
-    }
-
-  if (p > (1.0 - GSL_DBL_EPSILON))
-    {
-      /*
-       * When p is close to 1.0, the bisection
-       * works better with gsl_cdf_Q.
-       */
-      state = gslextras_cdf_beta_Qinv ( p, a, b);
-      result = 1.0 - state;
-      return result;
-    }
-  if (p < GSL_DBL_EPSILON )
-    {
-      /*
-       * Start at a small value and rise until
-       * we are above the correct result. This
-       * avoids overflow. When p is very close to
-       * 0, an initial state value of a/(a+b) will
-       * cause the interpolating polynomial
-       * to overflow.
-       */
-      upper = GSL_DBL_MIN;
-      beta_result = gsl_cdf_beta_P (upper, a, b);
-      while (beta_result < p)
-       {
-         lower = upper;
-         upper *= 4.0;
-         beta_result = gsl_cdf_beta_P (upper, a, b);
-       }
-      state = (lower + upper) / 2.0;
-    }
-  else
-    {
-      /*
-       * First guess is the expected value.
-       */
-      lower = 0.0;
-      upper = 1.0;
-      state = a/(a+b);
-      beta_result = gsl_cdf_beta_P (state, a, b);
-    }
-  err = beta_result - p;
-  abserr = fabs(err);
-  relerr = abserr / p;
-  while ( relerr > BETAINV_INIT_ERR)
-    {
-      tmp = new_guess_P ( state, lower, upper,
-                         p, a, b);
-      lower = ( tmp < state ) ? lower:state;
-      upper = ( tmp < state ) ? state:upper;
-      state = tmp;
-      beta_result = gsl_cdf_beta_P (state, a, b);
-      err = p - beta_result;
-      abserr = fabs(err);
-      relerr = abserr / p;
-    }
-
-  result = state;
-  min_err = relerr;
-  /*
-   * Use a second order Lagrange interpolating
-   * polynomial to get closer before switching to
-   * the iterative method.
-   */
-  p0 = gsl_cdf_beta_P (lower, a, b);
-  p1 = gsl_cdf_beta_P (state, a, b);
-  p2 = gsl_cdf_beta_P (upper, a, b);
-  if( p0 < p1 && p1 < p2)
-    {
-      frac1 = (p - p2) / (p0 - p1);
-      frac2 = (p - p1) / (p0 - p2);
-      frac3 = (p - p0) / (p1 - p2);
-      frac4 = (p - p0) * (p - p1) / ((p2 - p0) * (p2 - p1));
-      state = frac1 * (frac2 * lower - frac3 * state)
-       + frac4 * upper;
-
-      beta_result = gsl_cdf_beta_P( state, a, b);
-      err = p - beta_result;
-      abserr = fabs(err);
-      relerr = abserr / p;
-      if (relerr < min_err)
-       {
-         result = state;
-         min_err = relerr;
-       }
-      else
-       {
-         /*
-          * Lagrange polynomial failed to reduce the error.
-          * This will happen with a very skewed beta density.
-          * Undo previous steps.
-          */
-         state = result;
-         beta_result = gsl_cdf_beta_P(state,a,b);
-         err = p - beta_result;
-         abserr = fabs(err);
-         relerr = abserr / p;
-       }
-    }
-
-  n_iter = 0;
-
-  /*
-   * Newton-type iteration using the terms from the
-   * Cornish-Fisher expansion. If only the first term
-   * of the expansion is used, this is Newton's method.
-   */
-  while ( relerr > GSL_DBL_EPSILON && n_iter < BETADISTINV_MAXITER)
-    {
-      n_iter++;
-      c1 = get_corn_fish_lin (state, a, b);
-      c2 = get_corn_fish_quad (state, a, b);
-      /*
-       * The cubic term does not help, and can can
-       * harm the approximation for extreme values of
-       * p, a, or b.
-       */
-#if 0
-      c3 = get_corn_fish_cube (state, a, b);
-      state += err * (c1 + (err / 2.0 ) * (c2 + c3 * err / 3.0));
-#endif
-      state += err * (c1 + (c2 * err / 2.0 ));
-      /*
-       * The section below which is commented out uses
-       * a recursive function to get the coefficients.
-       * The recursion makes coding higher-order terms
-       * easier, but did not improve the result beyond
-       * the use of three terms. Since explicitly coding
-       * those three terms in the get_corn_fish_* functions
-       * was not difficult, the recursion was abandoned.
-       */
-#if 0
-      coeff = 1.0;
-      for(i = 1.0; i < BETADISTINV_N_TERMS; i += 1.0)
-       {
-         i_fac *= i;
-         coeff = get_corn_fish (coeff, prior_state, a, b, i);
-         state += coeff * pow(err, i) /
-           (i_fac * pow (gsl_ran_beta_pdf(prior_state,a,b), i));
-       }
-#endif
-      beta_result = gsl_cdf_beta_P ( state, a, b );
-      err = p - beta_result;
-      abserr = fabs(err);
-      relerr = abserr / p;
-      if (relerr < min_err)
-       {
-         result = state;
-         min_err = relerr;
-       }
-    }
-
-  return result;
-}
-
-double
-gslextras_cdf_beta_Qinv (double q, double a, double b)
-{
-  double result;
-  double state;
-  double beta_result;
-  double lower = 0.0;
-  double upper = 1.0;
-  double c1;
-  double c2;
-#if 0
-  double c3;
-#endif
-  double p0;
-  double p1;
-  double p2;
-  double frac1;
-  double frac2;
-  double frac3;
-  double frac4;
-  double tmp;
-  double err;
-  double abserr;
-  double relerr;
-  double min_err;
-  int n_iter = 0;
-
-  if ( q < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR("q < 0", GSL_EDOM);
-    }
-  if ( q > 1.0 )
-    {
-      GSLEXTRAS_CDF_ERROR("q > 1",GSL_EDOM);
-    }
-  if ( a < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("a < 0", GSL_EDOM );
-    }
-  if ( b < 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ( "b < 0", GSL_EDOM );
-    }
-  if ( q == 0.0 )
-    {
-      return 1.0;
-    }
-  if ( q == 1.0 )
-    {
-      return 0.0;
-    }
-
-  if ( q < GSL_DBL_EPSILON )
-    {
-      /*
-       * When q is close to 0, the bisection
-       * and interpolation done in the rest of
-       * this routine will not give the correct
-       * value within double precision, so
-       * gsl_cdf_beta_Qinv is called instead.
-       */
-      state = gslextras_cdf_beta_Pinv ( q, a, b);
-      result = 1.0 - state;
-      return result;
-    }
-  if ( q > 1.0 - GSL_DBL_EPSILON )
-    {
-      /*
-       * Make the initial guess close to 0.0.
-       */
-      upper = GSL_DBL_MIN;
-      beta_result = gsl_cdf_beta_Q ( upper, a, b);
-      while (beta_result > q )
-       {
-         lower = upper;
-         upper *= 4.0;
-         beta_result = gsl_cdf_beta_Q ( upper, a, b);
-       }
-      state = (upper + lower) / 2.0;
-    }
-  else
-    {
-      /* Bisection to get an initial approximation.
-       * First guess is the expected value.
-       */
-      state = a/(a+b);
-      lower = 0.0;
-      upper = 1.0;
-    }
-  beta_result = gsl_cdf_beta_Q (state, a, b);
-  err = beta_result - q;
-  abserr = fabs(err);
-  relerr = abserr / q;
-  while ( relerr > BETAINV_INIT_ERR)
-    {
-      n_iter++;
-      tmp = new_guess_Q ( state, lower, upper,
-                         q, a, b);
-      lower = ( tmp < state ) ? lower:state;
-      upper = ( tmp < state ) ? state:upper;
-      state = tmp;
-      beta_result = gsl_cdf_beta_Q (state, a, b);
-      err = q - beta_result;
-      abserr = fabs(err);
-      relerr = abserr / q;
-    }
-  result = state;
-  min_err = relerr;
-
-  /*
-   * Use a second order Lagrange interpolating
-   * polynomial to get closer before switching to
-   * the iterative method.
-   */
-  p0 = gsl_cdf_beta_Q (lower, a, b);
-  p1 = gsl_cdf_beta_Q (state, a, b);
-  p2 = gsl_cdf_beta_Q (upper, a, b);
-  if(p0 > p1 && p1 > p2)
-    {
-      frac1 = (q - p2) / (p0 - p1);
-      frac2 = (q - p1) / (p0 - p2);
-      frac3 = (q - p0) / (p1 - p2);
-      frac4 = (q - p0) * (q - p1) / ((p2 - p0) * (p2 - p1));
-      state = frac1 * (frac2 * lower - frac3 * state)
-       + frac4 * upper;
-      beta_result = gsl_cdf_beta_Q( state, a, b);
-      err = beta_result - q;
-      abserr = fabs(err);
-      relerr = abserr / q;
-      if (relerr < min_err)
-       {
-         result = state;
-         min_err = relerr;
-       }
-      else
-       {
-         /*
-          * Lagrange polynomial failed to reduce the error.
-          * This will happen with a very skewed beta density.
-          * Undo previous steps.
-          */
-         state = result;
-         beta_result = gsl_cdf_beta_P(state,a,b);
-         err = q - beta_result;
-         abserr = fabs(err);
-         relerr = abserr / q;
-       }
-    }
-
-  /*
-   * Iteration using the terms from the
-   * Cornish-Fisher expansion. If only the first term
-   * of the expansion is used, this is Newton's method.
-   */
-
-  n_iter = 0;
-  while ( relerr > GSL_DBL_EPSILON && n_iter < BETADISTINV_MAXITER)
-    {
-      n_iter++;
-      c1 = get_corn_fish_lin (state, a, b);
-      c2 = get_corn_fish_quad (state, a, b);
-      /*
-       * The cubic term does not help, and can harm
-       * the approximation for extreme values of p, a and b.
-       */
-#if 0
-      c3 = get_corn_fish_cube (state, a, b);
-      state += err * (c1 + (err / 2.0 ) * (c2 + c3 * err / 3.0));
-#endif
-      state += err * (c1 + (c2 * err / 2.0 ));
-      beta_result = gsl_cdf_beta_Q ( state, a, b );
-      err = beta_result - q;
-      abserr = fabs(err);
-      relerr = abserr / q;
-      if (relerr < min_err)
-       {
-         result = state;
-         min_err = relerr;
-       }
-    }
-
-  return result;
-}
diff --git a/lib/gsl-extras/binomial.c b/lib/gsl-extras/binomial.c
deleted file mode 100644 (file)
index 847247d..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* cdf/binomial.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/*
- * Computes the cumulative distribution function for a binomial
- * random variable. For a binomial random variable X with n trials
- * and success probability p,
- *
- *          Pr( X <= k ) = Pr( Y >= p )
- *
- * where Y is a beta random variable with parameters k+1 and n-k.
- *
- * Reference:
- *
- * W. Feller, "An Introduction to Probability and Its
- * Applications," volume 1. Wiley, 1968. Exercise 45, page 173,
- * chapter 6.
- */
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_cdf.h>
-#include "gsl-extras.h"
-
-double
-gslextras_cdf_binomial_P(const long k, const long n, const double p)
-{
-  double P;
-  double a;
-  double b;
-
-  if(p > 1.0 || p < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if ( k >= n )
-    {
-      P = 1.0;
-    }
-  else if (k < 0)
-    {
-      P = 0.0;
-    }
-  else
-    {
-      a = (double) k+1;
-      b = (double) n - k;
-      P = gsl_cdf_beta_Q( p, a, b);
-    }
-
-  return P;
-}
-double
-gslextras_cdf_binomial_Q(const long k, const long n, const double q)
-{
-  double P;
-  double a;
-  double b;
-
-  if(q > 1.0 || q < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if( k >= n )
-    {
-      P = 0.0;
-    }
-  else if ( k < 0 )
-    {
-      P = 1.0;
-    }
-  else
-    {
-      a = (double) k+1;
-      b = (double) n - k;
-      P = gsl_cdf_beta_P(q, a, b);
-    }
-
-  return P;
-}
-
diff --git a/lib/gsl-extras/geometric.c b/lib/gsl-extras/geometric.c
deleted file mode 100644 (file)
index de0f000..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* cdf/geometric.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/*
- * Pr(X <= n) for a negative binomial random variable X, i.e.,
- * the probability of n or fewer failuers before success k.
- */
-
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_sf.h>
-#include <gsl/gsl_cdf.h>
-#include "gsl-extras.h"
-
-/*
- * Pr (X <= n), i.e., the probability of n or fewer
- * failures until the first success.
- */
-double
-gslextras_cdf_geometric_P (const long n, const double p)
-{
-  double P;
-  double a;
-  int i;
-  int m;
-  double sign = 1.0;
-  double term;
-  double q;
-
-  if(p > 1.0 || p < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if ( n < 0 )
-    {
-      return 0.0;
-    }
-  q = 1.0 - p;
-  a = (double) n+1;
-  if( p < GSL_DBL_EPSILON )
-    {
-      /*
-       * 1.0 - pow(q,a) will overflow, so use
-       * a Taylor series.
-       */
-      i = 2;
-      m = n+1;
-      term = exp(log(a) + log(p));
-      P = term;
-      while ( term > GSL_DBL_MIN && i < m)
-       {
-         term = exp (sign * gsl_sf_lnchoose(m,i) + i * log(p));
-         P += term;
-         i++;
-         sign = -sign;
-       }
-    }
-  else
-    {
-      P = 1.0 - pow ( q, a);
-    }
-  return P;
-}
-double
-gslextras_cdf_geometric_Q ( const long n, const double p)
-{
-  double P;
-  double q;
-  double a;
-
-  if(p > 1.0 || p < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if ( n < 0 )
-    {
-      P = 1.0;
-    }
-  else
-    {
-      a = (double) n+1;
-      q = 1.0 - p;
-      P = pow(q, a);
-    }
-
-  return P;
-}
diff --git a/lib/gsl-extras/gsl-extras.h b/lib/gsl-extras/gsl-extras.h
deleted file mode 100644 (file)
index 48bf105..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef GSL_EXTRAS_H
-#define GSL_EXTRAS_H
-
-/* GSLEXTRAS_CDF_ERROR: call the error handler, and return a NAN. */
-#define GSLEXTRAS_CDF_ERROR(reason, gsl_errno) \
-       do { \
-       gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \
-       return GSL_NAN ; \
-       } while (0)
-
-double gslextras_cdf_beta_Pinv (const double p, const double a,
-                                const double b);
-double gslextras_cdf_beta_Qinv (double q, double a, double b);
-double gslextras_cdf_binomial_P(const long k, const long n, const double p);
-double gslextras_cdf_binomial_Q(const long k, const long n, const double q);
-double gslextras_cdf_geometric_P (const long n, const double p);
-double gslextras_cdf_geometric_Q ( const long n, const double p);
-double gslextras_cdf_hypergeometric_P (const unsigned int k,
-                                       const unsigned int n0,
-                                       const unsigned int n1,
-                                       const unsigned int t);
-double gslextras_cdf_hypergeometric_Q (const unsigned int k,
-                                       const unsigned int n0,
-                                       const unsigned int n1,
-                                       const unsigned int t);
-double gslextras_cdf_negative_binomial_P(const long n,
-                                         const long k, const double p);
-double gslextras_cdf_negative_binomial_Q(const long n, const long k,
-                                         const double p);
-double gslextras_cdf_poisson_P (const long k, const double lambda);
-double gslextras_cdf_poisson_Q (const long k, const double lambda);
-
-#endif /* gsl-extras.h */
diff --git a/lib/gsl-extras/hypergeometric.c b/lib/gsl-extras/hypergeometric.c
deleted file mode 100644 (file)
index 67b757b..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* cdf/hypergeometric.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/*
- * Computes the cumulative distribution function for a hypergeometric
- * random variable. A hypergeometric random variable X is the number
- * of elements of type 0 in a sample of size t, drawn from a population
- * of size n1 + n0, in which n1 are of type 1 and n0 are of type 0.
- *
- * This algorithm computes Pr( X <= k ) by summing the terms from
- * the mass function, Pr( X = k ).
- *
- * References:
- *
- * T. Wu. An accurate computation of the hypergeometric distribution
- * function. ACM Transactions on Mathematical Software. Volume 19, number 1,
- * March 1993.
- *  This algorithm is not used, since it requires factoring the
- *  numerator and denominator, then cancelling. It is more accurate
- *  than the algorithm used here, but the cancellation requires more
- *  time than the algorithm used here.
- *
- * W. Feller. An Introduction to Probability Theory and Its Applications,
- * third edition. 1968. Chapter 2, section 6.
- */
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_cdf.h>
-#include <gsl/gsl_randist.h>
-#include "gsl-extras.h"
-
-/*
- * Pr (X <= k)
- */
-double
-gslextras_cdf_hypergeometric_P (const unsigned int k,
-                                const unsigned int n0,
-                                const unsigned int n1,
-                                const unsigned int t)
-{
-  unsigned int i;
-  unsigned int mode;
-  double P;
-  double tmp;
-  double relerr;
-
-  if( t > (n0+n1))
-    {
-      GSLEXTRAS_CDF_ERROR("t larger than population size",GSL_EDOM);
-    }
-  else if( k >= n0 || k >= t)
-    {
-      P = 1.0;
-    }
-  else if (k < 0.0)
-    {
-      P = 0.0;
-    }
-  else
-    {
-      P = 0.0;
-      mode = (int) t*n0 / (n0+n1);
-      relerr = 1.0;
-      if( k < mode )
-       {
-         i = k;
-         relerr = 1.0;
-         while(i != UINT_MAX && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i--;
-           }
-       }
-      else
-       {
-         i = mode;
-         relerr = 1.0;
-         while(i <= k && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i++;
-           }
-         i = mode - 1;
-         relerr = 1.0;
-         while( i != UINT_MAX && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i--;
-           }
-       }
-      /*
-       * Hack to get rid of a pesky error when the sum
-       * gets slightly above 1.0.
-       */
-      P = GSL_MIN_DBL (P, 1.0);
-    }
-  return P;
-}
-
-/*
- * Pr (X > k)
- */
-double
-gslextras_cdf_hypergeometric_Q (const unsigned int k,
-                                const unsigned int n0,
-                                const unsigned int n1,
-                                const unsigned int t)
-{
-  unsigned int i;
-  unsigned int mode;
-  double P;
-  double relerr;
-  double tmp;
-
-  if( t > (n0+n1))
-    {
-      GSLEXTRAS_CDF_ERROR("t larger than population size",GSL_EDOM);
-    }
-  else if( k >= n0 || k >= t)
-    {
-      P = 0.0;
-    }
-  else if (k < 0.0)
-    {
-      P = 1.0;
-    }
-  else
-    {
-      P = 0.0;
-      mode = (int) t*n0 / (n0+n1);
-      relerr = 1.0;
-
-      if(k < mode)
-       {
-         i = mode;
-         while( i <= t && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i++;
-           }
-         i = mode - 1;
-         relerr = 1.0;
-         while ( i > k && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i--;
-           }
-       }
-      else
-       {
-         i = k+1;
-         while(i <= t && relerr > GSL_DBL_EPSILON && P < 1.0)
-           {
-             tmp = gsl_ran_hypergeometric_pdf(i, n0, n1, t);
-             P += tmp;
-             relerr = tmp / P;
-             i++;
-           }
-       }
-      /*
-       * Hack to get rid of a pesky error when the sum
-       * gets slightly above 1.0.
-       */
-      P = GSL_MIN_DBL(P, 1.0);
-    }
-  return P;
-}
diff --git a/lib/gsl-extras/negbinom.c b/lib/gsl-extras/negbinom.c
deleted file mode 100644 (file)
index b991f73..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* cdf/negbinom.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_cdf.h>
-#include "gsl-extras.h"
-
-/*
- * Pr(X <= n) for a negative binomial random variable X, i.e.,
- * the probability of n or fewer failuers before success k.
- */
-double
-gslextras_cdf_negative_binomial_P(const long n, const long k, const double p)
-{
-  double P;
-  double a;
-  double b;
-
-  if(p > 1.0 || p < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if ( k < 0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("k < 0",GSL_EDOM);
-    }
-  if ( n < 0 )
-    {
-      P = 0.0;
-    }
-  else
-    {
-      a = (double) k;
-      b = (double) n+1;
-      P = gsl_cdf_beta_P(p, a, b);
-    }
-
-  return P;
-}
-/*
- * Pr ( X > n ).
- */
-double
-gslextras_cdf_negative_binomial_Q(const long n, const long k, const double p)
-{
-  double P;
-  double a;
-  double b;
-
-  if(p > 1.0 || p < 0.0)
-    {
-      GSLEXTRAS_CDF_ERROR("p < 0 or p > 1",GSL_EDOM);
-    }
-  if ( k < 0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("k < 0",GSL_EDOM);
-    }
-  if ( n < 0 )
-    {
-      P = 1.0;
-    }
-  else
-    {
-      a = (double) k;
-      b = (double) n+1;
-      P = gsl_cdf_beta_Q(p, a, b);
-    }
-
-  return P;
-}
-
diff --git a/lib/gsl-extras/poisson.c b/lib/gsl-extras/poisson.c
deleted file mode 100644 (file)
index 3ce2bf5..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* cdf/poisson.c
- *
- * Copyright (C) 2004 Free Software Foundation, Inc.
- * 
- *
- * 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 (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
- * 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/*
- * Computes the cumulative distribution function for a Poisson
- * random variable. For a Poisson random variable X with parameter
- * lambda,
- *
- *          Pr( X <= k ) = Pr( Y >= p )
- *
- * where Y is a gamma random variable with parameters k+1 and 1.
- *
- * Reference:
- *
- * W. Feller, "An Introduction to Probability and Its
- * Applications," volume 1. Wiley, 1968. Exercise 46, page 173,
- * chapter 6.
- */
-#include <math.h>
-#include <gsl/gsl_math.h>
-#include <gsl/gsl_errno.h>
-#include <gsl/gsl_cdf.h>
-#include "gsl-extras.h"
-
-/*
- * Pr (X <= k) for a Poisson random variable X.
- */
-double
-gslextras_cdf_poisson_P (const long k, const double lambda)
-{
-  double P;
-  double a;
-
-  if ( lambda <= 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("lambda <= 0", GSL_EDOM);
-    }
-  if ( k < 0 )
-    {
-      P = 0.0;
-    }
-  else
-    {
-      a = (double) k+1;
-      P = gsl_cdf_gamma_Q ( lambda, a, 1.0);
-    }
-  return P;
-}
-
-/*
- * Pr ( X > k ) for a Possion random variable X.
- */
-double
-gslextras_cdf_poisson_Q (const long k, const double lambda)
-{
-  double P;
-  double a;
-
-  if ( lambda <= 0.0 )
-    {
-      GSLEXTRAS_CDF_ERROR ("lambda <= 0", GSL_EDOM);
-    }
-  if ( k < 0 )
-    {
-      P = 1.0;
-    }
-  else
-    {
-      a = (double) k+1;
-      P = gsl_cdf_gamma_P ( lambda, a, 1.0);
-    }
-  return P;
-}
-
diff --git a/lib/gtksheet/ChangeLog b/lib/gtksheet/ChangeLog
deleted file mode 100644 (file)
index b5ba1c8..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-2008-05-08  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6506.  Reviewed by John Darrington.
-
-       * gtksheet.c (gtk_sheet_unrealize): Don't call gtk_widget_unparent
-       on sheet->button if it's null.
-
-2008-05-06  Ben Pfaff  <blp@gnu.org>
-
-       * gtksheet.c (gtk_sheet_dispose): Set the sheet's entry_container
-       and button members to NULL after unref'ing them, so that a later
-       call to gtk_sheet_for_all will not try to dereference a dangling
-       pointer.
-
-2008-03-06 John Darrington <john@darrington.wattle.id.au>
-
-       * gsheet-row-iface.c gsheet-row-iface.h: Delete unused, unneccesary
-       gpointer variable from the interface.
-
-       * gtksheet.c: Update to match new gsheet-row-iface
-
-2008-02-27 John Darrington <john@darrington.wattle.id.au>
-       * gtksheet.c gtksheet.h: Corrected some leaks and other problems
-       related to de-allocating the sheet.
-
-2008-02-27 John Darrington <john@darrington.wattle.id.au>
-       * gtksheet.c: (gtk_sheet_expose) Don't queue a redraw on the entry
-       widget.  Fixes bug #21073
-
-2008-02-20 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h: Removed some unused signals.
-       Made the models properties of the widget.
-
-2008-02-08 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c: Removed the sheet_locked feature, which we never
-       used, and interfered with the editability of the entry widget.
-
-       * gtksheet.c: Add one to the row to which we scroll. Seems like
-       the best way to cope with granularity problems.
-       
-21 Septempber 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c (range_update_callback): Scroll to cell 0,0 if the
-       current position is outside the model's range.
-
-24 July 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h: Removed the `clip' feature, which IMO 
-       is a croc, and we're unlikely to use.  In its place, added a primary 
-       selection which supports text and html targets.
-
-16 July 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h: Removed some legacy functions called from 
-       gtk_sheet_finalize which caused unnecessary delays when shutting down.
-
-12 July 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h: Removed view member and replaced with 
-        function call.  Removed hadjustment_changed and vadjustment_changed 
-        functions which did nothing.  Added some whitespace arount != 
-        operators.
-
-09 July 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h (gtk_sheet_get_active_cell): Allowed row,
-       column  to be NULL.
-
-07 July 2007 John Darrington <john@darrington.wattle.id.au>
-        
-       * gsheet-column-iface.c gsheet-column-iface.h gsheet-row-iface.c
-       gsheet-row-iface.h gtksheet.c gtksheet.h: Added a "subtitle"
-       feature on row/column titles, which shows tooltip-like popups.  
-
-03 July 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * gtksheet.c gtksheet.h: Removed the autoscroll-on-select feature 
-       that was causing us grief.
-
-28 June 2007 John Darrington <john@darrington.wattle.id.au>
-
-        * gtksheet.c: Removed some features that we dont use, to get better 
-       speed.
-
-Sat Feb 17 17:36:56 2007  Ben Pfaff  <blp@gnu.org>
-
-       * gsheet-column-iface.c gsheet-hetero-column.c gsheet-row-iface.c
-       gsheet-uniform-column.c gsheet-uniform-row.c gsheetmodel.c
-       gtkextra-marshal.c gtkextra.c gtkiconlist.c gtkitementry.c
-       gtksheet.c: Add "#include <config.h>".
-
-Mon Jun 19 18:03:21 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * gsheet-column-iface.c gsheet-column-iface.h
-       gsheet-hetero-column.c gsheet-row-iface.c gsheet-row-iface.h
-       gsheet-uniform-column.c gsheet-uniform-row.c gtksheet.c
-       gtksheet.h:  Fixed some warnings.  Corrected errors updating
-               row/column titles
-       
-Di Mai 30 19:51:19 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gtksheet.c gtksheet.h: constness. Removed dependence on glib2.10
-
-Sat May 27 16:29:36 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gtksheet.c: Removed call to gtk_entry_set_text, which caused warnings 
-       and was unnecessary.
-
-Thu May 25 17:58:51 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gsheet-column-iface.c gsheet-column-iface.h gsheet-hetero-column.c
-    gsheet-row-iface.c gsheet-row-iface.h gsheet-uniform-row.c
-    gtksheet-extra.h gtksheet.c:  Plugged memory leaks.  Rationalised the way
-    that GtkSheetButtons are created.
-
-Sat May 20 21:02:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gsheetmodel.c gsheetmodel.h: Added columns-inserted and columns-deleted 
-    signals.  Added g_sheet_get_{row,column}_count functions.
-
-    * gtksheet.c gtksheet.h: Allowed -1 to be passed to
-    gtk_sheet_set_active_cell to indicate no active cell.
-
-Mon May 15 16:10:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gtksheet.c: Removed code which rendered the title buttons a second 
-    time.  Cut and Paste error ?
-
-Sat May 13 07:58:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-        * gsheetmodel.c gsheetmodel.h gtksheet.c gtksheeet.h: Added
-       free_strings flag to tell the sheet whether to free the string
-       data passed from the model.
-
-Thu May 11 22:20:04 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gtksheet.c, gtksheet.h: Fixed broken deallocation of sheet->pixmap.
-
-Thu May  4 17:55:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * gtksheet.c: Added callback on inserted rows.
-
-Sat Jan 28 08:48:08 2006 UTC John Darrington <john@darrington.wattle.id.au>
-
-    * Separated the data out of the GtkSheet.  The gtksheet should now be
-    regarded as a way of looking into the data.  The data is represented by a
-    GSheetModel and the rows and columns by  GSheetRow and GSheetColumn.
diff --git a/lib/gtksheet/OChangeLog b/lib/gtksheet/OChangeLog
new file mode 100644 (file)
index 0000000..b5ba1c8
--- /dev/null
@@ -0,0 +1,149 @@
+2008-05-08  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6506.  Reviewed by John Darrington.
+
+       * gtksheet.c (gtk_sheet_unrealize): Don't call gtk_widget_unparent
+       on sheet->button if it's null.
+
+2008-05-06  Ben Pfaff  <blp@gnu.org>
+
+       * gtksheet.c (gtk_sheet_dispose): Set the sheet's entry_container
+       and button members to NULL after unref'ing them, so that a later
+       call to gtk_sheet_for_all will not try to dereference a dangling
+       pointer.
+
+2008-03-06 John Darrington <john@darrington.wattle.id.au>
+
+       * gsheet-row-iface.c gsheet-row-iface.h: Delete unused, unneccesary
+       gpointer variable from the interface.
+
+       * gtksheet.c: Update to match new gsheet-row-iface
+
+2008-02-27 John Darrington <john@darrington.wattle.id.au>
+       * gtksheet.c gtksheet.h: Corrected some leaks and other problems
+       related to de-allocating the sheet.
+
+2008-02-27 John Darrington <john@darrington.wattle.id.au>
+       * gtksheet.c: (gtk_sheet_expose) Don't queue a redraw on the entry
+       widget.  Fixes bug #21073
+
+2008-02-20 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h: Removed some unused signals.
+       Made the models properties of the widget.
+
+2008-02-08 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c: Removed the sheet_locked feature, which we never
+       used, and interfered with the editability of the entry widget.
+
+       * gtksheet.c: Add one to the row to which we scroll. Seems like
+       the best way to cope with granularity problems.
+       
+21 Septempber 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c (range_update_callback): Scroll to cell 0,0 if the
+       current position is outside the model's range.
+
+24 July 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h: Removed the `clip' feature, which IMO 
+       is a croc, and we're unlikely to use.  In its place, added a primary 
+       selection which supports text and html targets.
+
+16 July 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h: Removed some legacy functions called from 
+       gtk_sheet_finalize which caused unnecessary delays when shutting down.
+
+12 July 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h: Removed view member and replaced with 
+        function call.  Removed hadjustment_changed and vadjustment_changed 
+        functions which did nothing.  Added some whitespace arount != 
+        operators.
+
+09 July 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h (gtk_sheet_get_active_cell): Allowed row,
+       column  to be NULL.
+
+07 July 2007 John Darrington <john@darrington.wattle.id.au>
+        
+       * gsheet-column-iface.c gsheet-column-iface.h gsheet-row-iface.c
+       gsheet-row-iface.h gtksheet.c gtksheet.h: Added a "subtitle"
+       feature on row/column titles, which shows tooltip-like popups.  
+
+03 July 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * gtksheet.c gtksheet.h: Removed the autoscroll-on-select feature 
+       that was causing us grief.
+
+28 June 2007 John Darrington <john@darrington.wattle.id.au>
+
+        * gtksheet.c: Removed some features that we dont use, to get better 
+       speed.
+
+Sat Feb 17 17:36:56 2007  Ben Pfaff  <blp@gnu.org>
+
+       * gsheet-column-iface.c gsheet-hetero-column.c gsheet-row-iface.c
+       gsheet-uniform-column.c gsheet-uniform-row.c gsheetmodel.c
+       gtkextra-marshal.c gtkextra.c gtkiconlist.c gtkitementry.c
+       gtksheet.c: Add "#include <config.h>".
+
+Mon Jun 19 18:03:21 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * gsheet-column-iface.c gsheet-column-iface.h
+       gsheet-hetero-column.c gsheet-row-iface.c gsheet-row-iface.h
+       gsheet-uniform-column.c gsheet-uniform-row.c gtksheet.c
+       gtksheet.h:  Fixed some warnings.  Corrected errors updating
+               row/column titles
+       
+Di Mai 30 19:51:19 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gtksheet.c gtksheet.h: constness. Removed dependence on glib2.10
+
+Sat May 27 16:29:36 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gtksheet.c: Removed call to gtk_entry_set_text, which caused warnings 
+       and was unnecessary.
+
+Thu May 25 17:58:51 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gsheet-column-iface.c gsheet-column-iface.h gsheet-hetero-column.c
+    gsheet-row-iface.c gsheet-row-iface.h gsheet-uniform-row.c
+    gtksheet-extra.h gtksheet.c:  Plugged memory leaks.  Rationalised the way
+    that GtkSheetButtons are created.
+
+Sat May 20 21:02:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gsheetmodel.c gsheetmodel.h: Added columns-inserted and columns-deleted 
+    signals.  Added g_sheet_get_{row,column}_count functions.
+
+    * gtksheet.c gtksheet.h: Allowed -1 to be passed to
+    gtk_sheet_set_active_cell to indicate no active cell.
+
+Mon May 15 16:10:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gtksheet.c: Removed code which rendered the title buttons a second 
+    time.  Cut and Paste error ?
+
+Sat May 13 07:58:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+        * gsheetmodel.c gsheetmodel.h gtksheet.c gtksheeet.h: Added
+       free_strings flag to tell the sheet whether to free the string
+       data passed from the model.
+
+Thu May 11 22:20:04 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gtksheet.c, gtksheet.h: Fixed broken deallocation of sheet->pixmap.
+
+Thu May  4 17:55:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * gtksheet.c: Added callback on inserted rows.
+
+Sat Jan 28 08:48:08 2006 UTC John Darrington <john@darrington.wattle.id.au>
+
+    * Separated the data out of the GtkSheet.  The gtksheet should now be
+    regarded as a way of looking into the data.  The data is represented by a
+    GSheetModel and the rows and columns by  GSheetRow and GSheetColumn.
index 0cf17095ebfa0234979ff5af439877e5e5e3af18..c5a32962add28a2e9494e3c611a0f9dcb2d1db0f 100644 (file)
@@ -31,3 +31,6 @@ lib_gtksheet_libgtksheet_a_SOURCES = \
        lib/gtksheet/gtksheet.h \
        lib/gtksheet/gtkxpaned.c \
        lib/gtksheet/gtkxpaned.h
+
+EXTRA_DIST += lib/gtksheet/OChangeLog \
+       lib/gtksheet/README
diff --git a/lib/linreg/ChangeLog b/lib/linreg/ChangeLog
deleted file mode 100644 (file)
index 48fcf31..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Sun Jan 9 00:57        2006    Jason Stover <jason@sakla.net>
-
-       * pspp_linreg.h: Altered the coefficient structure to include
-       variable/value pairs.
-       
-       * coefficient.c: Added functions to handle the matching between
-       model coefficients and their corresponding variables and values.
-
-       * linreg.c: (pspp_linreg_cache_free) Added pspp_linreg_coeff_free ()
-       to free coefficient structures.
-       
-Sun Oct 23 13:46:56 2005  Ben Pfaff  <blp@gnu.org>
-
-       * linreg.c: (pspp_linreg) Removed unused variable `mse'.
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/lib/linreg/OChangeLog b/lib/linreg/OChangeLog
new file mode 100644 (file)
index 0000000..48fcf31
--- /dev/null
@@ -0,0 +1,20 @@
+Sun Jan 9 00:57        2006    Jason Stover <jason@sakla.net>
+
+       * pspp_linreg.h: Altered the coefficient structure to include
+       variable/value pairs.
+       
+       * coefficient.c: Added functions to handle the matching between
+       model coefficients and their corresponding variables and values.
+
+       * linreg.c: (pspp_linreg_cache_free) Added pspp_linreg_coeff_free ()
+       to free coefficient structures.
+       
+Sun Oct 23 13:46:56 2005  Ben Pfaff  <blp@gnu.org>
+
+       * linreg.c: (pspp_linreg) Removed unused variable `mse'.
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index d65df864a762fd15b826427be31529a753b834a6..30fd2e592d4c48fd674a27dbcadaa60f10275e97 100644 (file)
@@ -1,6 +1,8 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
-noinst_LIBRARIES += lib/linreg/liblinreg.a
+noinst_LTLIBRARIES += lib/linreg/liblinreg.la
 
-lib_linreg_liblinreg_a_SOURCES = \
+lib_linreg_liblinreg_la_SOURCES = \
        lib/linreg/sweep.c  lib/linreg/sweep.h 
+
+EXTRA_DIST += lib/linreg/OChangeLog
diff --git a/lib/misc/README b/lib/misc/README
new file mode 100644 (file)
index 0000000..68ba91a
--- /dev/null
@@ -0,0 +1,2 @@
+This is not part of the GNU PSPP program, but is used with GNU PSPP.
+
diff --git a/lib/misc/automake.mk b/lib/misc/automake.mk
new file mode 100644 (file)
index 0000000..3b4f1a9
--- /dev/null
@@ -0,0 +1,8 @@
+## Process this file with automake to produce Makefile.in  -*- makefile -*-
+
+noinst_LTLIBRARIES += lib/misc/libmisc.la
+
+lib_misc_libmisc_la_SOURCES = \
+       lib/misc/wx-mp-sr.c  lib/misc/wx-mp-sr.h 
+
+EXTRA_DIST += lib/misc/README
diff --git a/lib/misc/wx-mp-sr.c b/lib/misc/wx-mp-sr.c
new file mode 100644 (file)
index 0000000..39e83b9
--- /dev/null
@@ -0,0 +1,101 @@
+#include <config.h>
+#include "wx-mp-sr.h"
+
+/*********************************************************************
+* 
+* Calculate the exact level of significance for a 
+* Wilcoxon Matched-Pair Signed-Ranks Test using the sample's
+* Sum of Ranks W and the sample size (i.e., number of pairs) N.
+* This whole routine can be run as a stand-alone program.
+*
+* Use: 
+* WX-MP-SR W N
+*
+* Copyright 1996, Rob van Son
+*
+* 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
+* (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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* -------------------------------------------------------
+*                 Rob van Son
+* Institute of Phonetic Sciences & IFOTT 
+* University of Amsterdam, Spuistraat 210 
+* NL-1012VT Amsterdam, The Netherlands
+* Tel.: (+31) 205252196        Fax.: (+31) 205252197
+* Email: r.j.j.h.vanson@uva.nl
+* WWW page: http://www.fon.hum.uva.nl/rob
+* -------------------------------------------------------
+*
+* This is the actual routine that calculates the exact (two-tailed)
+* level of significance for the Wilcoxon Matched-Pairs Signed-Ranks
+* test. The inputs are the Sum of Ranks of either the positive of 
+* negative samples (W) and the sample size (N).
+* The Level of significance is calculated by checking for each
+* possible outcome (2**N possibilities) whether the sum of ranks
+* is larger than or equal to the observed Sum of Ranks (W).
+*
+* NOTE: The execution-time scales like ~ N*2**N, i.e., N*pow(2, N), 
+* which is more than exponential. Adding a single pair to the sample 
+* (i.e., increase N by 1) will more than double the time needed to 
+* complete the calculations (apart from an additive constant).
+* The execution-time of this program can easily outrun your 
+* patience.
+*
+***********************************************************************/ 
+
+double LevelOfSignificanceWXMPSR(double Winput, long int N)
+{
+  unsigned long int W, MaximalW, NumberOfPossibilities, CountLarger;
+  unsigned long int i, RankSum, j;
+  double p;
+
+  /* Determine Wmax, i.e., work with the largest Rank Sum */
+  MaximalW = N*(N+1)/2;
+  if(Winput < MaximalW/2)Winput = MaximalW - Winput;
+  W = Winput;    /* Convert to long int */
+  if(W != Winput)++W;  /* Increase to next full integer */
+  
+  /* The total number of possible outcomes is 2**N  */
+  NumberOfPossibilities = 1 << N;
+  
+  /* Initialize and loop. The loop-interior will be run 2**N times. */
+  CountLarger = 0;
+  /* Generate all distributions of sign over ranks as bit-patterns (i). */
+  for(i=0; i < NumberOfPossibilities; ++i)
+  { 
+    RankSum = 0;
+    /* 
+       Shift "sign" bits out of i to determine the Sum of Ranks (j). 
+    */
+    for(j=0; j < N; ++j)
+    { 
+      if((i >> j) & 1)RankSum += j + 1;  
+    };
+    /*
+    * Count the number of "samples" that have a Sum of Ranks larger than 
+    * or equal to the one found (i.e., >= W).
+    */
+    if(RankSum >= W)++CountLarger;
+  };
+  /*****************************************************************
+  * The level of significance is the number of outcomes with a
+  * sum of ranks equal to or larger than the one found (W) 
+  * divided by the total number of possible outcomes. 
+  * The level is doubled to get the two-tailed result.
+  ******************************************************************/
+  p = 2*((double)CountLarger) / ((double)NumberOfPossibilities);
+
+  return p;
+}
+
diff --git a/lib/misc/wx-mp-sr.h b/lib/misc/wx-mp-sr.h
new file mode 100644 (file)
index 0000000..ec3ef5e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef WX_MP_SR
+#define WX_MP_SR 1
+
+double LevelOfSignificanceWXMPSR(double Winput, long int N);
+
+#endif
index 70767a9029d3e059e2fdc4fb6c6ca5884ca9ea73..c602e83ff841b1e699d6642af98cfcaf19cb0479 100644 (file)
@@ -1,14 +1,13 @@
 # British translations for PSPP
-# Copyright (C) 2007 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 # This file is distributed under the same licence as the PSPP package.
-# John Darrington <john@darrington.wattle.id.au>, 2007.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: PSPP 0.4.3\n"
+"Project-Id-Version: PSPP 0.7.0\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2008-07-12 14:17+0800\n"
-"PO-Revision-Date: 2007-09-15 08:29+0800\n"
+"POT-Creation-Date: 2008-11-11 13:13+0900\n"
+"PO-Revision-Date: 2008-11-05 08:17+0900\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
 "MIME-Version: 1.0\n"
@@ -101,7 +100,7 @@ msgstr ""
 
 #: src/data/data-in.c:338
 msgid "Unrecognized character in field."
-msgstr ""
+msgstr "Unrecognised character in field."
 
 #: src/data/data-in.c:362 src/data/data-in.c:636
 msgid "Field must have even length."
@@ -129,6 +128,8 @@ msgid ""
 "Unrecognized month format.  Months may be specified as Arabic or Roman "
 "numerals or as at least 3 letters of their English names."
 msgstr ""
+"Unrecognised month format.  Months may be specified as Arabic or Roman \n"
+"numerals or as at least 3 letters of their English names."
 
 #: src/data/data-in.c:850
 #, c-format
@@ -173,6 +174,8 @@ msgid ""
 "Unrecognized weekday name.  At least the first two letters of an English "
 "weekday name must be specified."
 msgstr ""
+"Unrecognised weekday name.  At least the first two letters of an English "
+"weekday name must be specified."
 
 #: src/data/data-in.c:1138
 #, c-format
@@ -194,12 +197,12 @@ msgstr ""
 msgid "%s field) "
 msgstr ""
 
-#: src/data/data-out.c:447
+#: src/data/data-out.c:446
 #, c-format
 msgid "Weekday number %f is not between 1 and 7."
 msgstr ""
 
-#: src/data/data-out.c:468
+#: src/data/data-out.c:467
 #, c-format
 msgid "Month number %f is not between 1 and 12."
 msgstr ""
@@ -216,13 +219,13 @@ msgstr ""
 msgid "scratch"
 msgstr ""
 
-#: src/data/dictionary.c:882
+#: src/data/dictionary.c:889
 msgid ""
 "At least one case in the data file had a weight value that was user-missing, "
 "system-missing, zero, or negative.  These case(s) were ignored."
 msgstr ""
 
-#: src/data/dictionary.c:1180
+#: src/data/dictionary.c:1187
 #, c-format
 msgid "Truncating document line to %d bytes."
 msgstr ""
@@ -319,33 +322,33 @@ msgstr[1] ""
 msgid "%s variables are not compatible with %s format %s."
 msgstr ""
 
-#: src/data/format.c:327 src/data/sys-file-reader.c:639
-#: src/ui/gui/data-editor.glade:1190 src/ui/gui/psppire.glade:2176
+#: src/data/format.c:327 src/data/sys-file-reader.c:655
+#: src/ui/gui/data-editor.glade:1197 src/ui/gui/psppire.glade:2176
 #: src/ui/gui/psppire-var-store.c:605
 msgid "String"
 msgstr ""
 
-#: src/data/format.c:327 src/data/sys-file-reader.c:639
-#: src/ui/gui/data-editor.glade:1079 src/ui/gui/psppire.glade:2131
+#: src/data/format.c:327 src/data/sys-file-reader.c:655
+#: src/ui/gui/data-editor.glade:1086 src/ui/gui/psppire.glade:2131
 #: src/ui/gui/psppire-var-store.c:598
 msgid "Numeric"
 msgstr ""
 
-#: src/data/format.c:328 src/data/sys-file-reader.c:1145
-#: src/data/sys-file-reader.c:1147
+#: src/data/format.c:328 src/data/sys-file-reader.c:1160
+#: src/data/sys-file-reader.c:1162
 #: src/language/dictionary/apply-dictionary.c:78
 #: src/language/dictionary/apply-dictionary.c:79
-#: src/language/xforms/recode.c:472 src/language/xforms/recode.c:473
-#: src/language/xforms/recode.c:485 src/language/xforms/recode.c:486
+#: src/language/xforms/recode.c:489 src/language/xforms/recode.c:490
+#: src/language/xforms/recode.c:502 src/language/xforms/recode.c:503
 msgid "numeric"
 msgstr ""
 
-#: src/data/format.c:328 src/data/sys-file-reader.c:1145
-#: src/data/sys-file-reader.c:1147
+#: src/data/format.c:328 src/data/sys-file-reader.c:1160
+#: src/data/sys-file-reader.c:1162
 #: src/language/dictionary/apply-dictionary.c:78
 #: src/language/dictionary/apply-dictionary.c:79
-#: src/language/xforms/recode.c:472 src/language/xforms/recode.c:473
-#: src/language/xforms/recode.c:485 src/language/xforms/recode.c:486
+#: src/language/xforms/recode.c:489 src/language/xforms/recode.c:490
+#: src/language/xforms/recode.c:502 src/language/xforms/recode.c:503
 msgid "string"
 msgstr ""
 
@@ -445,7 +448,7 @@ msgstr ""
 
 #. TRANSLATORS: this fragment will be interpolated into
 #. messages in fh_lock() that identify types of files.
-#: src/data/por-file-reader.c:268 src/data/por-file-writer.c:149
+#: src/data/por-file-reader.c:268 src/data/por-file-writer.c:148
 msgid "portable file"
 msgstr ""
 
@@ -484,7 +487,7 @@ msgstr ""
 #: src/data/por-file-reader.c:519
 #, c-format
 msgid "Unrecognized version code `%c'."
-msgstr ""
+msgstr "Unrecognised version code `%c'."
 
 #: src/data/por-file-reader.c:528
 #, c-format
@@ -572,17 +575,17 @@ msgid ""
 "Cannot assign value labels to %s and %s, which have different variable types."
 msgstr ""
 
-#: src/data/por-file-writer.c:141
+#: src/data/por-file-writer.c:140
 #, c-format
 msgid "Invalid decimal digits count %d.  Treating as %d."
 msgstr ""
 
-#: src/data/por-file-writer.c:161
+#: src/data/por-file-writer.c:160
 #, c-format
 msgid "Error opening \"%s\" for writing as a portable file: %s."
 msgstr ""
 
-#: src/data/por-file-writer.c:500
+#: src/data/por-file-writer.c:499
 #, c-format
 msgid "An I/O error occurred writing portable file \"%s\"."
 msgstr ""
@@ -639,7 +642,7 @@ msgstr ""
 msgid "scratch file"
 msgstr ""
 
-#: src/data/settings.c:685
+#: src/data/settings.c:687
 #, c-format
 msgid ""
 "%s: Custom currency string `%s' does not contain exactly three periods or "
@@ -652,352 +655,364 @@ msgstr ""
 
 #. TRANSLATORS: this fragment will be interpolated into
 #. messages in fh_lock() that identify types of files.
-#: src/data/sys-file-reader.c:198 src/data/sys-file-writer.c:190
+#: src/data/sys-file-reader.c:214 src/data/sys-file-writer.c:196
 msgid "system file"
 msgstr ""
 
-#: src/data/sys-file-reader.c:205
+#: src/data/sys-file-reader.c:221
 #, c-format
 msgid "Error opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:244
+#: src/data/sys-file-reader.c:260
 msgid "Misplaced type 4 record."
 msgstr ""
 
-#: src/data/sys-file-reader.c:255
+#: src/data/sys-file-reader.c:271
 #, c-format
 msgid "Unrecognized record type %d."
-msgstr ""
+msgstr "Unrecognised record type %d."
 
-#: src/data/sys-file-reader.c:294
+#: src/data/sys-file-reader.c:310
 #, c-format
 msgid "File header claims %d variable positions but %d were read from file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:334
+#: src/data/sys-file-reader.c:350
 #, c-format
 msgid "Error closing system file \"%s\": %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:399 src/data/sys-file-reader.c:409
+#: src/data/sys-file-reader.c:415 src/data/sys-file-reader.c:425
 msgid "This is not an SPSS system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:428
+#: src/data/sys-file-reader.c:444
 msgid ""
 "Compression bias is not the usual value of 100, or system file uses "
 "unrecognized floating-point format."
 msgstr ""
+"Compression bias is not the usual value of 100, or system file uses \n"
+"unrecognised floating-point format."
 
-#: src/data/sys-file-reader.c:496
+#: src/data/sys-file-reader.c:512
 #, c-format
 msgid "Invalid variable name `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:500
+#: src/data/sys-file-reader.c:516
 #, c-format
 msgid "Bad variable width %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:504
+#: src/data/sys-file-reader.c:520
 #, c-format
 msgid "Duplicate variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:512
+#: src/data/sys-file-reader.c:528
 msgid "Variable label indicator field is not 0 or 1."
 msgstr ""
 
-#: src/data/sys-file-reader.c:520
+#: src/data/sys-file-reader.c:536
 #, c-format
 msgid "Variable %s has label of invalid length %zu."
 msgstr ""
 
-#: src/data/sys-file-reader.c:539
+#: src/data/sys-file-reader.c:555
 msgid "Numeric missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
-#: src/data/sys-file-reader.c:554
+#: src/data/sys-file-reader.c:570
 msgid "String missing value indicator field is not 0, 1, 2, or 3."
 msgstr ""
 
-#: src/data/sys-file-reader.c:557
+#: src/data/sys-file-reader.c:573
 #, c-format
 msgid ""
 "Ignoring missing values on long string variable %s, which PSPP does not yet "
 "support."
 msgstr ""
 
-#: src/data/sys-file-reader.c:586
+#: src/data/sys-file-reader.c:602
 msgid "Missing string continuation record."
 msgstr ""
 
-#: src/data/sys-file-reader.c:620
+#: src/data/sys-file-reader.c:636
 #, c-format
 msgid "Unknown variable format %<PRIu8>."
 msgstr ""
 
-#: src/data/sys-file-reader.c:638
+#: src/data/sys-file-reader.c:654
 #, c-format
 msgid "%s variable %s has invalid %s format %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:641
+#: src/data/sys-file-reader.c:657
 msgid "print"
 msgstr ""
 
-#: src/data/sys-file-reader.c:641
+#: src/data/sys-file-reader.c:657
 msgid "write"
 msgstr ""
 
-#: src/data/sys-file-reader.c:645
+#: src/data/sys-file-reader.c:661
 msgid "Suppressing further invalid format warnings."
 msgstr ""
 
-#: src/data/sys-file-reader.c:663
+#: src/data/sys-file-reader.c:679
 msgid "Weighting variable must be numeric."
 msgstr ""
 
-#: src/data/sys-file-reader.c:677
+#: src/data/sys-file-reader.c:693
 msgid "Multiple type 6 (document) records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:681
+#: src/data/sys-file-reader.c:697
 #, c-format
 msgid "Number of document lines (%d) must be greater than 0."
 msgstr ""
 
-#: src/data/sys-file-reader.c:689
+#: src/data/sys-file-reader.c:705
 msgid "Document line contains null byte."
 msgstr ""
 
-#: src/data/sys-file-reader.c:763
+#: src/data/sys-file-reader.c:782
 msgid ""
 "Ignoring value labels for long string variables, which PSPP does not yet "
 "support."
 msgstr ""
 
-#: src/data/sys-file-reader.c:768
+#: src/data/sys-file-reader.c:787
 #, c-format
 msgid "Unrecognized record type 7, subtype %d."
-msgstr ""
+msgstr "Unrecognised record type 7, subtype %d."
 
-#: src/data/sys-file-reader.c:793
+#: src/data/sys-file-reader.c:812
 #, c-format
 msgid "Bad size (%zu) or count (%zu) field on record type 7, subtype 3."
 msgstr ""
 
-#: src/data/sys-file-reader.c:813
+#: src/data/sys-file-reader.c:832
 #, c-format
 msgid ""
 "Floating-point representation indicated by system file (%d) differs from "
 "expected (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:826
+#: src/data/sys-file-reader.c:845
 msgid "little-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:826
+#: src/data/sys-file-reader.c:845
 msgid "big-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:827
+#: src/data/sys-file-reader.c:846
 #, c-format
 msgid ""
 "Integer format indicated by system file (%s) differs from expected (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:843
+#: src/data/sys-file-reader.c:862
 #, c-format
 msgid "Bad size (%zu) or count (%zu) on extension 4."
 msgstr ""
 
-#: src/data/sys-file-reader.c:847
+#: src/data/sys-file-reader.c:866
 #, c-format
 msgid "File specifies unexpected value %g as SYSMIS."
 msgstr ""
 
-#: src/data/sys-file-reader.c:849
+#: src/data/sys-file-reader.c:868
 #, c-format
 msgid "File specifies unexpected value %g as HIGHEST."
 msgstr ""
 
-#: src/data/sys-file-reader.c:851
+#: src/data/sys-file-reader.c:870
 #, c-format
 msgid "File specifies unexpected value %g as LOWEST."
 msgstr ""
 
-#: src/data/sys-file-reader.c:867
+#: src/data/sys-file-reader.c:886
 #, c-format
 msgid "Bad size %zu on extension 11."
 msgstr ""
 
-#: src/data/sys-file-reader.c:879
+#: src/data/sys-file-reader.c:898
 #, c-format
 msgid "Extension 11 has bad count %zu (for %zu variables)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:900
+#: src/data/sys-file-reader.c:919
 #, c-format
 msgid ""
 "Invalid variable display parameters for variable %zu (%s).  Default "
 "parameters substituted."
 msgstr ""
 
-#: src/data/sys-file-reader.c:946
+#: src/data/sys-file-reader.c:963
 #, c-format
 msgid "Long variable mapping from %s to invalid variable name `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:956
+#: src/data/sys-file-reader.c:973
 #, c-format
 msgid "Duplicate long variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1011
+#: src/data/sys-file-reader.c:1026
 #, c-format
 msgid "%s listed as string of invalid length %s in very length string record."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1021
+#: src/data/sys-file-reader.c:1036
 #, c-format
 msgid ""
 "%s listed in very long string record with width %s, which requires only one "
 "segment."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1027
+#: src/data/sys-file-reader.c:1042
 #, c-format
 msgid "Very long string %s overflows dictionary."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1041
+#: src/data/sys-file-reader.c:1056
 #, c-format
 msgid ""
 "Very long string with width %ld has segment %d of width %d (expected %d)"
 msgstr ""
 
-#: src/data/sys-file-reader.c:1086
+#: src/data/sys-file-reader.c:1101
 #, c-format
 msgid "Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1117
+#: src/data/sys-file-reader.c:1132
 msgid ""
 "Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1124
+#: src/data/sys-file-reader.c:1139
 #, c-format
 msgid ""
 "Number of variables associated with a value label (%d) is not between 1 and "
 "the number of variables (%zu)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1134
+#: src/data/sys-file-reader.c:1149
 #, c-format
 msgid "Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1141
+#: src/data/sys-file-reader.c:1156
 #, c-format
 msgid ""
 "Variables associated with value label are not all of identical type.  "
 "Variable %s is %s, but variable %s is %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1174
+#: src/data/sys-file-reader.c:1189
 #, c-format
 msgid "Duplicate value label for %g on %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1177
+#: src/data/sys-file-reader.c:1192
 #, c-format
 msgid "Duplicate value label for \"%.*s\" on %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1255
+#: src/data/sys-file-reader.c:1230
+#, c-format
+msgid "Error parsing attribute value %s[%d]"
+msgstr ""
+
+#: src/data/sys-file-reader.c:1244
+#, c-format
+msgid "Attribute value %s[%d] is not quoted: %s"
+msgstr ""
+
+#: src/data/sys-file-reader.c:1360
 msgid "File ends in partial case."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1263
+#: src/data/sys-file-reader.c:1368
 #, c-format
 msgid "Error reading case from file %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1360 src/data/sys-file-reader.c:1396
+#: src/data/sys-file-reader.c:1465 src/data/sys-file-reader.c:1501
 msgid "Compressed data is corrupt."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1483
+#: src/data/sys-file-reader.c:1588
 #, c-format
 msgid "Variable index %d not in valid range 1...%d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1488
+#: src/data/sys-file-reader.c:1593
 #, c-format
 msgid "Variable index %d refers to long string continuation."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1574
+#: src/data/sys-file-reader.c:1661
 #, c-format
-msgid "Suppressed %d additional variable map warnings."
+msgid "Suppressed %d additional related warnings."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1587
+#: src/data/sys-file-reader.c:1702
 #, c-format
 msgid "Variable map refers to unknown variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1663
+#: src/data/sys-file-reader.c:1810
 #, c-format
 msgid "System error: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1665
+#: src/data/sys-file-reader.c:1812
 msgid "Unexpected end of file."
 msgstr ""
 
-#: src/data/sys-file-writer.c:163
+#: src/data/sys-file-writer.c:169
 #, c-format
 msgid "Unknown system file version %d. Treating as version %d."
 msgstr ""
 
-#: src/data/sys-file-writer.c:202
+#: src/data/sys-file-writer.c:208
 #, c-format
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-writer.c:737
+#: src/data/sys-file-writer.c:813
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
 
-#: src/data/variable.c:209
+#: src/data/variable.c:236
 #, c-format
 msgid ""
 "Character `%c' (in %s) may not appear as the first character in a variable "
 "name."
 msgstr ""
 
-#: src/data/variable.c:221
+#: src/data/variable.c:248
 #, c-format
 msgid "Character `%c' (in %s) may not appear in a variable name."
 msgstr ""
 
-#: src/data/variable.c:249
+#: src/data/variable.c:276
 msgid "Variable name cannot be empty string."
 msgstr ""
 
-#: src/data/variable.c:255
+#: src/data/variable.c:282
 #, c-format
 msgid "Variable name %s exceeds %d-character limit."
 msgstr ""
 
-#: src/data/variable.c:263
+#: src/data/variable.c:290
 #, c-format
 msgid "`%s' may not be used as a variable name because it is a reserved word."
 msgstr ""
@@ -1154,7 +1169,7 @@ msgstr ""
 msgid "This command may not follow ELSE in DO IF...END IF."
 msgstr ""
 
-#: src/language/control/loop.c:216
+#: src/language/control/loop.c:214
 msgid "Only one index clause may be specified."
 msgstr ""
 
@@ -1222,23 +1237,23 @@ msgstr ""
 msgid "At least one variable must be specified."
 msgstr ""
 
-#: src/language/data-io/data-list.c:348 src/language/data-io/data-list.c:437
+#: src/language/data-io/data-list.c:349 src/language/data-io/data-list.c:438
 #: src/language/data-io/get-data.c:528
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
-#: src/language/data-io/data-list.c:355
+#: src/language/data-io/data-list.c:356
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
-#: src/language/data-io/data-list.c:362
+#: src/language/data-io/data-list.c:363
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
-#: src/language/data-io/data-list.c:370
+#: src/language/data-io/data-list.c:371
 #, c-format
 msgid "Cannot place variable %s on record %d when RECORDS=%d is specified."
 msgstr ""
@@ -1272,9 +1287,9 @@ msgstr ""
 #: src/language/data-io/data-parser.c:641
 #: src/language/data-io/data-parser.c:682 src/language/data-io/print.c:403
 #: src/language/dictionary/split-file.c:84
-#: src/language/dictionary/sys-file-info.c:161
-#: src/language/dictionary/sys-file-info.c:390
-#: src/language/dictionary/sys-file-info.c:634
+#: src/language/dictionary/sys-file-info.c:162
+#: src/language/dictionary/sys-file-info.c:386
+#: src/language/dictionary/sys-file-info.c:709
 #: src/language/stats/descriptives.c:883 src/ui/gui/dict-display.c:245
 msgid "Variable"
 msgstr ""
@@ -1317,57 +1332,57 @@ msgstr ""
 msgid "Could not open \"%s\" for reading as a data file: %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:190
+#: src/language/data-io/data-reader.c:191
 msgid ""
 "Unexpected end-of-file while reading data in BEGIN DATA.  This probably "
 "indicates a missing or misformatted END DATA command.  END DATA must appear "
 "by itself on a single line with exactly one space between words."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:215
+#: src/language/data-io/data-reader.c:216
 #, c-format
 msgid "Error reading file %s: %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:218
+#: src/language/data-io/data-reader.c:219
 #, c-format
 msgid "Unexpected end of file reading %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:227
+#: src/language/data-io/data-reader.c:228
 #, c-format
 msgid "Unexpected end of file in partial record reading %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:287
+#: src/language/data-io/data-reader.c:288
 #, c-format
 msgid "Corrupt block descriptor word at offset 0x%lx in %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:288
+#: src/language/data-io/data-reader.c:289
 #, c-format
 msgid "Corrupt record descriptor word at offset 0x%lx in %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:301
+#: src/language/data-io/data-reader.c:302
 #, c-format
 msgid "Corrupt record size at offset 0x%lx in %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:443
+#: src/language/data-io/data-reader.c:444
 msgid "Record exceeds remaining block length."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:517
+#: src/language/data-io/data-reader.c:518
 #, c-format
 msgid "Attempt to read beyond end-of-file on file %s."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:520
+#: src/language/data-io/data-reader.c:521
 msgid "Attempt to read beyond END DATA."
 msgstr ""
 
-#: src/language/data-io/data-reader.c:706
+#: src/language/data-io/data-reader.c:707
 msgid ""
 "This command is not valid here since the current input program does not "
 "access the inline file."
@@ -1456,6 +1471,9 @@ msgid ""
 "variables on right side (%zu), in parenthesized group %d of RENAME "
 "subcommand."
 msgstr ""
+"Number of variables on left side of `=' (%zu) does not match number of \n"
+"variables on right side (%zu), in parenthesised group %d of RENAME \n"
+"subcommand."
 
 #: src/language/data-io/get.c:585
 #, c-format
@@ -1573,19 +1591,19 @@ msgid ""
 "specified on FIXCASE, %d."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:130
+#: src/language/data-io/inpt-pgm.c:129
 msgid "Unexpected end-of-file within INPUT PROGRAM."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:143
+#: src/language/data-io/inpt-pgm.c:142
 msgid "Input program did not create any variables."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:288
+#: src/language/data-io/inpt-pgm.c:287
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:338
+#: src/language/data-io/inpt-pgm.c:337
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
@@ -1681,7 +1699,7 @@ msgid_plural "Writing %d records."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/language/data-io/print-space.c:73 src/language/lexer/lexer.c:476
+#: src/language/data-io/print-space.c:73 src/language/lexer/lexer.c:477
 #: src/language/stats/autorecode.c:154 src/language/xforms/select-if.c:60
 msgid "expecting end of command"
 msgstr ""
@@ -1711,10 +1729,18 @@ msgid ""
 "Cannot apply missing values from source file to long string variable %s."
 msgstr ""
 
-#: src/language/dictionary/apply-dictionary.c:126
+#: src/language/dictionary/apply-dictionary.c:129
 msgid "No matching variables found between the source and target files."
 msgstr ""
 
+#: src/language/dictionary/attributes.c:108
+msgid "Attribute array index must be between 1 and 65535."
+msgstr ""
+
+#: src/language/dictionary/attributes.c:189
+msgid "expecting ATTRIBUTE= or DELETE="
+msgstr ""
+
 #: src/language/dictionary/delete-variables.c:40
 msgid ""
 "DELETE VARIABLES may not be used after TEMPORARY.  Temporary transformations "
@@ -1736,7 +1762,7 @@ msgid "`)' expected after output format."
 msgstr ""
 
 #: src/language/dictionary/missing-values.c:56
-#: src/language/stats/aggregate.c:451
+#: src/language/stats/aggregate.c:461
 msgid "expecting `('"
 msgstr ""
 
@@ -1820,7 +1846,7 @@ msgstr ""
 #: src/language/dictionary/modify-variables.c:302
 #, c-format
 msgid "Unrecognized subcommand name `%s'."
-msgstr ""
+msgstr "Unrecognised subcommand name `%s'."
 
 #: src/language/dictionary/modify-variables.c:304
 msgid "Subcommand name expected."
@@ -1869,233 +1895,239 @@ msgid "Renaming would duplicate variable name %s."
 msgstr ""
 
 #: src/language/dictionary/split-file.c:85
-#: src/language/dictionary/sys-file-info.c:563
+#: src/language/dictionary/sys-file-info.c:480
+#: src/language/dictionary/sys-file-info.c:629
 #: src/language/stats/crosstabs.q:1155 src/language/stats/crosstabs.q:1182
 #: src/language/stats/crosstabs.q:1202 src/language/stats/crosstabs.q:1224
-#: src/language/stats/examine.q:1198 src/language/stats/frequencies.q:1060
-#: src/language/stats/frequencies.q:1184
+#: src/language/stats/examine.q:1948 src/language/stats/frequencies.q:1055
+#: src/language/stats/frequencies.q:1179 src/language/stats/reliability.q:572
+#: src/language/stats/reliability.q:583
 msgid "Value"
 msgstr ""
 
 #: src/language/dictionary/split-file.c:86
-#: src/language/dictionary/sys-file-info.c:397
-#: src/language/dictionary/sys-file-info.c:564 src/ui/gui/crosstabs.glade:275
+#: src/language/dictionary/sys-file-info.c:390
+#: src/language/dictionary/sys-file-info.c:630 src/ui/gui/crosstabs.glade:275
 #: src/ui/gui/psppire.glade:2099 src/ui/gui/psppire-var-sheet.c:104
 msgid "Label"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:110
+#: src/language/dictionary/sys-file-info.c:113
 msgid "File:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:112 src/ui/gui/psppire.glade:2052
+#: src/language/dictionary/sys-file-info.c:115 src/ui/gui/psppire.glade:2052
 #: src/ui/gui/recode.glade:841
 msgid "Label:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:116
+#: src/language/dictionary/sys-file-info.c:119
 msgid "No label."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:119
+#: src/language/dictionary/sys-file-info.c:122
 msgid "Created:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:122
+#: src/language/dictionary/sys-file-info.c:125
 msgid "Integer Format:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:124
+#: src/language/dictionary/sys-file-info.c:127
 msgid "Big Endian."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:125
+#: src/language/dictionary/sys-file-info.c:128
 msgid "Little Endian."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:126
-#: src/language/dictionary/sys-file-info.c:134
+#: src/language/dictionary/sys-file-info.c:129
+#: src/language/dictionary/sys-file-info.c:137
 msgid "Unknown."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:127
+#: src/language/dictionary/sys-file-info.c:130
 msgid "Real Format:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:129
+#: src/language/dictionary/sys-file-info.c:132
 msgid "IEEE 754 LE."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:130
+#: src/language/dictionary/sys-file-info.c:133
 msgid "IEEE 754 BE."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:131
+#: src/language/dictionary/sys-file-info.c:134
 msgid "VAX D."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:132
+#: src/language/dictionary/sys-file-info.c:135
 msgid "VAX G."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:133
+#: src/language/dictionary/sys-file-info.c:136
 msgid "IBM 390 Hex Long."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:135
+#: src/language/dictionary/sys-file-info.c:138
 #: src/ui/gui/descriptives-dialog.glade:79 src/ui/gui/recode.glade:940
 msgid "Variables:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:137
+#: src/language/dictionary/sys-file-info.c:140
 msgid "Cases:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:139
+#: src/language/dictionary/sys-file-info.c:142
 msgid "Unknown"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:141
+#: src/language/dictionary/sys-file-info.c:144
 msgid "Type:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:142
+#: src/language/dictionary/sys-file-info.c:145
 msgid "System File."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:143
+#: src/language/dictionary/sys-file-info.c:146
 msgid "Weight:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:148
+#: src/language/dictionary/sys-file-info.c:151
 msgid "Not weighted."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:150
+#: src/language/dictionary/sys-file-info.c:153
 msgid "Mode:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:152
+#: src/language/dictionary/sys-file-info.c:155
 #, c-format
 msgid "Compression %s."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:152
+#: src/language/dictionary/sys-file-info.c:155
 msgid "on"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:152
+#: src/language/dictionary/sys-file-info.c:155
 msgid "off"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:162
-#: src/language/dictionary/sys-file-info.c:395
+#: src/language/dictionary/sys-file-info.c:163
+#: src/language/dictionary/sys-file-info.c:390
 msgid "Description"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:163
-#: src/language/dictionary/sys-file-info.c:393
-#: src/language/dictionary/sys-file-info.c:633
+#: src/language/dictionary/sys-file-info.c:164
+#: src/language/dictionary/sys-file-info.c:392
+#: src/language/dictionary/sys-file-info.c:708
 msgid "Position"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:222
+#: src/language/dictionary/sys-file-info.c:213
 msgid "The active file does not have a file label."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:225
+#: src/language/dictionary/sys-file-info.c:216
 msgid "File label:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:288
+#: src/language/dictionary/sys-file-info.c:291
 msgid "No variables to display."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:307
+#: src/language/dictionary/sys-file-info.c:306
 msgid "Macros not supported."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:317
+#: src/language/dictionary/sys-file-info.c:316
 msgid "The active file dictionary does not contain any documents."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:325
+#: src/language/dictionary/sys-file-info.c:324
 msgid "Documents in the active file:"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:477
+#: src/language/dictionary/sys-file-info.c:479
+msgid "Attribute"
+msgstr ""
+
+#: src/language/dictionary/sys-file-info.c:537
 #, c-format
 msgid "Format: %s"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:485
+#: src/language/dictionary/sys-file-info.c:544
 #, c-format
 msgid "Print Format: %s"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:488
+#: src/language/dictionary/sys-file-info.c:547
 #, c-format
 msgid "Write Format: %s"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:494
+#: src/language/dictionary/sys-file-info.c:559
 #, c-format
 msgid "Measure: %s"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:495
+#: src/language/dictionary/sys-file-info.c:560
 #: src/ui/gui/psppire-var-sheet.c:123
 msgid "Nominal"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:496
+#: src/language/dictionary/sys-file-info.c:561
 #: src/ui/gui/psppire-var-sheet.c:124
 msgid "Ordinal"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:497
+#: src/language/dictionary/sys-file-info.c:562
 #: src/ui/gui/psppire-var-sheet.c:125
 msgid "Scale"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:500
+#: src/language/dictionary/sys-file-info.c:565
 #, c-format
 msgid "Display Alignment: %s"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:501
+#: src/language/dictionary/sys-file-info.c:566
 #: src/ui/gui/psppire-var-sheet.c:116
 msgid "Left"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:502
+#: src/language/dictionary/sys-file-info.c:567
 #: src/ui/gui/psppire-var-sheet.c:118
 msgid "Center"
 msgstr "Centre"
 
-#: src/language/dictionary/sys-file-info.c:503
+#: src/language/dictionary/sys-file-info.c:568
 #: src/ui/gui/psppire-var-sheet.c:117
 msgid "Right"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:506
+#: src/language/dictionary/sys-file-info.c:571
 #, c-format
 msgid "Display Width: %d"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:517
+#: src/language/dictionary/sys-file-info.c:583
 msgid "Missing Values: "
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:611
+#: src/language/dictionary/sys-file-info.c:686
 msgid "No vectors defined."
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:632
+#: src/language/dictionary/sys-file-info.c:707
 msgid "Vector"
 msgstr ""
 
-#: src/language/dictionary/sys-file-info.c:635
+#: src/language/dictionary/sys-file-info.c:710
 msgid "Print Format"
 msgstr ""
 
@@ -2106,20 +2138,15 @@ msgid ""
 "s."
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:629
+#: src/language/dictionary/value-labels.c:157 src/language/lexer/lexer.c:630
 msgid "expecting string"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:643
-msgid "expecting integer"
-msgstr ""
-
-#: src/language/dictionary/value-labels.c:170
-#, c-format
-msgid "Value label `%g' is not integer."
+#: src/language/dictionary/value-labels.c:166 src/language/lexer/lexer.c:657
+msgid "expecting number"
 msgstr ""
 
-#: src/language/dictionary/value-labels.c:184
+#: src/language/dictionary/value-labels.c:182
 msgid "Truncating value label to 60 characters."
 msgstr ""
 
@@ -2175,11 +2202,11 @@ msgstr ""
 msgid "The weighting variable may not be scratch."
 msgstr ""
 
-#: src/language/expressions/evaluate.c:155
+#: src/language/expressions/evaluate.c:154
 msgid "expecting number or string"
 msgstr ""
 
-#: src/language/expressions/evaluate.c:169
+#: src/language/expressions/evaluate.c:168
 #, c-format
 msgid "Duplicate variable name %s."
 msgstr ""
@@ -2226,6 +2253,10 @@ msgid ""
 "Unrecognized date unit \"%.*s\".  Valid date units are \"years\", \"quarters"
 "\", \"months\", \"weeks\", \"days\", \"hours\", \"minutes\", and \"seconds\"."
 msgstr ""
+"Unrecognised date unit \"%.*s\".  Valid date units are \"years\", \"quarters"
+"\"\n"
+"\"\", \"months\", \"weeks\", \"days\", \"hours\", \"minutes\", and \"seconds"
+"\"."
 
 #: src/language/expressions/helpers.c:332
 msgid ""
@@ -2274,7 +2305,7 @@ msgstr ""
 msgid "Unknown identifier %s."
 msgstr ""
 
-#: src/language/expressions/parse.c:885 src/language/stats/aggregate.c:509
+#: src/language/expressions/parse.c:885 src/language/stats/aggregate.c:519
 msgid "expecting `)'"
 msgstr ""
 
@@ -2342,8 +2373,7 @@ msgstr ""
 msgid "%s is a PSPP extension."
 msgstr ""
 
-#: src/language/expressions/parse.c:1267 src/ui/terminal/command-line.c:127
-#: src/ui/terminal/command-line.c:146 src/ui/terminal/command-line.c:158
+#: src/language/expressions/parse.c:1267
 #, c-format
 msgid "%s is not yet implemented."
 msgstr ""
@@ -2366,84 +2396,84 @@ msgstr ""
 msgid "%s does not form a valid number."
 msgstr ""
 
-#: src/language/lexer/lexer.c:386
+#: src/language/lexer/lexer.c:387
 #, c-format
 msgid "Bad character in input: `%c'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:388
+#: src/language/lexer/lexer.c:389
 #, c-format
 msgid "Bad character in input: `\\%o'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:424
+#: src/language/lexer/lexer.c:425
 #, c-format
 msgid "Subcommand %s may only be specified once."
 msgstr ""
 
-#: src/language/lexer/lexer.c:432
+#: src/language/lexer/lexer.c:433
 #, c-format
 msgid "missing required subcommand %s"
 msgstr ""
 
-#: src/language/lexer/lexer.c:461
+#: src/language/lexer/lexer.c:462
 #, c-format
 msgid "Syntax error %s at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:464
+#: src/language/lexer/lexer.c:465
 #, c-format
 msgid "Syntax error at %s."
 msgstr ""
 
-#: src/language/lexer/lexer.c:598 src/language/lexer/lexer.c:615
+#: src/language/lexer/lexer.c:599 src/language/lexer/lexer.c:616
 #, c-format
 msgid "expecting `%s'"
 msgstr ""
 
-#: src/language/lexer/lexer.c:656
-msgid "expecting number"
+#: src/language/lexer/lexer.c:644
+msgid "expecting integer"
 msgstr ""
 
-#: src/language/lexer/lexer.c:668
+#: src/language/lexer/lexer.c:669
 msgid "expecting identifier"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1062
+#: src/language/lexer/lexer.c:1063
 msgid "binary"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1067
+#: src/language/lexer/lexer.c:1068
 msgid "octal"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1072
+#: src/language/lexer/lexer.c:1073
 msgid "hex"
 msgstr ""
 
-#: src/language/lexer/lexer.c:1082
+#: src/language/lexer/lexer.c:1083
 #, c-format
 msgid "String of %s digits has %zu characters, which is not a multiple of %d."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1111
+#: src/language/lexer/lexer.c:1112
 #, c-format
 msgid "`%c' is not a valid %s digit."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1145
+#: src/language/lexer/lexer.c:1146
 msgid "Unterminated string constant."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1199
+#: src/language/lexer/lexer.c:1200
 msgid "Unexpected end of file in string concatenation."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1207
+#: src/language/lexer/lexer.c:1208
 msgid "String expected following `+'."
 msgstr ""
 
-#: src/language/lexer/lexer.c:1220
+#: src/language/lexer/lexer.c:1221
 #, c-format
 msgid "String exceeds 255 characters in length (%zu characters)."
 msgstr ""
@@ -2546,54 +2576,54 @@ msgstr ""
 msgid "Bad bounds in use of TO convention."
 msgstr ""
 
-#: src/language/stats/aggregate.c:209
+#: src/language/stats/aggregate.c:218
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
-#: src/language/stats/aggregate.c:240
+#: src/language/stats/aggregate.c:249
 msgid "expecting BREAK"
 msgstr ""
 
-#: src/language/stats/aggregate.c:245
+#: src/language/stats/aggregate.c:254
 msgid ""
 "When PRESORTED is specified, specifying sorting directions with (A) or (D) "
 "has no effect.  Output data will be sorted the same way as the input data."
 msgstr ""
 
-#: src/language/stats/aggregate.c:416
+#: src/language/stats/aggregate.c:426
 msgid "expecting aggregation function"
 msgstr ""
 
-#: src/language/stats/aggregate.c:434
+#: src/language/stats/aggregate.c:444
 #, c-format
 msgid "Unknown aggregation function %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:490
+#: src/language/stats/aggregate.c:500
 #, c-format
 msgid "Missing argument %zu to %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:499
+#: src/language/stats/aggregate.c:509
 #, c-format
 msgid "Arguments to %s must be of same type as source variables."
 msgstr ""
 
-#: src/language/stats/aggregate.c:521
+#: src/language/stats/aggregate.c:531
 #, c-format
 msgid ""
 "Number of source variables (%zu) does not match number of target variables (%"
 "zu)."
 msgstr ""
 
-#: src/language/stats/aggregate.c:537
+#: src/language/stats/aggregate.c:547
 #, c-format
 msgid ""
 "The value arguments passed to the %s function are out-of-order.  They will "
 "be treated as if they had been specified in the correct order."
 msgstr ""
 
-#: src/language/stats/aggregate.c:607
+#: src/language/stats/aggregate.c:617
 #, c-format
 msgid ""
 "Variable name %s is not unique within the aggregate file dictionary, which "
@@ -2615,54 +2645,56 @@ msgstr ""
 msgid "Duplicate variable name %s among target variables."
 msgstr ""
 
-#: src/language/stats/binomial.c:133
+#: src/language/stats/binomial.c:132
 #, c-format
 msgid "Variable %s is not dichotomous"
 msgstr ""
 
-#: src/language/stats/binomial.c:178
+#: src/language/stats/binomial.c:179
 msgid "Binomial Test"
 msgstr ""
 
-#: src/language/stats/binomial.c:202
+#: src/language/stats/binomial.c:203
 msgid "Group1"
 msgstr ""
 
-#: src/language/stats/binomial.c:203
+#: src/language/stats/binomial.c:204
 msgid "Group2"
 msgstr ""
 
-#: src/language/stats/binomial.c:204 src/language/stats/chisquare.c:223
+#: src/language/stats/binomial.c:205 src/language/stats/chisquare.c:223
 #: src/language/stats/chisquare.c:283 src/language/stats/crosstabs.q:862
 #: src/language/stats/crosstabs.q:1062 src/language/stats/crosstabs.q:1785
-#: src/language/stats/examine.q:918 src/language/stats/frequencies.q:1137
-#: src/language/stats/oneway.q:306 src/language/stats/oneway.q:476
-#: src/language/stats/regression.q:309 src/ui/gui/crosstabs-dialog.c:59
+#: src/language/stats/examine.q:1207 src/language/stats/frequencies.q:1132
+#: src/language/stats/oneway.q:304 src/language/stats/oneway.q:470
+#: src/language/stats/regression.q:309 src/language/stats/reliability.q:705
+#: src/language/stats/wilcoxon.c:246 src/ui/gui/crosstabs-dialog.c:59
 msgid "Total"
 msgstr ""
 
-#: src/language/stats/binomial.c:236 src/language/stats/chisquare.c:246
+#: src/language/stats/binomial.c:237 src/language/stats/chisquare.c:246
 #: src/language/stats/crosstabs.q:1180 src/language/stats/crosstabs.q:1221
 msgid "Category"
 msgstr ""
 
-#: src/language/stats/binomial.c:237 src/language/stats/crosstabs.q:872
-#: src/language/stats/examine.q:993 src/language/stats/frequencies.q:1405
-#: src/language/stats/npar-summary.c:122 src/language/stats/oneway.q:391
-#: src/language/stats/t-test.q:693 src/language/stats/t-test.q:716
-#: src/language/stats/t-test.q:850 src/language/stats/t-test.q:1387
+#: src/language/stats/binomial.c:238 src/language/stats/crosstabs.q:872
+#: src/language/stats/examine.q:1280 src/language/stats/frequencies.q:1400
+#: src/language/stats/npar-summary.c:122 src/language/stats/oneway.q:386
+#: src/language/stats/reliability.q:708 src/language/stats/t-test.q:693
+#: src/language/stats/t-test.q:716 src/language/stats/t-test.q:850
+#: src/language/stats/t-test.q:1387 src/language/stats/wilcoxon.c:229
 msgid "N"
 msgstr ""
 
-#: src/language/stats/binomial.c:238
+#: src/language/stats/binomial.c:239
 msgid "Observed Prop."
 msgstr ""
 
-#: src/language/stats/binomial.c:239
+#: src/language/stats/binomial.c:240
 msgid "Test Prop."
 msgstr ""
 
-#: src/language/stats/binomial.c:242
+#: src/language/stats/binomial.c:243
 #, c-format
 msgid "Exact Sig. (%d-tailed)"
 msgstr ""
@@ -2691,7 +2723,7 @@ msgstr ""
 msgid "Frequencies"
 msgstr ""
 
-#: src/language/stats/chisquare.c:297
+#: src/language/stats/chisquare.c:297 src/language/stats/wilcoxon.c:297
 msgid "Test Statistics"
 msgstr ""
 
@@ -2700,7 +2732,7 @@ msgid "Chi-Square"
 msgstr ""
 
 #: src/language/stats/chisquare.c:312 src/language/stats/crosstabs.q:1156
-#: src/language/stats/oneway.q:279 src/language/stats/oneway.q:694
+#: src/language/stats/oneway.q:277 src/language/stats/oneway.q:683
 #: src/language/stats/regression.q:302 src/language/stats/t-test.q:1001
 #: src/language/stats/t-test.q:1193 src/language/stats/t-test.q:1286
 msgid "df"
@@ -2740,24 +2772,26 @@ msgstr ""
 msgid "Summary."
 msgstr ""
 
-#: src/language/stats/crosstabs.q:859 src/language/stats/examine.q:981
+#: src/language/stats/crosstabs.q:859 src/language/stats/examine.q:1268
+#: src/language/stats/reliability.q:696
 msgid "Cases"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:860 src/language/stats/examine.q:916
-#: src/language/stats/frequencies.q:1058 src/language/stats/frequencies.q:1406
+#: src/language/stats/crosstabs.q:860 src/language/stats/examine.q:1205
+#: src/language/stats/frequencies.q:1053 src/language/stats/frequencies.q:1401
+#: src/language/stats/reliability.q:699
 msgid "Valid"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:861 src/language/stats/examine.q:917
-#: src/language/stats/frequencies.q:1128 src/language/stats/frequencies.q:1407
+#: src/language/stats/crosstabs.q:861 src/language/stats/examine.q:1206
+#: src/language/stats/frequencies.q:1123 src/language/stats/frequencies.q:1402
 #: src/ui/gui/psppire-var-sheet.c:106
 msgid "Missing"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:873 src/language/stats/examine.q:996
-#: src/language/stats/frequencies.q:1062 src/language/stats/frequencies.q:1063
-#: src/language/stats/frequencies.q:1064
+#: src/language/stats/crosstabs.q:873 src/language/stats/examine.q:1283
+#: src/language/stats/frequencies.q:1057 src/language/stats/frequencies.q:1058
+#: src/language/stats/frequencies.q:1059
 msgid "Percent"
 msgstr ""
 
@@ -2799,7 +2833,7 @@ msgstr ""
 
 #: src/language/stats/crosstabs.q:1154 src/language/stats/crosstabs.q:1181
 #: src/language/stats/crosstabs.q:1201 src/language/stats/crosstabs.q:1222
-#: src/language/stats/examine.q:1442 src/ui/gui/checkbox-treeview.c:94
+#: src/language/stats/examine.q:1745 src/ui/gui/checkbox-treeview.c:94
 msgid "Statistic"
 msgstr ""
 
@@ -2859,139 +2893,139 @@ msgstr ""
 msgid "Type"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1977
+#: src/language/stats/crosstabs.q:1976
 msgid "Pearson Chi-Square"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1978
+#: src/language/stats/crosstabs.q:1977
 msgid "Likelihood Ratio"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1979
+#: src/language/stats/crosstabs.q:1978
 msgid "Fisher's Exact Test"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1980
+#: src/language/stats/crosstabs.q:1979
 msgid "Continuity Correction"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:1981
+#: src/language/stats/crosstabs.q:1980
 msgid "Linear-by-Linear Association"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2018 src/language/stats/crosstabs.q:2088
-#: src/language/stats/crosstabs.q:2147
+#: src/language/stats/crosstabs.q:2017 src/language/stats/crosstabs.q:2087
+#: src/language/stats/crosstabs.q:2146
 msgid "N of Valid Cases"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2034 src/language/stats/crosstabs.q:2163
+#: src/language/stats/crosstabs.q:2033 src/language/stats/crosstabs.q:2162
 msgid "Nominal by Nominal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2035 src/language/stats/crosstabs.q:2164
+#: src/language/stats/crosstabs.q:2034 src/language/stats/crosstabs.q:2163
 msgid "Ordinal by Ordinal"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2036
+#: src/language/stats/crosstabs.q:2035
 msgid "Interval by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2037
+#: src/language/stats/crosstabs.q:2036
 msgid "Measure of Agreement"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2042 src/ui/gui/crosstabs-dialog.c:41
+#: src/language/stats/crosstabs.q:2041 src/ui/gui/crosstabs-dialog.c:41
 msgid "Phi"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2043
+#: src/language/stats/crosstabs.q:2042
 msgid "Cramer's V"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2044
+#: src/language/stats/crosstabs.q:2043
 msgid "Contingency Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2045
+#: src/language/stats/crosstabs.q:2044
 msgid "Kendall's tau-b"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2046
+#: src/language/stats/crosstabs.q:2045
 msgid "Kendall's tau-c"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2047 src/ui/gui/crosstabs-dialog.c:48
+#: src/language/stats/crosstabs.q:2046 src/ui/gui/crosstabs-dialog.c:48
 msgid "Gamma"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2048
+#: src/language/stats/crosstabs.q:2047
 msgid "Spearman Correlation"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2049
+#: src/language/stats/crosstabs.q:2048
 msgid "Pearson's R"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2050 src/ui/gui/crosstabs-dialog.c:50
+#: src/language/stats/crosstabs.q:2049 src/ui/gui/crosstabs-dialog.c:50
 msgid "Kappa"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2120
+#: src/language/stats/crosstabs.q:2119
 #, c-format
 msgid "Odds Ratio for %s (%g / %g)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2123
+#: src/language/stats/crosstabs.q:2122
 #, c-format
 msgid "Odds Ratio for %s (%.*s / %.*s)"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2131
+#: src/language/stats/crosstabs.q:2130
 #, c-format
 msgid "For cohort %s = %g"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2134
+#: src/language/stats/crosstabs.q:2133
 #, c-format
 msgid "For cohort %s = %.*s"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2165
+#: src/language/stats/crosstabs.q:2164
 msgid "Nominal by Interval"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2170 src/ui/gui/crosstabs-dialog.c:43
+#: src/language/stats/crosstabs.q:2169 src/ui/gui/crosstabs-dialog.c:43
 msgid "Lambda"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2171
+#: src/language/stats/crosstabs.q:2170
 msgid "Goodman and Kruskal tau"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2172
+#: src/language/stats/crosstabs.q:2171
 msgid "Uncertainty Coefficient"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2173
+#: src/language/stats/crosstabs.q:2172
 msgid "Somers' d"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2174 src/ui/gui/crosstabs-dialog.c:51
+#: src/language/stats/crosstabs.q:2173 src/ui/gui/crosstabs-dialog.c:51
 msgid "Eta"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2179
+#: src/language/stats/crosstabs.q:2178
 msgid "Symmetric"
 msgstr ""
 
-#: src/language/stats/crosstabs.q:2180 src/language/stats/crosstabs.q:2181
+#: src/language/stats/crosstabs.q:2179 src/language/stats/crosstabs.q:2180
 #, c-format
 msgid "%s Dependent"
 msgstr ""
 
-#: src/language/stats/descriptives.c:102 src/language/stats/examine.q:1556
+#: src/language/stats/descriptives.c:102 src/language/stats/examine.q:1550
 #: src/language/stats/frequencies.q:123 src/language/stats/npar-summary.c:125
-#: src/language/stats/oneway.q:392 src/language/stats/t-test.q:694
+#: src/language/stats/oneway.q:387 src/language/stats/t-test.q:694
 #: src/language/stats/t-test.q:717 src/language/stats/t-test.q:849
 #: src/language/stats/t-test.q:1187 src/ui/gui/descriptives-dialog.c:39
 #: src/ui/gui/frequencies-dialog.c:40
@@ -3006,13 +3040,13 @@ msgstr ""
 msgid "Std Dev"
 msgstr ""
 
-#: src/language/stats/descriptives.c:105 src/language/stats/examine.q:1636
+#: src/language/stats/descriptives.c:105 src/language/stats/examine.q:1581
 #: src/language/stats/frequencies.q:128 src/ui/gui/descriptives-dialog.c:46
 #: src/ui/gui/frequencies-dialog.c:45
 msgid "Variance"
 msgstr ""
 
-#: src/language/stats/descriptives.c:106 src/language/stats/examine.q:1743
+#: src/language/stats/descriptives.c:106 src/language/stats/examine.q:1617
 #: src/language/stats/frequencies.q:129 src/ui/gui/descriptives-dialog.c:47
 #: src/ui/gui/frequencies-dialog.c:50
 msgid "Kurtosis"
@@ -3022,7 +3056,7 @@ msgstr ""
 msgid "S E Kurt"
 msgstr ""
 
-#: src/language/stats/descriptives.c:108 src/language/stats/examine.q:1723
+#: src/language/stats/descriptives.c:108 src/language/stats/examine.q:1612
 #: src/language/stats/frequencies.q:131 src/ui/gui/descriptives-dialog.c:48
 #: src/ui/gui/frequencies-dialog.c:46
 msgid "Skewness"
@@ -3032,22 +3066,22 @@ msgstr ""
 msgid "S E Skew"
 msgstr ""
 
-#: src/language/stats/descriptives.c:110 src/language/stats/examine.q:1684
+#: src/language/stats/descriptives.c:110 src/language/stats/examine.q:1601
 #: src/language/stats/frequencies.q:133 src/ui/gui/descriptives-dialog.c:43
 #: src/ui/gui/frequencies-dialog.c:48
 msgid "Range"
 msgstr ""
 
-#: src/language/stats/descriptives.c:111 src/language/stats/examine.q:1661
+#: src/language/stats/descriptives.c:111 src/language/stats/examine.q:1591
 #: src/language/stats/frequencies.q:134 src/language/stats/npar-summary.c:131
-#: src/language/stats/oneway.q:404 src/ui/gui/descriptives-dialog.c:41
+#: src/language/stats/oneway.q:400 src/ui/gui/descriptives-dialog.c:41
 #: src/ui/gui/frequencies-dialog.c:42
 msgid "Minimum"
 msgstr ""
 
-#: src/language/stats/descriptives.c:112 src/language/stats/examine.q:1672
+#: src/language/stats/descriptives.c:112 src/language/stats/examine.q:1596
 #: src/language/stats/frequencies.q:135 src/language/stats/npar-summary.c:134
-#: src/language/stats/oneway.q:405 src/ui/gui/descriptives-dialog.c:42
+#: src/language/stats/oneway.q:401 src/ui/gui/descriptives-dialog.c:42
 #: src/ui/gui/frequencies-dialog.c:43
 msgid "Maximum"
 msgstr ""
@@ -3102,119 +3136,132 @@ msgstr ""
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
 
-#: src/language/stats/examine.q:288 src/language/stats/examine.q:291
-#, c-format
-msgid "%s is not currently supported."
+#: src/language/stats/examine.q:337 src/language/stats/examine.q:490
+#: src/language/stats/examine.q:1047
+msgid "Not creating plot because data set is empty."
 msgstr ""
 
-#: src/language/stats/examine.q:501 src/language/stats/examine.q:514
+#: src/language/stats/examine.q:347
 #, c-format
-msgid "%s and %s are mutually exclusive"
+msgid "Normal Q-Q Plot of %s"
 msgstr ""
 
-#: src/language/stats/examine.q:976
-msgid "Case Processing Summary"
+#: src/language/stats/examine.q:348 src/language/stats/examine.q:353
+msgid "Observed Value"
 msgstr ""
 
-#: src/language/stats/examine.q:1183
-msgid "Extreme Values"
+#: src/language/stats/examine.q:349
+msgid "Expected Normal"
 msgstr ""
 
-#: src/language/stats/examine.q:1199
-msgid "Case Number"
+#: src/language/stats/examine.q:351
+#, c-format
+msgid "Detrended Normal Q-Q Plot of %s"
 msgstr ""
 
-#: src/language/stats/examine.q:1297
-msgid "Highest"
+#: src/language/stats/examine.q:354
+msgid "Dev from Normal"
 msgstr ""
 
-#: src/language/stats/examine.q:1302
-msgid "Lowest"
+#: src/language/stats/examine.q:507
+#, c-format
+msgid "Boxplot of %s vs. %s"
 msgstr ""
 
-#: src/language/stats/examine.q:1443 src/language/stats/oneway.q:394
-#: src/language/stats/oneway.q:692 src/language/stats/regression.q:203
-msgid "Std. Error"
+#: src/language/stats/examine.q:511
+#, c-format
+msgid "Boxplot of %s"
 msgstr ""
 
-#: src/language/stats/examine.q:1445 src/language/stats/oneway.q:408
-#: src/ui/gui/examine.glade:307
-msgid "Descriptives"
+#: src/language/stats/examine.q:747 src/language/stats/examine.q:760
+#, c-format
+msgid "%s and %s are mutually exclusive"
+msgstr ""
+
+#: src/language/stats/examine.q:1263 src/language/stats/reliability.q:673
+msgid "Case Processing Summary"
 msgstr ""
 
-#: src/language/stats/examine.q:1574 src/language/stats/oneway.q:399
+#: src/language/stats/examine.q:1555 src/language/stats/oneway.q:395
 #, c-format
 msgid "%g%% Confidence Interval for Mean"
 msgstr ""
 
-#: src/language/stats/examine.q:1580 src/language/stats/oneway.q:401
+#: src/language/stats/examine.q:1561 src/language/stats/oneway.q:397
 msgid "Lower Bound"
 msgstr ""
 
-#: src/language/stats/examine.q:1591 src/language/stats/oneway.q:402
+#: src/language/stats/examine.q:1566 src/language/stats/oneway.q:398
 msgid "Upper Bound"
 msgstr ""
 
-#: src/language/stats/examine.q:1603
+#: src/language/stats/examine.q:1571
 #, c-format
 msgid "5%% Trimmed Mean"
 msgstr ""
 
-#: src/language/stats/examine.q:1614 src/language/stats/frequencies.q:125
+#: src/language/stats/examine.q:1576 src/language/stats/frequencies.q:125
 #: src/ui/gui/frequencies-dialog.c:52
 msgid "Median"
 msgstr ""
 
-#: src/language/stats/examine.q:1648 src/language/stats/npar-summary.c:128
-#: src/language/stats/oneway.q:393 src/language/stats/t-test.q:695
+#: src/language/stats/examine.q:1586 src/language/stats/npar-summary.c:128
+#: src/language/stats/oneway.q:388 src/language/stats/t-test.q:695
 #: src/language/stats/t-test.q:718 src/language/stats/t-test.q:851
 #: src/language/stats/t-test.q:1188
 msgid "Std. Deviation"
 msgstr ""
 
-#: src/language/stats/examine.q:1696
+#: src/language/stats/examine.q:1606
 msgid "Interquartile Range"
 msgstr ""
 
-#: src/language/stats/examine.q:1850
-#, c-format
-msgid "Boxplot of %s vs. %s"
+#: src/language/stats/examine.q:1742 src/language/stats/oneway.q:404
+#: src/ui/gui/examine.glade:307
+msgid "Descriptives"
 msgstr ""
 
-#: src/language/stats/examine.q:1877
-msgid "Boxplot"
+#: src/language/stats/examine.q:1748 src/language/stats/oneway.q:389
+#: src/language/stats/oneway.q:681 src/language/stats/regression.q:203
+msgid "Std. Error"
 msgstr ""
 
-#: src/language/stats/examine.q:1919
+#: src/language/stats/examine.q:1845 src/language/stats/examine.q:1850
+#: src/ui/gui/psppire-var-store.c:675 src/ui/gui/psppire-var-store.c:685
+#: src/ui/gui/psppire-var-store.c:695
 #, c-format
-msgid "Normal Q-Q Plot of %s"
+msgid "%d"
 msgstr ""
 
-#: src/language/stats/examine.q:1920 src/language/stats/examine.q:1926
-msgid "Observed Value"
+#: src/language/stats/examine.q:1928
+msgid "Highest"
 msgstr ""
 
-#: src/language/stats/examine.q:1921
-msgid "Expected Normal"
+#: src/language/stats/examine.q:1933
+msgid "Lowest"
 msgstr ""
 
-#: src/language/stats/examine.q:1924
-#, c-format
-msgid "Detrended Normal Q-Q Plot of %s"
+#: src/language/stats/examine.q:1940
+msgid "Extreme Values"
 msgstr ""
 
-#: src/language/stats/examine.q:1927
-msgid "Dev from Normal"
+#: src/language/stats/examine.q:1944
+msgid "Case Number"
 msgstr ""
 
-#: src/language/stats/examine.q:2046 src/language/stats/examine.q:2068
-#: src/language/stats/frequencies.q:1417 src/language/stats/npar-summary.c:141
+#: src/language/stats/examine.q:2066
+msgid "Tukey's Hinges"
+msgstr ""
+
+#: src/language/stats/examine.q:2106 src/language/stats/examine.q:2124
+#: src/language/stats/frequencies.q:1412 src/language/stats/npar-summary.c:141
 #: src/ui/gui/examine.glade:328
 msgid "Percentiles"
 msgstr ""
 
-#: src/language/stats/examine.q:2204
-msgid "Tukey's Hinges"
+#: src/language/stats/examine.q:2113
+#, c-format
+msgid "%g"
 msgstr ""
 
 #: src/language/stats/flip.c:96
@@ -3317,64 +3364,60 @@ msgid ""
 "MIN was specified as %g and MAX as %g.  MIN and MAX will be ignored."
 msgstr ""
 
-#: src/language/stats/frequencies.q:759
+#: src/language/stats/frequencies.q:754
 #, c-format
 msgid "Variable %s specified multiple times on VARIABLES subcommand."
 msgstr ""
 
-#: src/language/stats/frequencies.q:822
+#: src/language/stats/frequencies.q:817
 msgid "`)' expected after GROUPED interval list."
 msgstr ""
 
-#: src/language/stats/frequencies.q:834
+#: src/language/stats/frequencies.q:829
 #, c-format
 msgid "Variables %s specified on GROUPED but not on VARIABLES."
 msgstr ""
 
-#: src/language/stats/frequencies.q:841
+#: src/language/stats/frequencies.q:836
 #, c-format
 msgid "Variables %s specified multiple times on GROUPED subcommand."
 msgstr ""
 
-#: src/language/stats/frequencies.q:1059 src/language/stats/frequencies.q:1152
-#: src/language/stats/frequencies.q:1153 src/language/stats/frequencies.q:1187
+#: src/language/stats/frequencies.q:1054 src/language/stats/frequencies.q:1147
+#: src/language/stats/frequencies.q:1148 src/language/stats/frequencies.q:1182
 msgid "Cum"
 msgstr ""
 
-#: src/language/stats/frequencies.q:1061 src/output/charts/plot-hist.c:126
+#: src/language/stats/frequencies.q:1056 src/output/charts/plot-hist.c:140
 msgid "Frequency"
 msgstr ""
 
-#: src/language/stats/frequencies.q:1082
+#: src/language/stats/frequencies.q:1077
 msgid "Value Label"
 msgstr ""
 
-#: src/language/stats/frequencies.q:1185
+#: src/language/stats/frequencies.q:1180
 msgid "Freq"
 msgstr ""
 
-#: src/language/stats/frequencies.q:1186 src/language/stats/frequencies.q:1188
+#: src/language/stats/frequencies.q:1181 src/language/stats/frequencies.q:1183
 msgid "Pct"
 msgstr ""
 
-#: src/language/stats/frequencies.q:1379
+#: src/language/stats/frequencies.q:1374
 #, c-format
 msgid "No valid data for variable %s; statistics not displayed."
 msgstr ""
 
-#: src/language/stats/frequencies.q:1421
+#: src/language/stats/frequencies.q:1416
 msgid "50 (Median)"
 msgstr ""
 
-#: src/language/stats/glm.q:147
+#: src/language/stats/glm.q:143
 msgid "Multivariate GLM not yet supported"
 msgstr ""
 
-#: src/language/stats/glm.q:271 src/language/stats/regression.q:931
-msgid "Dependent variable must be numeric."
-msgstr ""
-
-#: src/language/stats/glm.q:346 src/language/stats/regression.q:1026
+#: src/language/stats/glm.q:261 src/language/stats/regression.q:994
 msgid "No valid data found. This command was skipped."
 msgstr ""
 
@@ -3386,24 +3429,24 @@ msgstr ""
 msgid "TABLES subcommand may not appear more than once."
 msgstr ""
 
-#: src/language/stats/npar.q:98
+#: src/language/stats/npar.q:108
 msgid "NPAR subcommand not currently implemented."
 msgstr ""
 
-#: src/language/stats/npar.q:236
+#: src/language/stats/npar.q:251
 #, c-format
 msgid ""
 "The specified value of HI (%d) is lower than the specified value of LO (%d)"
 msgstr ""
 
-#: src/language/stats/npar.q:291
+#: src/language/stats/npar.q:306
 #, c-format
 msgid ""
 "%d expected values were given, but the specified range (%d-%d) requires "
 "exactly %d values."
 msgstr ""
 
-#: src/language/stats/npar.q:425 src/language/stats/t-test.q:496
+#: src/language/stats/npar.q:443 src/language/stats/t-test.q:496
 #, c-format
 msgid ""
 "PAIRED was specified but the number of variables preceding WITH (%zu) did "
@@ -3426,98 +3469,98 @@ msgstr ""
 msgid "75th"
 msgstr ""
 
-#: src/language/stats/oneway.q:169
+#: src/language/stats/oneway.q:170
 msgid "Number of contrast coefficients must equal the number of groups"
 msgstr ""
 
-#: src/language/stats/oneway.q:178
+#: src/language/stats/oneway.q:179
 #, c-format
 msgid "Coefficients for contrast %zu do not total zero"
 msgstr ""
 
-#: src/language/stats/oneway.q:244
+#: src/language/stats/oneway.q:242
 #, c-format
 msgid "`%s' is not a variable name"
 msgstr ""
 
-#: src/language/stats/oneway.q:278 src/language/stats/regression.q:301
+#: src/language/stats/oneway.q:276 src/language/stats/regression.q:301
 msgid "Sum of Squares"
 msgstr ""
 
-#: src/language/stats/oneway.q:280 src/language/stats/regression.q:303
+#: src/language/stats/oneway.q:278 src/language/stats/regression.q:303
 msgid "Mean Square"
 msgstr ""
 
-#: src/language/stats/oneway.q:281 src/language/stats/regression.q:304
+#: src/language/stats/oneway.q:279 src/language/stats/regression.q:304
 #: src/language/stats/t-test.q:998
 msgid "F"
 msgstr ""
 
-#: src/language/stats/oneway.q:282 src/language/stats/oneway.q:542
+#: src/language/stats/oneway.q:280 src/language/stats/oneway.q:532
 #: src/language/stats/regression.q:206 src/language/stats/regression.q:305
 msgid "Significance"
 msgstr ""
 
-#: src/language/stats/oneway.q:304
+#: src/language/stats/oneway.q:302
 msgid "Between Groups"
 msgstr ""
 
-#: src/language/stats/oneway.q:305
+#: src/language/stats/oneway.q:303
 msgid "Within Groups"
 msgstr ""
 
-#: src/language/stats/oneway.q:352 src/language/stats/regression.q:330
+#: src/language/stats/oneway.q:347 src/language/stats/regression.q:330
 msgid "ANOVA"
 msgstr ""
 
-#: src/language/stats/oneway.q:539
+#: src/language/stats/oneway.q:529
 msgid "Levene Statistic"
 msgstr ""
 
-#: src/language/stats/oneway.q:540
+#: src/language/stats/oneway.q:530
 msgid "df1"
 msgstr ""
 
-#: src/language/stats/oneway.q:541
+#: src/language/stats/oneway.q:531
 msgid "df2"
 msgstr ""
 
-#: src/language/stats/oneway.q:545
+#: src/language/stats/oneway.q:534
 msgid "Test of Homogeneity of Variances"
 msgstr ""
 
-#: src/language/stats/oneway.q:613
+#: src/language/stats/oneway.q:602
 msgid "Contrast Coefficients"
 msgstr ""
 
-#: src/language/stats/oneway.q:615 src/language/stats/oneway.q:690
+#: src/language/stats/oneway.q:604 src/language/stats/oneway.q:679
 msgid "Contrast"
 msgstr ""
 
-#: src/language/stats/oneway.q:688
+#: src/language/stats/oneway.q:677
 msgid "Contrast Tests"
 msgstr ""
 
-#: src/language/stats/oneway.q:691
+#: src/language/stats/oneway.q:680
 msgid "Value of Contrast"
 msgstr ""
 
-#: src/language/stats/oneway.q:693 src/language/stats/regression.q:205
+#: src/language/stats/oneway.q:682 src/language/stats/regression.q:205
 #: src/language/stats/t-test.q:1000 src/language/stats/t-test.q:1192
 #: src/language/stats/t-test.q:1285
 msgid "t"
 msgstr ""
 
-#: src/language/stats/oneway.q:695 src/language/stats/t-test.q:1002
+#: src/language/stats/oneway.q:684 src/language/stats/t-test.q:1002
 #: src/language/stats/t-test.q:1194 src/language/stats/t-test.q:1287
 msgid "Sig. (2-tailed)"
 msgstr ""
 
-#: src/language/stats/oneway.q:739
+#: src/language/stats/oneway.q:728
 msgid "Assume equal variances"
 msgstr ""
 
-#: src/language/stats/oneway.q:743
+#: src/language/stats/oneway.q:732
 msgid "Does not assume equal"
 msgstr ""
 
@@ -3633,6 +3676,87 @@ msgid ""
 "meaningless."
 msgstr ""
 
+#: src/language/stats/regression.q:898
+msgid "Dependent variable must be numeric."
+msgstr ""
+
+#: src/language/stats/reliability.q:429
+msgid "Reliability Statistics"
+msgstr ""
+
+#: src/language/stats/reliability.q:472
+msgid "Item-Total Statistics"
+msgstr ""
+
+#: src/language/stats/reliability.q:494
+msgid "Scale Mean if Item Deleted"
+msgstr ""
+
+#: src/language/stats/reliability.q:497
+msgid "Scale Variance if Item Deleted"
+msgstr ""
+
+#: src/language/stats/reliability.q:500
+msgid "Corrected Item-Total Correlation"
+msgstr ""
+
+#: src/language/stats/reliability.q:503
+msgid "Cronbach's Alpha if Item Deleted"
+msgstr ""
+
+#: src/language/stats/reliability.q:550 src/language/stats/reliability.q:566
+msgid "Cronbach's Alpha"
+msgstr ""
+
+#: src/language/stats/reliability.q:553
+msgid "N of items"
+msgstr ""
+
+#: src/language/stats/reliability.q:569
+msgid "Part 1"
+msgstr ""
+
+#: src/language/stats/reliability.q:575 src/language/stats/reliability.q:586
+msgid "N of Items"
+msgstr ""
+
+#: src/language/stats/reliability.q:580
+msgid "Part 2"
+msgstr ""
+
+#: src/language/stats/reliability.q:591
+msgid "Total N of Items"
+msgstr ""
+
+#: src/language/stats/reliability.q:594
+msgid "Correlation Between Forms"
+msgstr ""
+
+#: src/language/stats/reliability.q:598
+msgid "Spearman-Brown Coefficient"
+msgstr ""
+
+#: src/language/stats/reliability.q:601
+msgid "Equal Length"
+msgstr ""
+
+#: src/language/stats/reliability.q:604
+msgid "Unequal Length"
+msgstr ""
+
+#: src/language/stats/reliability.q:608
+msgid "Guttman Split-Half Coefficient"
+msgstr ""
+
+#: src/language/stats/reliability.q:702
+msgid "Excluded"
+msgstr ""
+
+#: src/language/stats/reliability.q:711
+#, c-format
+msgid "%%"
+msgstr ""
+
 #: src/language/stats/sort-cases.c:64
 msgid "Buffer limit must be at least 2."
 msgstr ""
@@ -3771,6 +3895,56 @@ msgstr ""
 msgid "%s & %s"
 msgstr ""
 
+#: src/language/stats/wilcoxon.c:216
+msgid "Ranks"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:230
+msgid "Mean Rank"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:231
+msgid "Sum of Ranks"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:243
+msgid "Negative Ranks"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:244
+msgid "Positive Ranks"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:245
+msgid "Ties"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:310
+msgid "Z"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:311
+msgid "Asymp. Sig (2-tailed)"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:315
+msgid "Exact Sig (2-tailed)"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:316
+msgid "Exact Sig (1-tailed)"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:319
+msgid "Point Probability"
+msgstr ""
+
+#: src/language/stats/wilcoxon.c:358
+#, c-format
+msgid ""
+"Exact significance was not calculated after %.2f minutes. Skipping test."
+msgstr ""
+
 #: src/language/syntax-file.c:88
 #, c-format
 msgid "opening \"%s\" as syntax file"
@@ -3842,28 +4016,28 @@ msgstr ""
 msgid "Only USE ALL is currently implemented."
 msgstr ""
 
-#: src/language/utilities/include.c:91
+#: src/language/utilities/include.c:90
 msgid "Expecting BATCH or INTERACTIVE after SYNTAX."
 msgstr ""
 
-#: src/language/utilities/include.c:108
+#: src/language/utilities/include.c:107
 msgid "Expecting YES or NO after CD."
 msgstr ""
 
-#: src/language/utilities/include.c:125
+#: src/language/utilities/include.c:124
 msgid "Expecting CONTINUE or STOP after ERROR."
 msgstr ""
 
-#: src/language/utilities/include.c:132
+#: src/language/utilities/include.c:131
 #, c-format
 msgid "Unexpected token: `%s'."
 msgstr ""
 
-#: src/language/utilities/include.c:177
+#: src/language/utilities/include.c:176
 msgid "expecting file name"
 msgstr ""
 
-#: src/language/utilities/include.c:189
+#: src/language/utilities/include.c:188
 #, c-format
 msgid "Can't find `%s' in include file search path."
 msgstr ""
@@ -3883,132 +4057,136 @@ msgstr ""
 msgid "Cannot change mode of %s: %s"
 msgstr ""
 
-#: src/language/utilities/set.q:201 src/language/utilities/set.q:203
-#: src/language/utilities/set.q:205 src/language/utilities/set.q:207
-#: src/language/utilities/set.q:209 src/language/utilities/set.q:211
-#: src/language/utilities/set.q:213 src/language/utilities/set.q:215
-#: src/language/utilities/set.q:217
+#: src/language/utilities/set.q:200
+msgid "WORKSPACE must be at least 1MB"
+msgstr ""
+
+#: src/language/utilities/set.q:206 src/language/utilities/set.q:208
+#: src/language/utilities/set.q:210 src/language/utilities/set.q:212
+#: src/language/utilities/set.q:214 src/language/utilities/set.q:216
+#: src/language/utilities/set.q:218 src/language/utilities/set.q:220
+#: src/language/utilities/set.q:222
 #, c-format
 msgid "%s is obsolete."
 msgstr ""
 
-#: src/language/utilities/set.q:220
+#: src/language/utilities/set.q:225
 #, c-format
 msgid "%s is not implemented."
 msgstr ""
 
-#: src/language/utilities/set.q:223
+#: src/language/utilities/set.q:228
 msgid "Active file compression is not implemented."
 msgstr ""
 
-#: src/language/utilities/set.q:318
+#: src/language/utilities/set.q:323
 msgid "EPOCH must be 1500 or later."
 msgstr ""
 
-#: src/language/utilities/set.q:325
+#: src/language/utilities/set.q:330
 msgid "expecting AUTOMATIC or year"
 msgstr ""
 
-#: src/language/utilities/set.q:346
+#: src/language/utilities/set.q:351
 msgid "LENGTH must be at least 1."
 msgstr ""
 
-#: src/language/utilities/set.q:390
+#: src/language/utilities/set.q:395
 msgid "WIDTH must be at least 40."
 msgstr ""
 
-#: src/language/utilities/set.q:413
+#: src/language/utilities/set.q:418
 #, c-format
 msgid ""
 "FORMAT requires numeric output format as an argument.  Specified format %s "
 "is of type string."
 msgstr ""
 
-#: src/language/utilities/set.q:480
+#: src/language/utilities/set.q:485
 msgid "BLANKS is SYSMIS."
 msgstr ""
 
-#: src/language/utilities/set.q:482
+#: src/language/utilities/set.q:487
 #, c-format
 msgid "BLANKS is %g."
 msgstr ""
 
-#: src/language/utilities/set.q:517
+#: src/language/utilities/set.q:522
 #, c-format
 msgid "%s is \"%s\"."
 msgstr ""
 
-#: src/language/utilities/set.q:553
+#: src/language/utilities/set.q:558
 #, c-format
 msgid "DECIMAL is \"%c\"."
 msgstr ""
 
-#: src/language/utilities/set.q:559
+#: src/language/utilities/set.q:564
 #, c-format
 msgid "ENDCMD is \"%c\"."
 msgstr ""
 
-#: src/language/utilities/set.q:567
+#: src/language/utilities/set.q:572
 #, c-format
 msgid "ERRORS is \"%s\"."
 msgstr ""
 
-#: src/language/utilities/set.q:578
+#: src/language/utilities/set.q:583
 #, c-format
 msgid "FORMAT is %s."
 msgstr ""
 
-#: src/language/utilities/set.q:584
+#: src/language/utilities/set.q:589
 #, c-format
 msgid "LENGTH is %d."
 msgstr ""
 
-#: src/language/utilities/set.q:590
+#: src/language/utilities/set.q:595
 #, c-format
 msgid "MXERRS is %d."
 msgstr ""
 
-#: src/language/utilities/set.q:596
+#: src/language/utilities/set.q:601
 #, c-format
 msgid "MXLOOPS is %d."
 msgstr ""
 
-#: src/language/utilities/set.q:602
+#: src/language/utilities/set.q:607
 #, c-format
 msgid "MXWARNS is %d."
 msgstr ""
 
-#: src/language/utilities/set.q:609 src/language/utilities/set.q:660
+#: src/language/utilities/set.q:614 src/language/utilities/set.q:665
 #, c-format
 msgid "%s is %s (%s)."
 msgstr ""
 
-#: src/language/utilities/set.q:681
+#: src/language/utilities/set.q:686
 msgid "SCOMPRESSION is ON."
 msgstr ""
 
-#: src/language/utilities/set.q:683
+#: src/language/utilities/set.q:688
 msgid "SCOMPRESSION is OFF."
 msgstr ""
 
-#: src/language/utilities/set.q:690
+#: src/language/utilities/set.q:695
 msgid "UNDEFINED is WARN."
 msgstr ""
 
-#: src/language/utilities/set.q:692
+#: src/language/utilities/set.q:697
 msgid "UNDEFINED is NOWARN."
 msgstr ""
 
-#: src/language/utilities/set.q:700
+#: src/language/utilities/set.q:705
 msgid "WEIGHT is off."
 msgstr ""
 
-#: src/language/utilities/set.q:702
+#: src/language/utilities/set.q:707
 #, c-format
 msgid "WEIGHT is variable %s."
 msgstr ""
 
-#: src/language/utilities/set.q:720
+#: src/language/utilities/set.q:725
 #, c-format
 msgid "WIDTH is %d."
 msgstr ""
@@ -4045,44 +4223,44 @@ msgstr ""
 msgid "Destination cannot be a string variable."
 msgstr ""
 
-#: src/language/xforms/recode.c:246
+#: src/language/xforms/recode.c:251
 msgid ""
 "Inconsistent target variable types.  Target variables must be all numeric or "
 "all string."
 msgstr ""
 
-#: src/language/xforms/recode.c:267
+#: src/language/xforms/recode.c:272
 msgid "CONVERT requires string input values and numeric output values."
 msgstr ""
 
-#: src/language/xforms/recode.c:317
+#: src/language/xforms/recode.c:329
 msgid "THRU is not allowed with string variables."
 msgstr ""
 
-#: src/language/xforms/recode.c:391
+#: src/language/xforms/recode.c:407
 msgid "expecting output value"
 msgstr ""
 
-#: src/language/xforms/recode.c:440
+#: src/language/xforms/recode.c:456
 #, c-format
 msgid ""
 "%zu variable(s) cannot be recoded into %zu variable(s).  Specify the same "
 "number of variables as source and target variables."
 msgstr ""
 
-#: src/language/xforms/recode.c:455
+#: src/language/xforms/recode.c:471
 #, c-format
 msgid ""
 "There is no variable named %s.  (All string variables specified on INTO must "
 "already exist.  Use the STRING command to create a string variable.)"
 msgstr ""
 
-#: src/language/xforms/recode.c:470
+#: src/language/xforms/recode.c:487
 #, c-format
 msgid "INTO is required with %s input values and %s output values."
 msgstr ""
 
-#: src/language/xforms/recode.c:483
+#: src/language/xforms/recode.c:500
 #, c-format
 msgid "Type mismatch.  Cannot store %s data in %s variable %s."
 msgstr ""
@@ -4108,28 +4286,28 @@ msgstr ""
 msgid "The filter variable may not be scratch."
 msgstr ""
 
-#: src/libpspp/hash.c:615
+#: src/libpspp/hash.c:545
 #, c-format
 msgid "hash table:"
 msgstr ""
 
-#: src/math/percentiles.c:41
+#: src/math/percentiles.c:35
 msgid "HAverage"
 msgstr ""
 
-#: src/math/percentiles.c:42
+#: src/math/percentiles.c:36
 msgid "Weighted Average"
 msgstr ""
 
-#: src/math/percentiles.c:43
+#: src/math/percentiles.c:37
 msgid "Rounded"
 msgstr ""
 
-#: src/math/percentiles.c:44
+#: src/math/percentiles.c:38
 msgid "Empirical"
 msgstr ""
 
-#: src/math/percentiles.c:45
+#: src/math/percentiles.c:39
 msgid "Empirical with averaging"
 msgstr ""
 
@@ -4279,7 +4457,7 @@ msgstr ""
 msgid "creating \"%s\""
 msgstr ""
 
-#: src/output/charts/plot-hist.c:124
+#: src/output/charts/plot-hist.c:138
 msgid "HISTOGRAM"
 msgstr ""
 
@@ -4398,7 +4576,7 @@ msgstr ""
 #: src/output/output.c:719
 #, c-format
 msgid "cannot initialize output driver `%s' of class `%s'"
-msgstr ""
+msgstr "cannot initialise output driver `%s' of class `%s'"
 
 #: src/output/output.c:765
 #, c-format
@@ -4656,329 +4834,337 @@ msgstr ""
 msgid "Style of bevel around the custom entry button"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:150
+#: src/ui/gui/data-editor.c:152
 msgid "Transformations Pending"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:323
+#: src/ui/gui/data-editor.c:325
 msgid "_Labels"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:324
+#: src/ui/gui/data-editor.c:326
 msgid "Show/hide value labels"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:342 src/ui/gui/data-editor.c:361
-#: src/ui/gui/data-editor.c:1507 src/ui/gui/data-editor.c:1561
+#: src/ui/gui/data-editor.c:344 src/ui/gui/data-editor.c:363
+#: src/ui/gui/data-editor.c:1539 src/ui/gui/data-editor.c:1593
 msgid "Clear"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:343
+#: src/ui/gui/data-editor.c:345
 msgid "Delete the cases at the selected position(s)"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:362
+#: src/ui/gui/data-editor.c:364
 msgid "Delete the variables at the selected position(s)"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:377
+#: src/ui/gui/data-editor.c:379
 msgid "Insert _Variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:378
+#: src/ui/gui/data-editor.c:380
 msgid "Create a new variable at the current position"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:396
+#: src/ui/gui/data-editor.c:398
 msgid "Insert Ca_se"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:397
+#: src/ui/gui/data-editor.c:399
 msgid "Create a new case at the current position"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:417
+#: src/ui/gui/data-editor.c:419
 msgid "_Goto Case"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:418
+#: src/ui/gui/data-editor.c:420
 msgid "Jump to a Case in the Data Sheet"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:437
+#: src/ui/gui/data-editor.c:439
 msgid "_Weights"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:438
+#: src/ui/gui/data-editor.c:440
 msgid "Weight cases by variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:447 src/ui/gui/data-editor.glade:319
+#: src/ui/gui/data-editor.c:449 src/ui/gui/data-editor.glade:319
 msgid "_Transpose"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:448
+#: src/ui/gui/data-editor.c:450
 msgid "Transpose the cases with the variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:459
+#: src/ui/gui/data-editor.c:461
 msgid "S_plit"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:460
+#: src/ui/gui/data-editor.c:462
 msgid "Split the active file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:470
+#: src/ui/gui/data-editor.c:472
 msgid "_Sort"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:471
+#: src/ui/gui/data-editor.c:473
 msgid "Sort cases in the active file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:479 src/ui/gui/data-editor.glade:340
+#: src/ui/gui/data-editor.c:481 src/ui/gui/data-editor.glade:340
 msgid "Select _Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:480
+#: src/ui/gui/data-editor.c:482
 msgid "Select cases from the active file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:489 src/ui/gui/data-editor.glade:369
+#: src/ui/gui/data-editor.c:491 src/ui/gui/data-editor.glade:369
 msgid "_Compute"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:490
+#: src/ui/gui/data-editor.c:492
 msgid "Compute new values for a variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:498
+#: src/ui/gui/data-editor.c:500
 msgid "Oneway _ANOVA"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:499
+#: src/ui/gui/data-editor.c:501
 msgid "Perform one way analysis of variance"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:507 src/ui/gui/data-editor.glade:496
+#: src/ui/gui/data-editor.c:509 src/ui/gui/data-editor.glade:496
 msgid "_Independent Samples T Test"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:508
+#: src/ui/gui/data-editor.c:510
 msgid "Calculate T Test for samples from independent groups"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:517 src/ui/gui/data-editor.glade:504
+#: src/ui/gui/data-editor.c:519 src/ui/gui/data-editor.glade:504
 msgid "_Paired Samples T Test"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:518
+#: src/ui/gui/data-editor.c:520
 msgid "Calculate T Test for paired samples"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:527
+#: src/ui/gui/data-editor.c:529
 msgid "One _Sample T Test"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:528
+#: src/ui/gui/data-editor.c:530
 msgid "Calculate T Test for sample from a single distribution"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:537 src/ui/gui/data-editor.glade:593
+#: src/ui/gui/data-editor.c:539 src/ui/gui/data-editor.glade:593
 msgid "Data File _Comments"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:538
+#: src/ui/gui/data-editor.c:540
 msgid "Commentary text for the data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:546 src/ui/gui/data-editor.glade:228
+#: src/ui/gui/data-editor.c:548 src/ui/gui/data-editor.glade:228
 msgid "_Find"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:547
+#: src/ui/gui/data-editor.c:549
 msgid "Find Case"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:556 src/ui/gui/data-editor.glade:377
+#: src/ui/gui/data-editor.c:558 src/ui/gui/data-editor.glade:377
 msgid "Ran_k Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:557
+#: src/ui/gui/data-editor.c:559
 msgid "Rank Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:566 src/ui/gui/data-editor.glade:389
+#: src/ui/gui/data-editor.c:568 src/ui/gui/data-editor.glade:389
 msgid "Recode into _Same Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:567
+#: src/ui/gui/data-editor.c:569
 msgid "Recode values into the same Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:576 src/ui/gui/data-editor.glade:396
+#: src/ui/gui/data-editor.c:578 src/ui/gui/data-editor.glade:396
 msgid "Recode into _Different Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:577
+#: src/ui/gui/data-editor.c:579
 msgid "Recode values into different Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:586 src/ui/gui/data-editor.glade:293
+#: src/ui/gui/data-editor.c:588 src/ui/gui/data-editor.glade:293
 #: src/ui/gui/data-editor.glade:584
 msgid "_Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:587
+#: src/ui/gui/data-editor.c:589
 msgid "Jump to Variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:595 src/ui/gui/data-editor.glade:450
+#: src/ui/gui/data-editor.c:597 src/ui/gui/data-editor.glade:450
 #: src/ui/gui/oneway.glade:179
 msgid "_Descriptives"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:596
+#: src/ui/gui/data-editor.c:598
 msgid "Calculate descriptive statistics (mean, variance, ...)"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:605 src/ui/gui/data-editor.glade:442
+#: src/ui/gui/data-editor.c:607 src/ui/gui/data-editor.glade:442
 msgid "_Frequencies"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:606
+#: src/ui/gui/data-editor.c:608
 msgid "Generate frequency statistics"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:614 src/ui/gui/data-editor.glade:466
+#: src/ui/gui/data-editor.c:616 src/ui/gui/data-editor.glade:466
 msgid "_Crosstabs"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:615
+#: src/ui/gui/data-editor.c:617
 msgid "Generate crosstabulations"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:624 src/ui/gui/data-editor.glade:458
+#: src/ui/gui/data-editor.c:626 src/ui/gui/data-editor.glade:458
 msgid "_Explore"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:625
+#: src/ui/gui/data-editor.c:627
 msgid "Examine Data by Factors"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:634 src/ui/gui/data-editor.glade:532
+#: src/ui/gui/data-editor.c:636 src/ui/gui/data-editor.glade:532
 msgid "Linear _Regression"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:635
+#: src/ui/gui/data-editor.c:637
 msgid "Estimate parameters of the linear model"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1027
+#: src/ui/gui/data-editor.c:921
+msgid "_Split Window"
+msgstr ""
+
+#: src/ui/gui/data-editor.c:922
+msgid "Split the window vertically and horizontally"
+msgstr ""
+
+#: src/ui/gui/data-editor.c:1042
 msgid "Font Selection"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1099
+#: src/ui/gui/data-editor.c:1126
 msgid "No Split"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1108
+#: src/ui/gui/data-editor.c:1135
 msgid "Split by "
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1133
+#: src/ui/gui/data-editor.c:1160
 msgid "Filter off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1145
+#: src/ui/gui/data-editor.c:1172
 #, c-format
 msgid "Filter by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1163
+#: src/ui/gui/data-editor.c:1190
 msgid "Weights off"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1175
+#: src/ui/gui/data-editor.c:1202
 #, c-format
 msgid "Weight by %s"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1198 src/ui/gui/data-editor.c:1440
-#: src/ui/gui/data-editor.glade:660
+#: src/ui/gui/data-editor.c:1225 src/ui/gui/data-editor.c:1472
+#: src/ui/gui/data-editor.glade:667
 msgid "Open"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1199
+#: src/ui/gui/data-editor.c:1226
 msgid "Open a data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1207 src/ui/gui/data-editor.c:1323
-#: src/ui/gui/data-editor.glade:670
+#: src/ui/gui/data-editor.c:1234 src/ui/gui/data-editor.c:1350
+#: src/ui/gui/data-editor.glade:677
 msgid "Save"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1208 src/ui/gui/data-editor.c:1218
+#: src/ui/gui/data-editor.c:1235 src/ui/gui/data-editor.c:1245
 msgid "Save data to file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1217
+#: src/ui/gui/data-editor.c:1244
 msgid "Save As"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1226 src/ui/gui/recode-dialog.c:928
+#: src/ui/gui/data-editor.c:1253 src/ui/gui/recode-dialog.c:928
 #: src/ui/gui/recode-dialog.c:1023
 msgid "New"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1227
+#: src/ui/gui/data-editor.c:1254
 msgid "New data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1235
+#: src/ui/gui/data-editor.c:1262
 msgid "_Import Text Data"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1236
+#: src/ui/gui/data-editor.c:1263
 msgid "Import text data file"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1331 src/ui/gui/data-editor.c:1448
+#: src/ui/gui/data-editor.c:1358 src/ui/gui/data-editor.c:1480
 msgid "System Files (*.sav)"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1337 src/ui/gui/data-editor.c:1454
+#: src/ui/gui/data-editor.c:1364 src/ui/gui/data-editor.c:1486
 msgid "Portable Files (*.por) "
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1343 src/ui/gui/data-editor.c:1460
+#: src/ui/gui/data-editor.c:1370 src/ui/gui/data-editor.c:1492
 #: src/ui/gui/syntax-editor.c:138 src/ui/gui/syntax-editor.c:522
 msgid "All Files"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1351
+#: src/ui/gui/data-editor.c:1378
 msgid "System File"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1356
+#: src/ui/gui/data-editor.c:1383
 msgid "Portable File"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1498
+#: src/ui/gui/data-editor.c:1530
 msgid "Sort Ascending"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1501
+#: src/ui/gui/data-editor.c:1533
 msgid "Sort Descending"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1504 src/ui/gui/data-editor.glade:150
-#: src/ui/gui/data-editor.glade:801
+#: src/ui/gui/data-editor.c:1536 src/ui/gui/data-editor.glade:150
+#: src/ui/gui/data-editor.glade:808
 msgid "Insert Variable"
 msgstr ""
 
-#: src/ui/gui/data-editor.c:1558 src/ui/gui/data-editor.glade:789
+#: src/ui/gui/data-editor.c:1590 src/ui/gui/data-editor.glade:796
 msgid "Insert Case"
 msgstr ""
 
@@ -5019,7 +5205,7 @@ msgstr ""
 msgid "Insert Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:738
+#: src/ui/gui/data-editor.glade:166 src/ui/gui/data-editor.glade:745
 msgid "Go To Case"
 msgstr ""
 
@@ -5073,7 +5259,7 @@ msgstr ""
 
 #: src/ui/gui/data-editor.glade:422
 msgid "_Analyze"
-msgstr ""
+msgstr "_Analyse"
 
 #: src/ui/gui/data-editor.glade:432
 msgid "_Descriptive Statistics"
@@ -5119,175 +5305,179 @@ msgstr ""
 #: src/ui/gui/data-editor.glade:611 src/ui/gui/output-viewer.glade:88
 #: src/ui/gui/syntax-editor.glade:243
 msgid "_Minimize All Windows"
+msgstr "_Minimise All Windows"
+
+#: src/ui/gui/data-editor.glade:618
+msgid "_Split"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:622 src/ui/gui/output-viewer.glade:99
+#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:99
 #: src/ui/gui/syntax-editor.glade:254
 msgid "_Help"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:629 src/ui/gui/output-viewer.glade:106
+#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:106
 #: src/ui/gui/syntax-editor.glade:262
 msgid "_Reference Manual"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:636 src/ui/gui/output-viewer.glade:113
+#: src/ui/gui/data-editor.glade:643 src/ui/gui/output-viewer.glade:113
 #: src/ui/gui/syntax-editor.glade:269
 msgid "_About"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:680
+#: src/ui/gui/data-editor.glade:687
 msgid "Print"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:690
+#: src/ui/gui/data-editor.glade:697
 msgid "Recall"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:708
+#: src/ui/gui/data-editor.glade:715
 msgid "Undo"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:718
+#: src/ui/gui/data-editor.glade:725
 msgid "Redo"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:748
+#: src/ui/gui/data-editor.glade:755
 msgid "Variables"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:769
+#: src/ui/gui/data-editor.glade:776
 msgid "Find"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:821
+#: src/ui/gui/data-editor.glade:828
 msgid "Split File"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:832
+#: src/ui/gui/data-editor.glade:839
 msgid "Weight Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:844
+#: src/ui/gui/data-editor.glade:851
 msgid "Select Cases"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:864 src/ui/gui/data-editor.glade:1452
-#: src/ui/gui/data-editor.glade:1633
+#: src/ui/gui/data-editor.glade:871 src/ui/gui/data-editor.glade:1459
+#: src/ui/gui/data-editor.glade:1640
 msgid "Value Labels"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:875
+#: src/ui/gui/data-editor.glade:882
 msgid "Use Sets"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:907
+#: src/ui/gui/data-editor.glade:914
 msgid "Information Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:926
+#: src/ui/gui/data-editor.glade:933
 msgid "Processor Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:951
+#: src/ui/gui/data-editor.glade:958
 msgid "Case Counter Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:976
+#: src/ui/gui/data-editor.glade:983
 msgid "Filter Use Status Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1002
+#: src/ui/gui/data-editor.glade:1009
 msgid "Weight Status Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1028
+#: src/ui/gui/data-editor.glade:1035
 msgid "Split File Status Area"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1058
+#: src/ui/gui/data-editor.glade:1065
 msgid "Variable Type"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1094 src/ui/gui/psppire-var-store.c:599
+#: src/ui/gui/data-editor.glade:1101 src/ui/gui/psppire-var-store.c:599
 msgid "Comma"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1110 src/ui/gui/psppire-var-store.c:600
+#: src/ui/gui/data-editor.glade:1117 src/ui/gui/psppire-var-store.c:600
 msgid "Dot"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1126
+#: src/ui/gui/data-editor.glade:1133
 msgid "Scientific notation"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1142 src/ui/gui/psppire-var-store.c:602
+#: src/ui/gui/data-editor.glade:1149 src/ui/gui/psppire-var-store.c:602
 msgid "Date"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1158 src/ui/gui/psppire-var-store.c:603
+#: src/ui/gui/data-editor.glade:1165 src/ui/gui/psppire-var-store.c:603
 msgid "Dollar"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1174
+#: src/ui/gui/data-editor.glade:1181
 msgid "Custom currency"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1268
+#: src/ui/gui/data-editor.glade:1275
 msgid "positive"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1274
+#: src/ui/gui/data-editor.glade:1281
 msgid "negative"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1287
+#: src/ui/gui/data-editor.glade:1294
 msgid "Sample"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1337
+#: src/ui/gui/data-editor.glade:1344
 msgid "Width:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1381
+#: src/ui/gui/data-editor.glade:1388
 msgid "Decimal Places:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1550
+#: src/ui/gui/data-editor.glade:1557
 msgid "Value Label:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1563 src/ui/gui/psppire.glade:2544
+#: src/ui/gui/data-editor.glade:1570 src/ui/gui/psppire.glade:2544
 #: src/ui/gui/recode.glade:185
 msgid "Value:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1700 src/ui/gui/examine.glade:423
+#: src/ui/gui/data-editor.glade:1707 src/ui/gui/examine.glade:423
 #: src/ui/gui/t-test.glade:460
 msgid "Missing Values"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1718
+#: src/ui/gui/data-editor.glade:1725
 msgid "_Range plus one optional discrete missing value"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1743
+#: src/ui/gui/data-editor.glade:1750
 msgid "_Low:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1772
+#: src/ui/gui/data-editor.glade:1779
 msgid "_High:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1813
+#: src/ui/gui/data-editor.glade:1820
 msgid "Di_screte value:"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1860
+#: src/ui/gui/data-editor.glade:1867
 msgid "_No missing values"
 msgstr ""
 
-#: src/ui/gui/data-editor.glade:1878
+#: src/ui/gui/data-editor.glade:1885
 msgid "_Discrete missing values"
 msgstr ""
 
@@ -5415,6 +5605,22 @@ msgstr ""
 msgid "Cannot open reference manual: %s"
 msgstr ""
 
+#: src/ui/gui/main.c:42
+msgid "Don't show the splash screen"
+msgstr ""
+
+#: src/ui/gui/main.c:158
+msgid "PSPPIRE --- A user interface for PSPP"
+msgstr ""
+
+#: src/ui/gui/main.c:160
+msgid "Miscellaneous options:"
+msgstr ""
+
+#: src/ui/gui/main.c:162 src/ui/terminal/main.c:126
+msgid "Options affecting syntax and behavior:"
+msgstr "Options affecting syntax and behaviour:"
+
 #: src/ui/gui/message-dialog.c:101
 msgid "data file error"
 msgstr ""
@@ -5578,19 +5784,29 @@ msgstr ""
 msgid "Paste"
 msgstr ""
 
-#: src/ui/gui/psppire.c:194
+#: src/ui/gui/psppire.c:216
 msgid "_Reset"
 msgstr ""
 
-#: src/ui/gui/psppire.c:195
+#: src/ui/gui/psppire.c:217
 msgid "_Select"
 msgstr ""
 
-#: src/ui/gui/psppire-data-editor.c:647
+#: src/ui/gui/psppire.c:253
+#, c-format
+msgid "Cannot open %s: %s.\n"
+msgstr ""
+
+#: src/ui/gui/psppire.c:270
+#, c-format
+msgid "%s is neither a system nor portable file"
+msgstr ""
+
+#: src/ui/gui/psppire-data-editor.c:703
 msgid "Data View"
 msgstr ""
 
-#: src/ui/gui/psppire-data-editor.c:650
+#: src/ui/gui/psppire-data-editor.c:706
 msgid "Variable View"
 msgstr ""
 
@@ -5639,7 +5855,7 @@ msgstr ""
 
 #: src/ui/gui/psppire.glade:452
 msgid "Organize output by groups."
-msgstr ""
+msgstr "Organise output by groups."
 
 #: src/ui/gui/psppire.glade:499
 msgid "Groups based on:"
@@ -5852,12 +6068,6 @@ msgstr ""
 msgid "Custom"
 msgstr ""
 
-#: src/ui/gui/psppire-var-store.c:675 src/ui/gui/psppire-var-store.c:685
-#: src/ui/gui/psppire-var-store.c:695
-#, c-format
-msgid "%d"
-msgstr ""
-
 #: src/ui/gui/rank.glade:111
 msgid "By:"
 msgstr ""
@@ -6479,60 +6689,62 @@ msgstr ""
 msgid "%s --- PSPP Output"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:230
-#, c-format
+#: src/ui/source-init-opts.c:42
 msgid ""
-"PSPP, a program for statistical analysis of sample data.\n"
-"\n"
-"Usage: %s [OPTION]... FILE...\n"
-"\n"
-"If a long option shows an argument as mandatory, then it is mandatory\n"
-"for the equivalent short option also.  Similarly for optional arguments.\n"
-"\n"
-"Configuration:\n"
-"  -a, --algorithm={compatible|enhanced}\n"
-"                            set to `compatible' if you want output\n"
-"                            calculated from broken algorithms\n"
-"  -B, --config-dir=DIR      set configuration directory to DIR\n"
-"  -o, --device=DEVICE       select output driver DEVICE and disable "
-"defaults\n"
-"\n"
-"Input and output:\n"
-"  -e, --error-file=FILE     send error messages to FILE (appended)\n"
-"  -f, --out-file=FILE       send output to FILE (overwritten)\n"
-"  -p, --pipe                read syntax from stdin, send output to stdout\n"
-"  -I-, --no-include         clear include path\n"
-"  -I, --include=DIR         append DIR to include path\n"
-"\n"
-"Language modifiers:\n"
-"  -i, --interactive         interpret syntax in interactive mode\n"
-"  -n, --edit                just check syntax; don't actually run the code\n"
-"  -r, --no-statrc           disable execution of .pspp/rc at startup\n"
-"  -s, --safer               don't allow some unsafe operations\n"
-"  -x, --syntax={compatible|enhanced}\n"
-"                            set to `compatible' if you want only to accept\n"
-"                            spss compatible syntax\n"
-"\n"
-"Informative output:\n"
-"  -h, --help                print this help, then exit\n"
-"  -l, --list                print a list of known driver classes, then exit\n"
-"  -V, --version             show PSPP version, then exit\n"
-"  -v, --verbose             increments verbosity level\n"
-"\n"
-"Non-option arguments:\n"
-" FILE                       syntax file to execute\n"
-" KEY=VALUE                  overrides macros in output initialization file\n"
-"\n"
+"set to `compatible' if you want output calculated from broken algorithms"
+msgstr ""
+
+#: src/ui/source-init-opts.c:43
+msgid "Append DIR to include path"
 msgstr ""
 
-#: src/ui/terminal/command-line.c:265
+#: src/ui/source-init-opts.c:44
+msgid "Clear include path"
+msgstr ""
+
+#: src/ui/source-init-opts.c:45
+msgid "Disable execution of .pspp/rc at startup"
+msgstr ""
+
+#: src/ui/source-init-opts.c:46
+msgid "Set configuration directory to DIR"
+msgstr ""
+
+#: src/ui/source-init-opts.c:47
+msgid "Don't allow some unsafe operations"
+msgstr ""
+
+#: src/ui/source-init-opts.c:48
+msgid "Set to `compatible' if you want only to accept SPSS compatible syntax"
+msgstr ""
+
+#: src/ui/source-init-opts.c:83
 #, c-format
-msgid ""
-"\n"
-"Report bugs to <%s>.\n"
+msgid "Algorithm must be either \"compatible\" or \"enhanced\"."
 msgstr ""
 
-#: src/ui/terminal/main.c:130
+#: src/ui/source-init-opts.c:124
+#, c-format
+msgid "Syntax must be either \"compatible\" or \"enhanced\"."
+msgstr ""
+
+#: src/ui/terminal/main.c:116
+msgid "PSPP --- A program for statistical analysis"
+msgstr ""
+
+#: src/ui/terminal/main.c:117
+msgid "FILE1, FILE2 ... FILEn"
+msgstr ""
+
+#: src/ui/terminal/main.c:120 src/ui/terminal/terminal-opts.c:177
+msgid "Options affecting input and output locations:"
+msgstr ""
+
+#: src/ui/terminal/main.c:123
+msgid "Diagnositic options:"
+msgstr ""
+
+#: src/ui/terminal/main.c:157
 msgid ""
 "Stopping syntax file processing here to avoid a cascade of dependent command "
 "failures."
@@ -6570,6 +6782,30 @@ msgstr ""
 msgid "could not access definition for terminal `%s'"
 msgstr ""
 
+#: src/ui/terminal/terminal-opts.c:41
+msgid "Increase diagnostic verbosity level"
+msgstr ""
+
+#: src/ui/terminal/terminal-opts.c:68
+msgid "Send error messages to FILE (appended)"
+msgstr ""
+
+#: src/ui/terminal/terminal-opts.c:71
+msgid "Select output driver DEVICE and disable defaults"
+msgstr ""
+
+#: src/ui/terminal/terminal-opts.c:74
+msgid "Print a list of known driver classes, then exit"
+msgstr ""
+
+#: src/ui/terminal/terminal-opts.c:76
+msgid "Start an interactive session"
+msgstr ""
+
+#: src/ui/terminal/terminal-opts.c:178
+msgid "Diagnostic options:"
+msgstr ""
+
 #~ msgid ""
 #~ "   This program is free software: you can redistribute it and/or modify\n"
 #~ "   it under the terms of the GNU General Public License as published by\n"
diff --git a/src/ChangeLog b/src/ChangeLog
deleted file mode 100644 (file)
index bba2afa..0000000
+++ /dev/null
@@ -1,14204 +0,0 @@
-2007-11-03 John Darrington <john@darrington.wattle.id.au>
-
-       * gnumeric-reader.c gnumeric-reader.h: New files.
-
-Thu May  4 21:47:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, move
-       procedure.c and procedure.h from src to src/data.  Update
-       makefiles and #includes accordingly.
-
-       * automake.mk: Remove special rule for src/procedure.o.
-
-       * procedure.c: Moved to src/data.
-
-       * procedure.h: Moved to src/data.
-
-Wed May  3 22:24:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * procedure.c: (global var vfm_source) Make static.  Changed
-       external references to use in_input_program(), proc_set_source(),
-       or proc_capture_output() instead.
-       (global var vfm_sink) Make static.  Changed external references to
-       use proc_set_sink() instead.
-       (global var default_dict) Move here from data/dictionary.c.
-       (static var permanent_trns_chain) New var.
-       (static var temp_dict) Renamed permanent_dict, updated references.
-       (static var temporary_trns_chain) New var.
-       (static var cur_trns_chain) New var.
-       (static var in_procedure) Removed.
-       (global var t_trns) Removed.
-       (global var n_trns) Removed.
-       (global var m_trns) Removed.
-       (global var f_trns) Removed.
-       (procedure) Even if there's "nothing to do" we need to clear
-       PROCESS IF, N OF CASES, vector state.  (This should be
-       abstracted.)
-       (multipass_callback) New function.
-       (multipass_procedure) New function.
-       (open_active_file) Add N OF CASES, FILTER, PROCESS IF
-       transformations.  Finalize transformations.  No need to call
-       ctl_stack_clear() anymore because finalizers will do that.
-       (write_case) Simplify and rewrite.
-       (execute_transformations) Removed.
-       (filter_case) Removed.
-       (close_active_file) Use proc_cancel_temporary_transformations().
-       No need to clear PROCESS IF, N OF CASES here anymore because
-       helpers do that.
-       (multipass_procedure_with_splits) Keep track of success.
-       (multipass_split_callback) Ditto.
-       (multipass_split_output) Ditto.
-       (discard_variables) No need to call ctl_stack_clear() anymore
-       because finalizers will do that.
-       (proc_capture_transformations) New function.
-       (add_transformation) Rewrite in terms of trns_chain_append().
-       (add_transformation_with_finalizer) New function.
-       (next_transformation) Rewrite in terms of trns_chain_next().
-       (proc_in_temporary_transformations) New function.
-       (proc_start_temporary_transformations) New function.
-       (proc_make_temporary_transformations_permanent) New function.
-       (proc_cancel_temporary_transformations) New function.
-       (cancel_transformations) Rename proc_cancel_all_transformations(),
-       rewrite in terms of trns_chain_destroy().
-       (proc_init) New function.
-       (proc_done) New function.
-       (proc_set_sink) New function.
-       (proc_set_source) New function.
-       (proc_has_source) New function.
-       (proc_capture_output) New function.
-       (add_case_limit_trns) New function.
-       (case_limit_trns_proc) New function.
-       (case_limit_trns_free) New function.
-       (add_filter_trns) New function.
-       (filter_trns_proc) New function.
-       (add_process_if_trns) New function.
-       (process_if_trns_proc) New function.
-       (process_if_trns_free) New function.
-
-Wed Apr 26 20:00:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c (create_trns_case): Fix inverted decision on whether
-       numeric values should be initialized to 0 or SYSMIS.
-
-Wed Apr 26 19:48:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, assert
-       that add_transformation() is not called during procedure
-       execution.  Thanks to John Darrington for the suggestion.
-       
-       * procedure.c: (static var in_procedure) New var.
-       (internal_procedure) Get rid of recursive_call local var and
-       logic.
-       (open_active_file) Set in_procedure and make sure it wasn't
-       already set.
-       (close_active_file) Reset in_procedure and make sure it was
-       already set.
-       (add_transformation) Make sure we're not in a procedure.
-
-Wed Apr 26 19:33:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, break
-       procedure.c into multiple files.
-       
-       * procedure.c (vfm_last_invocation): Rename
-       time_of_last_procedure().  Update all references.
-       (struct storage_stream_info) Move to data/storage-stream.c.
-       (storage_sink_open) Ditto.
-       (destroy_storage_stream_info) Ditto.
-       (storage_sink_write) Ditto.
-       (storage_sink_destroy) Ditto.
-       (storage_sink_make_source) Ditto.
-       (var storage_sink_class) Ditto.
-       (storage_source_count) Ditto.
-       (storage_source_read) Ditto.
-       (storage_source_destroy) Ditto.
-       (storage_source_class) Ditto.
-       (storage_source_get_casefile) Ditto.
-       (storage_source_create) Ditto.
-       (null_sink_class) Move to data/case-sink.c.
-       (create_case_source) Move to data/case-source.c.
-       (free_case_source) Ditto.
-       (case_source_is_class) Ditto.
-       (create_case_sink) Move to data/case-sink.c.
-       (free_case_sink) Ditto.
-
-       * procedure.h: (struct case_source) Move to data/case-source.h.
-       (struct case_source_class) Ditto.
-       (struct case_sink) Move to data/case-sink.h.
-       (struct case_sink_class) Ditto.
-
-Thu Apr 27 09:28:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * automake.mk: Removed explicit dependencies for message.o, since
-       that module no longer exists.
-
-Wed Apr 26 15:29:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start reforming procedure execution.  In this phase, get rid of
-       function prototypes for never-defined functions.
-       
-       * procedure.h: Get rid of function prototypes for never-defined
-       functions.
-
-Wed Apr 26 12:58:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       Improve the way we handle the various parsing "states".  Until now
-       we've hard-coded the state transitions in the command definition
-       file, but that's error-prone and, worse, it's redundant--we can
-       figure out what state we're in anyhow.  We can cleanly handle
-       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
-       
-       * procedure.c (case_source_is_complex): Removed.
-       (discard_variables) No need to set pgm_state anymore.
-
-Tue Apr 25 11:06:49 2006  Ben Pfaff  <blp@gnu.org>
-
-       Finish reforming error message support.  In this phase, move
-       message.c into libpspp.
-       
-       * message.c: Move to libpspp.
-
-Tue Apr 25 10:47:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, drop
-       actual message printing from core code, substituting a callback,
-       and add the callback to each UI.  Also, move verbose_msg() into
-       its own module.
-
-       * message.c: (var err_error_count) Renamed error_count and moved
-       to ui/terminal/msg-ui.c.
-       (var err_warning_count) Renamed warning_count and moved to
-       ui/terminal/msg-ui.c.
-       (err_check_count) Renamed check_msg_count() and moved to
-       ui/terminal/msg-ui.c.
-       (dump_message) Rewrote to take stream instead of function pointer
-       and moved to ui/terminal/msg-ui.c.
-       (msg_emit) Moved its guts to ui/terminal/msg-ui.c as handle_msg()
-       and rewrote to just pass message to callback.
-       
-       (var err_verbosity) Renamed "verbosity" and moved to
-       libpspp/verbose-msg.c.
-       (verbose_msg) Moved to libpspp/verbose-msg.c.
-       
-       (var err_already_flagged) Removed.
-       (puts_stdout) Removed.
-       
-       (var msg_handler) New static variable.
-       (msg_init) New function.
-       (msg_get_command_name) New function.
-       
-Mon Apr 24 17:40:08 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, rename
-       all the message functions and types to start with "msg", except
-       for the ones that will be moving to other modules anyway.
-
-       All references to the identifiers below were updated likewise.
-       
-       * message.c: (err_done) Renamed msg_done().
-       (err_push_file_locator) Renamed msg_push_msg_locator().
-       (err_pop_file_locator) Renamed msg_pop_msg_locator().
-       (err_location) Renamed msg_location().
-       (err_set_command_name) Renamed msg_set_command_name().
-
-Mon Apr 24 14:11:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       * message.c: Use exit.h from gnulib instead of checking for and
-       defining EXIT_SUCCESS and EXIT_FAILURE by hand.
-
-Sun Apr 23 22:00:23 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-
-       * message.c: (tmsg) Removed.
-       (msg) Use err_msg() instead of err_vmsg().  Format message
-       ourselves.
-       (err_vmsg) Renamed err_msg().  Changed interface, dropping message
-       and va_list args which are now in the error struct.
-               
-Sun Apr 23 20:35:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.
-
-       * message.c: Use linebreak module from gnulib instead of home-brew
-       line breaking.
-       (puts_stdout) Rewrote.
-       (dump_message) Rewrote.  Changed interface and updated all callers.
-       (compulsory_break) Removed.
-       (char_is_break) Removed.
-       (break_before) Removed.
-       (break_after) Removed.
-       (macro BREAK_LONG_WORD) Removed.
-
-Sun Apr 16 20:41:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we
-       divide the classification of messages along "category" and
-       "severity" axes.
-
-       * message.c: (err_vmsg) Rewrite to deal with categories and
-       severities in a straightforward manner instead of mixing them into
-       classes.
-       [0] (puts_stderr) Removed (dead code).
-       (msg) Changed first argument from `int' to `enum msg_class'.
-       (tmsg) Ditto.
-
-Sun Apr 16 18:53:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       GNU standards require "file name" instead of "filename" in
-       documentation.  It's nice for our code to follow the convention
-       too.
-
-       Basically did search and replace in the whole source tree.  Major
-       changes in function names or struct member names have their own
-       change log entries.
-
-Sun Apr 16 15:58:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we get
-       rid of VM() and the other msg() support for "verbosity", replacing
-       it by a new function verbose_msg().
-
-       * message.c: (verbose_msg) New function.
-       (err_vmsg) Remove support for verbosity levels.
-
-Sun Apr 16 11:46:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start reforming error message support.  In this phase, we get rid
-       of "installation errors" and change all uses of msg() in the
-       output drivers to uses of error() or error_at_line().
-
-       * message.c: (err_vmsg) Get rid of IE, IS support.
-
-Sat Mar 11 14:17:47 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk: Changed the pattern specific AM_CPPFLAGS to two target 
-         specific ones. Eventually there will be none at all.
-
-       * automake.mk: Moved the pspp binary to ui/terminal
-
-Sat Mar  4 12:59:08 2006  Ben Pfaff  <blp@gnu.org>
-
-       * In many source files, #include "compiler.h" to get GCC attribute
-       definitions.
-
-Sat Mar  4 12:28:09 2006  Ben Pfaff  <blp@gnu.org>
-
-       * In many source files, replace INT_DIGITS by
-       INT_STRLEN_BOUND(int) and include intprops.h.
-
-John Darrington:
-       
-       * Replaced '_' with '-' in most filenames.
-
-       * Renamed files as follows:
-               vfm.[ch] to procedure.[ch]
-               error.[ch] to message.[ch]
-               getl.[ch] to line-buffer.[ch]
-               mkfile.[ch] to make-file.[ch]
-               pfm-write.h to por-file-writer.h
-               pfm-write.c to por-file-writer.c
-               sfmP.h to sfm-private.h
-               lex-def.c to identifier.c
-               lex-def.h to identifier.h
-               sfm-read.c to sys-file-reader.c
-               sfm-read.h to sys-file-reader.h
-               sfm-write.h to sys-file-writer.h
-               sfm-write.c to sys-file-writer.c
-               chart.[ch] to chart-geometry.[ch]
-               val.h to value.h
-               var.h to variable.h
-               vars-atr.c to variable.c
-               ctl-stack.c to control-stack.c
-               ctl-stack.h to control-stack.h
-               dfm-read.c to data-reader.c
-               dfm-write.c to data-writer.c
-               dfm-write.h to data-writer.h
-               dfm-read.h to data-reader.h
-               apply-dict.c to apply-dictionary.c
-               mis-val.c to missing-values.c
-               sysfile-info.c to sys-file-info.c
-               modify-vars.c to modifiy-variables.c
-               rename-vars.c to rename-variables.c
-               val-labs.c to value-labels.c
-               var-display.c to variable-display.c
-               var-labs.c to variable-label.c
-               format-prs.c to format-parser.c
-               range-prs.c to range-parser.c
-               range-prs.h to range-parser.h
-               subclist.c to subcommand-list.c
-               subclist.h to subcommand-list.h
-               vars-prs.c to variable-parser.c
-               descript.c to descriptives.c
-               sort-prs.c to sort-criteria.c/sort-cases.c
-               sort-prs.h to sort-criteria.h
-               sel-if.c to select-if.c
-               algorithm.c to array.c
-               algorithm.h to array.h
-               bitvector.h to bit-vector.h
-               som.c to manager.c
-               som.h to manager.h
-               tab.h to table.h
-               tab.c to table.c
-               readln.c to read-line.c
-               readln.h to read-line.h
-               cmdline.c to command-line.c
-               cmdline.h to command-line.h
-
-
-Sat Feb 11 22:35:20 2006  Ben Pfaff  <blp@gnu.org>
-
-       General clean-ups and minor bug fixes.
-
-       * filename.h: Move DIR_SEPARATOR, PATH_SEPARATOR here from
-       pref.h.orig.
-
-       * lex-def.h: (macro CHAR_IS_ID1) Removed.  All references changed
-       to lex_is_id1().
-       (macro CHAR_IS_IDN) Removed.  All references changed to
-       lex_is_idn().
-       
-       * lex-def.c: (lex_is_id1) New function.
-       (lex_is_idn) New function.
-       (lex_skip_identifier) New function.
-       (lex_id_match_len) Return bool instead of int.
-       (lex_id_match) Ditto.
-
-       * command.c: (parse_command_name) Convert parsed words to
-       uppercase to make error messages easier to read.
-       (cmd_host) Fix return value.
-
-       * dfm-read.c: (read_inline_record) Use tokens to check for BEGIN
-       DATA, not specialized lexical analysis.
-
-       * print.c: (print_space_trns_proc) Count of lines should be `int',
-       otherwise we might never finish.
-       (print_space_trns_free) Close writer.
-
-       * lexer.c: (enum string_type) New enum.
-       (lex_get) Remove essentially unused local variable `cp'.
-       Use enum string_type values.  Use parse_id().
-       (parse_id) New function.
-       (lex_look_ahead) Recognize octal strings too.
-       (strip_comments) New function.
-       (lex_get_line) Rewrite.
-       (lex_preprocess_line) Removed.
-       (convert_numeric_string_to_char_string) Use enum string_type.
-       (parse_string) Ditto.
-
-       * autorecode.c: (recode) Clone correct number of bytes based on
-       source string width.
-
-Sat Feb 11 22:34:38 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reduce dependencies on getl, and of getl.
-
-       * data-in.c: (vdls_error) Don't output different message depending
-       on whether we're interactive.
-
-       * getl.h: (struct getl_line_list) Removed.
-       (struct getl_script) Removed.
-       (GETL_PRPT_*) Removed.
-       (GETL_MODE_*) Removed.
-       (GETL_PROMPT_FIRST, GETL_PROMPT_LATER, GETL_PROMPT_DATA,
-       GETL_PROMPT_CNT) New enums.
-
-       * settings.c: (static var prompt) Removed.
-       (static var cprompt) Removed.
-       (static var dprompt) Removed.
-       (settings_done) Don't initialize prompt, cprompt, dprompt.
-       (get_prompt) Removed.
-       (set_prompt) Removed.
-       (get_dprompt) Removed.
-       (set_dprompt) Removed.
-       (get_cprompt) Removed.
-       (set_cprompt) Removed.
-
-       * pfm-read.c: (corrupt_msg) Don't show filename and line number,
-       to get rid of getl_location().
-
-       * sfm-read.c: (corrupt_msg) Ditto.
-
-       * getl.c: (struct getl_source) New.
-       (static var cur_source) New.
-       (static var last_source) New.
-       (static var DO_REPEAT_level) Removed.
-       (global var getl_head) Removed.
-       (global var getl_tail) Removed.
-       (getl_initialize) Call init_prompts().
-       (getl_add_file) Removed.
-       (getl_include) Removed.
-       (getl_add_DO_REPEAT_file) Removed.
-       (getl_handle_line_buffer) Removed.
-       (getl_close_file) Removed.
-       (getl_close_all) Removed.
-       (getl_is_separate) Removed.
-       (getl_set_separate) Removed.
-       (getl_reading_script) Removed.
-       (append_source) New function.
-       (include_source) New function.
-       (create_source) New function.
-       (create_syntax_file_source) New function.
-       (create_filter_source) New function.
-       (create_function_source) New function.
-       (create_interactive_source) New function.
-       (getl_append_syntax_file) New function.
-       (getl_include_syntax_file) New function.
-       (getl_include_filter) New function.
-       (getl_include_function) New function.
-       (getl_append_interactive) New function.
-       (getl_abort_noninteractive) New function.
-       (getl_is_interactive) New function.
-       (close_source) New function.
-       (getl_location) Use new `cur_source' var.
-       (getl_uninitialize) Use close_source().  Call uninit_prompts().
-       (read_syntax_file) New function.
-       (read_line_from_source) New function.
-       (do_read_line) New function.
-       (getl_read_line) Rewrite.
-       (static var prompts) New.
-       (static var current_style) New.
-       (init_prompts) New function.
-       (uninit_prompts) New function.
-       (getl_get_prompt) New function.
-       (getl_set_prompt) New function.
-       (getl_set_prompt_style) New function.
-       (get_prompt) New function.
-
-       * command.c: Merge the EXIT (aka Q, aka QUIT) and FINISH commands,
-       and make EXIT undocumented.  EXIT was a PSPP extension that never
-       really entirely made sense.
-       (cmd_exit) Removed.
-       (cmd_finish) Return CMD_EOF unconditionally.
-       (cmd_clear_transformations) Drop requirement of interactivity.
-
-       * command.def: Merge the EXIT (aka Q, aka QUIT) and FINISH
-       commands.
-
-       * repeat.c: Major changes to match getl revision.
-       (struct line_list) New struct.
-       (enum repeat_entry_type) New.
-       (struct repeat_entry) Made `type' an enum repeat_entry_type.
-       (struct repeat_block) New.
-       (static var repeat_tab) Removed.
-       (static var count) Removed.
-       (static var line_buf_head) Removed.
-       (static var line_buf_tail) Removed.
-       (cmd_do_repeat) Rewritten.
-       (clean_up) Removed.
-       (append_record) Removed.
-       (recognize_keyword) New function.
-       (internal_cmd_do_repeat) Removed.
-       (parse_specification) New function.
-       (skip_indentor) New function.
-       (recognize_do_repeat) New function.
-       (recognize_end_repeat) New function.
-       (parse_lines) New function.
-       (create_vars) New function.
-       (parse_ids) Use enum repeat_entry_type.
-       (parse_strings) Ditto.
-       (find_DO_REPEAT_substitution) Renamed find_substitution(),
-       rewrote.
-       (perform_DO_REPEAT_substitutions) Renamed do_repeat_filter(),
-       rewrote.
-       (do_repeat_read) New function.
-       (do_repeat_close) New function.
-
-       * data-list.c: Don't need to keep track of eof from getl anymore,
-       because getl can tell us now.
-       (struct data_list_pgm) Removed `eof' member.
-       (cmd_data_list) Don't assign to `eof'.
-       (get_data_list_read_func) Renamed read_from_data_list(), changed
-       interface.
-       (read_from_data_list_fixed) Changed interface.
-       (read_from_data_list_free) Changed interface.
-       (read_from_data_list_list) Changed interface.
-       (data_list_trns_proc) Rewrote based on dfm_eof() and
-       dfm_reader_error().
-       (data_list_source_read) Check for dfm reader errors.
-
-       * dfm-read.c: (enum dfm_reader_flags) Removed DFM_EOF in favor of
-       new `eof_cnt' member in struct dfm_reader.
-       (struct dfm_reader) New `eof_cnt' member.
-       (dfm_close_reader) Check `eof_cnt', not DFM_EOF.
-       (dfm_open_reader) Initialize `eof_cnt'.
-       (read_inline_record) Set prompt style with
-       getl_set_prompt_style().  
-       (read_record) Rewrite.
-       (cmd_begin_data) Set prompt style with getl_set_prompt_style().
-
-       * include.c: (cmd_include) Use getl_include_syntax_file().
-
-       * set.q: (cmd_set) Use getl_set_prompt().
-
-       * html.c: (postopen) Remove "source-file" expansion variable, to
-       avoid use of getl_location().
-
-       * postscript.c: (postopen) Remove "source-file" expansion
-       variable, to avoid use of getl_location().
-
-       * cmdline.c: (parse_command_line) Drop -c command line option,
-       because it wasn't very useful.  -i command line option now calls
-       getl_append_interactive().  Use new getl function interfaces.
-       Drop support for clearing dictionary between syntax files and thus
-       the "+" command line syntax.
-       (static var pre_syntax_message) Remove description of now-gone -c
-       option.  Remove "+" command line syntax.
-
-       * main.c: (main) Only call handle_error() if the return value is
-       an error.
-       (execute_command) Use getl_set_prompt_style().  Drop support for
-       clearing dictionary between syntax files.
-       (handle_error) Handle CMD_CASCADING_FAILURE.  Don't call err_break().
-
-       * readln.c: Drop lots of #ifdefs.  Now that the Autoconf tests are
-       pickier, we can just use HAVE_READLINE.
-       (static var welcomed) Move into welcome().
-       (welcome) Make `welcomed' a local static var.  Check for and read
-       history file here.
-       (global var getl_mode) Removed.
-       (global var getl_interactive) Removed.
-       (global var getl_prompt) Removed.
-       (getl_read_line) removed.
-       (readln_read) New function.
-       (read_console) Removed.
-       
-
-Sat Feb 11 22:16:21 2006  Ben Pfaff  <blp@gnu.org>
-
-       Try to reduce some of the nastier dependencies on the error
-       module, and at the same time make PSPP nicer to deal with, by
-       getting rid of fatal errors.  All the existing calls to msg (FE,
-       ...) or err_cond_fail() or err_failure() have been replaced by
-       propagating an error upward to the command-dispatch layer.
-       Unfortunately this propagation took a fair bit of extra mechanism,
-       because now a lot of functions can fail that couldn't before.
-
-       New command return value CMD_CASCADING_FAILURE which indicates to
-       the command processor that syntax file processing should be
-       abandoned.  Many commands were modified to return
-       CMD_CASCADING_FAILURE.  When this modification was trivial it
-       isn't mentioned in detail below.
-
-       Transformation procedures (trns_proc_func) and free functions
-       (trns_free_func) now have a `bool' return type, which is normally
-       true, but false when an I/O or other serious error occurs.  All
-       transformation functions were modified to have this return type.
-       When this modification was trivial it isn't mentioned in detail
-       below.
-
-       * pspp-error.h: (FE) Removed this error class.
-
-       * error.c: (err_failure) Removed.
-       (err_cond_fail) Removed.
-       (err_break) Removed (it was unused).
-       (err_check_count) Don't cause a fatal error--instead, stop reading
-       the syntax file.
-       (err_vmsg) Don't have FE anymore, so no need to call terminate().
-
-       * any-reader.c: (any_reader_error) New function.
-
-       * any-writer.c: (any_writer_write) Propagate
-       scratch_writer_write_case()'s new return value.
-       (any_writer_error) New function.
-       (any_writer_close) Propagate underlying function's new return
-       value.
-
-       * casefile.c: Add an "error state" to a casefile.  A casefile that
-       encounters an I/O error enters the error state, and afterward
-       reading and writing cases fails.
-       (struct casefile) Add `ok' member.
-       (casefile_create) Set `ok' to true.
-       (casefile_destroy) Use io_error().
-       (casefile_error) New function.
-       (casefile_sleep) Now returns bool to indicate success.
-       (casefile_append) Ditto.
-       (casefile_append_xfer) Ditto.
-       (casefile_to_disk) Ditto.
-       (write_case_to_disk) Don't do anything in error state.
-       (flush_buffer) Don't do anything in error state.  Use io_error().
-       (reader_open_file) Ditto.
-       (fill_buffer) Ditto.
-       (casereader_read) Don't do anything in error state.  Handle
-       errors.
-       (casereader_read_xfer_assert) Removed, because now an I/O error
-       can occur even if the caller knows a case exists.
-       (io_error) New function.
-
-       * mkfile.c: (make_temp_file) Make failure non-fatal.
-       (make_unique_file_stream) Ditto.
-
-       * pfm-read.c: Add an error state.
-       (struct pfm_reader) Add `ok' member to indicate error state.
-       (error) Set `ok' to false.
-       (pfm_open_reader) Set `ok' to true.  Make failure non-fatal.
-       (pfm_read_case) Don't do anything in error state.
-       (pfm_read_error) New function.
-
-       * pfm-write.c: Postpone most error checking in favor of checking
-       ferror() afterward.
-       (pfm_open_writer) Make failure non-fatal.  Check for write error
-       after writing header.
-       (buf_write) Don't do anything if error has occurred.  Postpone
-       error checking.  Change return type to void.
-       (write_float) Postpone error checking.  Change return type to
-       void.
-       (write_int) Ditto.
-       (write_string) Ditto.
-       (write_header) Ditto.
-       (write_version_data) Ditto.
-       (write_format) Ditto.
-       (write_value) Ditto.
-       (write_variables) Ditto.
-       (write_value_labels) Ditto.
-       (pfm_write_case) Don't do anything if error has occurred.
-       (pfm_write_error) New function.
-       (pfm_close_writer) Change return type to bool.  Return false if an
-       I/O error occurred.
-
-       * scratch-reader.c: (scratch_reader_error) New function.
-
-       * scratch-writer.c: (scratch_writer_write_case) Change return type
-       to bool.  Propagate casefile error return.
-       (scratch_writer_error) New function.
-       (scratch_writer_close) Change return type to bool.  Propagate
-       casefile error return.
-
-       * sfm-read.c: Add an error state.
-       (struct sfm_reader) Add `ok' member.
-       (sfm_open_reader) Initialize `ok'.  Make errors non-fatal.
-       (buf_read) Set `ok' to false on error.
-       (buffer_input) Do nothing in error state.  Set `ok' to false on
-       error.
-       (read_compressed_data) Set `ok' false on error.
-       (sfm_read_case) Return false in error state.
-       (fread_ok) Set `ok' false on error.
-       (sfm_read_error) New function.
-
-       * sfm-write.c: Postpone most error checking in favor of checking
-       ferror() afterward.
-       (sfm_open_writer) Make failure non-fatal.  Check for write error
-       after writing header.
-       (write_header) Postpone error checking.  Change return type to
-       void.
-       (write_variable) Ditto.
-       (write_value_labels) Ditto.
-       (write_documents) Ditto.
-       (write_variable_display_parameters) Ditto.
-       (write_longvar_table) Ditto.
-       (write_rec_7_34) Ditto.
-       (buf_write) Ditto.
-       (ensure_buf_space) Ditto.
-       (sfm_write_case) Do nothing if write error has occurred.
-       (sfm_write_error) New function.
-       (pfm_close_writer) Change return type to bool.  Return false if an
-       I/O error occurred.
-
-       * var.h: Introduced a new return value for trns_proc_func that
-       means "a serious error has occurred, so abort the procedure
-       entirely".  Because the hard-coded values of -1, -2, etc. were
-       becoming even a worse idea now, also introduced some macros for
-       them: TRNS_CONTINUE, TRNS_DROP_CASE, TRNS_ERROR, TRNS_NEXT_CASE,
-       TRNS_END_FILE.  Also replaced all references to the hard-coded
-       values by uses of the macros.
-       
-       * command.h: New command return value CMD_CASCADING_FAILURE which
-       indicates to the command processor that syntax file processing
-       should be abandoned.
-
-       * dfm-read.c: (dfm_open_reader) Make failure non-fatal.
-       (dfm_reader_error) New function.
-       (read_inline_record) Make unexpected end of file nonfatal.
-       (read_file_record) Make read error nonfatal.
-       (dfm_eof) Make second unexpected end of file nonfatal.
-       (cmd_begin_data) Make errors nonfatal.  
-       
-       * dfm-write.c: (dfm_open_writer) Make failure non-fatal.
-       (dfm_write_error) New function.
-       (dfm_put_record) Do nothing in error state.  Now return error
-       state.
-       (dfm_close_reader) Now return `bool' indicating error state.
-
-       * file-type.c: (file_type_source_read) Now return `bool'
-       indicating error state.
-
-       * get.c: (case_reader_source_read) Now return `bool' indicating
-       write error.
-       (case_writer_destroy) Ditto.
-       (case_writer_write_case) Ditto.
-       (struct mtf_proc) New member `ok' indicating error state.
-       (cmd_match_files) Initialize and deal with `ok'.
-       (mtf_processing_finish) Now return `bool' indicating I/O error.
-       (mtf_free_file) Renamed mtf_close_file().  Now return `bool'
-       indicating I/O error.
-       (mtf_free) Now return `bool' indicating I/O error.
-       (mtf_delete_file_in_place) Ditto.
-       (mtf_read_nonactive_records) Ditto.
-       (mtf_processing) Ditto.
-
-       * inpt-pgm.c: (input_program_source_read) Now return `bool'
-       indicating I/O error.  Handle new TRNS_ERROR transformation return
-       value.
-
-       * matrix-data.c: Introduce error state.
-       (cmd_matrix_data) Check error return values.
-       (read_matrices_without_rowtype) Now return `bool' indicating I/O
-       error.
-       (matrix_data_read_without_rowtype) Ditto.
-       (dump_cell_content) Ditto.
-       (nr_output_data) Ditto.
-       (read_matrices_with_rowtype) Ditto.
-       (matrix_data_read_with_rowtype) Ditto.
-       (wr_output_data) Ditto.
-
-       * lexer.c: (lex_init) Make unexpected eof non-fatal.
-       (lex_get) Ditto.
-       (lex_look_ahead) Ditto.
-       (unexpected_eof) Removed.
-       (convert_numeric_string_to_char_string) Make unexpected eof
-       non-fatal.
-       (parse_string) Ditto.
-
-       * flip.c: Make I/O errors non-fatal.
-       (struct flip_pgm) Add `pool', `output_buf' members.
-       (cmd_flip) Create and use pool.  Propagate errors.
-       (destroy_flip_pgm) Rewrite, using pool.
-       (struct flip_sink_info) Removed.
-       (flip_sink_create) Use pool.  Make errors non-fatal.
-       (flip_sink_write) Make errors non-fatal.
-       (flip_file) Make errors non-fatal.  Make `bool' return type to
-       indicate failure.
-       (flip_sink_destroy) Remove.
-       (static var flip_sink_class) Use NULL as destroy func, not
-       flip_sink_destroy().
-
-       * sort.c: Make I/O errors non-fatal.  Propagate errors.
-       (sort_active_file_in_place) Propagate errors.
-       (sort_active_file_to_casefile) Ditto.
-       (do_internal_sort) Ditto.
-       (do_external_sort) Ditto.
-       (write_runs) Ditto.
-       (destroy_initial_run_state) Propagate errors via new `bool' return
-       type.
-       (merge) Propagate errors.
-       (merge_once) Ditto.
-
-       * output.c: [GLOBAL_DEBUGGING] Remove reentrancy detection,
-       because it used msg (FE, ...) and wasn't very useful.
-
-       * main.c: (handle_error) Handle CMD_CASCADING_FAILURE.
-
-       * vfm.c: (struct write_case_data) Change `proc_func' return type
-       to bool.
-       (procedure) Add `bool' return type to indicate I/O error.
-       Propagate errors.
-       (internal_procedure) Ditto.
-       (write_case) Ditto.
-       (execute_transformations) If a transformation returns TRNS_ERROR,
-       propagate the error.
-       (close_active_file) Add `bool' return type to indicate I/O error.
-       Propagate errors.
-       (cancel_transformations) Add `bool' return type to indicate I/O
-       error.  Propagate errors.
-       (struct split_aux_data) Change `proc_func' return type to bool.
-       (procedure_with_splits) Change `proc_func' return type to bool.
-       Add `bool' return type to indicate I/O error.
-       (multipass_procedure_with_splits) Change `split_func' return type
-       to bool.  Add `bool' return type to indicate I/O error.
-       (multipass_split_callback) Add `bool' return type to indicate I/O
-       error.  Propagate errors.
-
-       * vfm.h: (struct case_source_class) Change `read' return type from
-       void to bool to allow reporting I/O errors.  Updated all
-       implementations to do so.
-       (struct case_sink_class) Change `write' return type from void to
-       bool to allow reporting I/O errors.  Updated all implementations
-       to do so.
-
-Sun Feb 12 18:12:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * pool.c: Useful new functions.
-       (pool_tmpfile) New function.
-       (pool_attach_file) New function.
-       (pool_detach_file) New function.
-       (pool_fopen) Reimplement in terms of pool_attach_file().
-       (pool_fclose) Reimplement in terms of pool_detach_file().  Fix
-       double-free.
-
-       * str.c: Useful new functions.
-       (ds_swap) New function.
-       (ds_rtrim_spaces) New function.
-       (ds_chomp) New function.
-       (ds_is_empty) New function.
-       (ds_first) New function.
-       (ds_last) New function.
-
-Sat Feb 11 21:51:21 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of finished, start_interactive globals.
-
-       * command.c: (cmd_exit) Instead of setting `finished', return
-       CMD_EOF.
-       (cmd_finish) Ditto.
-
-       * command.h: New enum CMD_EOF.
-
-       * main.c: (global var finished) Removed.
-       (global var start_interactive) Removed.
-       (main) Execute commands until CMD_EOF is the return value.
-       If parse_command_line() returns false, don't execute any commands
-       at all.
-
-       * cmdline.c: (parse_command_line) If the command line indicates we
-       shouldn't execute syntax files, return false instead of
-       terminating.
-       (usage) Don't terminate.
-
-Sat Feb 11 21:48:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of cur_proc global.  Replace by functions in err and tab
-       modules, which were the users.
-
-       * error.c: (static var command_name) New static var.
-       (err_vmsg) Use command_name.
-       (err_set_command_name) New function.
-
-       * tab.c: (static var command_name) New static var.
-       (tabi_title) Use command_name.
-       (tab_set_command_name) New function.
-
-       * command.c: (global var cur_proc) Removed.
-       (cmd_parse) Call err_set_command_name(), tab_set_command_name()
-       around executing command to set and clear command name.
-
-Sat Feb 11 21:44:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of glob.c, glob.h.
-
-       * Makefile.am: (pspp_SOURCES) Remove glob.c, glob.h.
-       
-       * dictionary.c: Move default_dict definition here.
-
-       * glob.c: Removed.
-       (global var FILTER_before_TEMPORARY) Variable removed.  All
-       references deleted.  The info in this var was redundant with
-       temp_dict, so they were changed to use temp_dict where needed.
-
-       * glob.h: Removed.
-
-       * start-date.c: New file. Moved get_start_date() here.
-
-       * start-date.h: New file.
-
-Fri Feb  3 20:34:52 2006  Ben Pfaff  <blp@gnu.org>
-       * font.h: (struct font_set) Removed, because unused.
-Sat Jan 28 17:45:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       Cleaner (faster?) way to compact cases.
-
-       * dictionary.c: (dict_compact_case) Removed.
-       (dict_needs_compaction) New function.
-       (struct copy_map) New structure.
-       (struct dict_compactor) New structure.
-       (dict_make_compactor) New function.
-       (dict_compactor_compact) New function.
-       (dict_compactor_destroy) New function.
-       
-Sat Jan 28 17:24:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       Cleanups.
-
-       * data-list.c: Make data_list_source_class static.
-       (dump_fixed_table) Use fh_get_name() to describe source of data.
-       (dump_free_table) Ditto.
-       (cmd_repeating_data) Eliminate special cases for inline file.
-
-       * dictionary.c: (dict_contains_var) Change return value from int to
-       bool.
-       (dict_rename_vars) Ditto.
-       (dict_create_vector) Ditto.
-
-Sat Jan 28 17:20:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       Add scratch file handles.
-
-       Now a file handle can refer to a disk file, to an in-memory
-       structure, or to the "inline" file, instead of just to a disk
-       file.  The introduction of new categories means that special cases
-       for the inline file in a few places could be eliminated, but it
-       also means that code that assumed that a handle refers to a file
-       has to check for that.
-
-       Also, now file handles can be freed, so code now must be sure not
-       to access a handle after closing it (with fh_close()).
-
-       * Makefile.am: Add any-reader.c, any-reader.h, any-writer.c,
-       any-writer.h, scratch-handle.c, scratch-handle.h,
-       scratch-reader.c, scratch-reader.h, scratch-writer.c,
-       scratch-writer.h to pspp_SOURCES.
-
-       * any-reader.c: New file.
-       
-       * any-reader.h: New file.
-       
-       * any-writer.c: New file.
-       
-       * any-writer.h: New file.
-
-       * scratch-handle.c: New file.
-       
-       * scratch-handle.h: New file.
-
-       * scratch-reader.c: New file.
-       
-       * scratch-reader.h: New file.
-
-       * scratch-writer.c: New file.
-       
-       * scratch-writer.h: New file.
-
-       * aggregate.c: Use an any_writer instead of an sfm_writer, to add
-       flexibility.
-
-       * apply-dict.c: Use an any_reader instead of an sfm_reader, to add
-       flexibility.
-
-       * command.def: Add CLOSE FILE HANDLE command.
-
-       * dfm-reader.c: Now fewer special cases for inline file.
-       (static var inline_open_cnt) Removed.
-       (static var inline_file) Removed.
-       (dfm_close_reader) Eliminate a special case for inline file.
-       Reorganize to avoid access-after-free.
-       (dfm_open_reader) Eliminate a special case for inline file.
-       (read_inline_record) Use bool instead of int.  No need to
-       increment line number.
-       (read_file_record) Use bool instead of int.
-       (read_record) Check whether file handle is inline file, instead of
-       for null pointer.
-       (dfm_eof) Ditto.
-       (dfm_expand_tabs) Ditto.
-       (dfm_push) Ditto.
-       (dfm_pop) Ditto.
-       (cmd_begin_data) Fix inaccurate check for whether the inline file
-       is in use--now we can tell by checking whether the inline file's
-       open count is positive.
-       
-       * file-handle-def.c: (struct file_handle) Reorder members.  Add
-       `deleted' member.  Add `referent' member.  Add `sh' member.
-       (static var default_handle) New variable.
-       (static var inline_file) New variable.
-       (fh_init) Initialize inline file.
-       (free_handle) New function.
-       (fh_done) Rewrite.
-       (fh_from_name) Don't return deleted handles.
-       (fh_from_filename) Ditto.
-       (fh_create) Removed.
-       (create_handle) New function.
-       (fh_create_file) New function.
-       (fh_create_scratch) New function.
-       (fh_inline_file) New function.
-       (fh_free) Rewrite.
-       (fh_open) Now requires a referent type mask and verifies it.  All
-       references updated.
-       (fh_close) If open_cnt goes to 0 on a deleted handle, free it.
-       (fh_is_open) New function.
-       (fh_get_referent) New function.
-       (fh_get_filename) Limit to handles that refer to files.
-       (fh_get_mode) Ditto.
-       (fh_get_record_width) Limit to handles that refer to files or the
-       inline file.
-       (fh_get_tab_width) Ditto.
-       (fh_get_scratch_handle) New function.
-       (fh_set_scratch_handle) New function.
-       (fh_get_default_handle) New function.
-       (fh_set_default_handle) New function.
-
-       * file-handle.h: (enum fh_referent) New type.
-       (enum fh_mode) Rename MODE_TEXT to FH_MODE_TEXT, MODE_BINARY to
-       FH_MODE_BINARY, and update all usages.
-
-       * file-handle.q: Add "scratch" as a possible mode.
-       (cmd_file_handle) Mention CLOSE FILE HANDLE in error message.
-       Use lex_end_of_command(), lex_sbc_missing().  Support creating
-       scratch handles.
-       (cmd_close_file_handle) New function.
-       (referent_name) New function.
-       (fh_parse) Now takes a referent type mask to specify handles that
-       can be accepted.  Updated all references.
-       
-       * filename.c: (fn_extension) New function.
-
-       * get.c: Use any_reader and any_writer and thereby merge code that
-       has been duplicated for each kind of file.  Also, we had something
-       here called `any_writer' before, so its name had to be changed to
-       `case_writer'.
-       (enum operation) Removed, because unused.
-       (struct get_pgm) Removed.
-       (get_pgm_free) Removed.
-       (get_source_destroy) Removed.
-       (get_source_read) Removed.
-       (global var get_source_class) Removed.
-       (static var case_reader_source_class) Removed.
-       (enum reader_command) New enum.
-       (struct case_reader_pgm) New struct.
-       (parse_read_command) New function.
-       (case_reader_pgm_free) New function.
-       (case_reader_source_destroy) New function.
-       (case_Reader_source_Read) New function.
-       (cmd_get) Rewrote as a call to parse_read_command().
-       (cmd_import) Ditto.
-       (struct any_writer) Rename to case_writer.  Drop `writer_type',
-       `writer' members in favor of an `any_writer' member named
-       `writer'.
-       (any_writer_destroy) Rename case_writer_destroy.  Use
-       any_writer_close().
-       (parse_write_command) Allow scratch files.  Use any_writer.
-       (any_writer_write_case) Rename case_writer_write_case().  Use
-       any_writer_write().
-`      (struct mtf_file) Use any_reader.
-       (cmd_match_files) Allow scratch files.  Use any_reader.
-       (mtf_free_file) Use any_reader_close().
-       (mtf_read_nonactive_records) Use any_reader_read().
-       (mtf_processing) Use any_reader_read().
-       (struct import_pgm) Removed.
-       (import_pgm_free) Removed.
-       (import_source_destroy) Removed.
-       (import_source_read) Removed.
-       (global var import_source_class) Removed.
-
-       * glob.c: (global var default_handle) Removed.  Replaced all
-       references by fh_get_default_handle() or fh_set_default_handle().
-
-       * pfm-read.c: (static var portable_to_local) Moved from inside
-       read_header() to top level.
-       (pfm_detect) New function.
-
-       * pfm-write.c: (pfm_write_case) Make case argument const.
-       Reorganize to avoid access-after-free.
-
-       * print.c: (dump_table) Use fh_get_name() to describe source of
-       data.
-
-       * sfm-read.c: (sfm_close_reader) Reorganize to avoid
-       access-after-free.
-       (sfm_detect) New function.
-
-       * str.c: (str_lowercase) New function.
-
-       * vfm.c: Use new compaction interface.
-       (static var compaction_necessary) Removed.
-       (static var compactor) New variable.
-       (open_active_file) Initialize compactor.
-       (write_case) Use compactor.
-       (close_active_file) Free compactor.
-       
-Wed Jan 11 19:28:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       Clean up file handle code in preparation to add scratch file
-       handles.
-       
-       * file-handle-def.c: Lots of formatting cleanup.  Added function
-       comments.
-       (struct file_handle) Renamed `length' member
-       to `record_width'.  All references updated.
-       (fh_init) New function.  Moved here from file-handle.q.
-       (fh_done) New function.  Moved here from file-handle.q and
-       rewrote.
-       (get_handle_with_name) Renamed fh_from_name().
-       (get_handle_for_filename) Renamed fh_from_filename().
-       (create_file_handle) Renamed fh_create().  Changed to take a
-       `struct fh_properties' instead of discrete values.  Updated all
-       references.
-       (create_file_handle_with_defaults) Removed.  Updated all
-       references to use fh_create() with fh_default_properties().
-       (fh_default_properties) New function.
-       (destroy_file_handle) Removed.  The code is now in fh_done().
-       (handle_get_name) Renamed fh_get_name().
-       (handle_get_filename) Renamed fh_get_filename().
-       (handle_get_record_width) Renamed fh_get_record_width().
-       (handle_get_tab_width) Renamed fh_get_tab_width().
-
-       * file-handle-def.h: Formatting, comment fixes.
-       (enum file_handle_mode) Renamed struct fh_mode.
-       (struct fh_properties) New structure.
-       (fh_init) Move prototype here from file-handle.h.
-       (fh_done) Ditto.
-       (fh_close) Ditto.
-
-       * file-handle.q: (static var handle_list) Removed.
-       (fh_parse) Don't add handle to handle_list, because
-       file-handle-def.c has its own list.
-       (fh_init) Moved to file-handle-def.c.
-       (fh_done) Ditto.
-
-Sun Jan 9 01:09  Jason Stover  <jason@sakla.net>
-
-       * regression.q: (run_regression) Moved coefficient initialization
-       to the linreg library. Altered other functions accordingly.
-
-Sat Jan  7 13:30:54 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-        * command.c data-in.c main.c: Fixed bug which crept in when 
-          separating getl from readline.
-
-        * vars-atr.c value-labels.h: Fixed constness of  val_labs_count.
-
-Fri Dec 23 20:59:01 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * getl.c error.c: Separated file_loc functionality from error.c
-
-Mon Dec 19 14:01:56 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * format.c: Additional error checking.
-       * getl.[ch]: Separated into getl.c and readln.c
-       * settings.[ch]: Made CC_CNT public
-
-Fri Dec 16 09:11:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q: Fixed buglet when cleaning up at end of procedure.
-
-Tue Dec 13 22:34:42 2005  Ben Pfaff  <blp@gnu.org>
-
-       Move global initialization and cleanup code into main.c.
-       Remove vestigial log infrastructure.
-       Minor related cleanups.
-       
-       * command.c: (shell) When execl() fails, use _exit(), not
-       err_hcf().
-
-       * error.c: (err_hcf) Move into main.c, rename terminate().  All
-       callers updated.
-       (err_done) New function with just the error.c-specific code for
-       err_hcf().  Called by terminate().
-
-       * glob.c: Removed all Borland C, DJGPP cruft.
-       (init_glob) Merged into main().
-       (done_glob) Merged into terminate().
-       (get_date) Removed.
-       (get_start_date) New function.  All users of curdate updated to call
-       this function instead.
-
-       * lexer.c: (lex_init) Moved initialization of tokstr here, from
-       init_glob().
-       (lex_done) Moved destruction of tokstr here, from done_glob().
-
-       * main.c: (global var pgmname) Removed.  Changed all references to
-       program_name, which is defined by gnulib.
-       (global var curdate) Removed.
-       (main) Moved init_glob() code here.  Merged parse_script() in
-       here.
-       (parse_script) Removed.
-       (terminate) Moved err_hcf() here from error.c and renamed
-       terminate().  Merged done_glob() code in here.  Call err_done().
-       All callers updated.
-       (i18n_init) New function.
-       (fpu_init) New function.
-
-       * output.c: (outp_init) Make void.
-       (init_default_drivers) New function.
-       (outp_read_devices) If no drivers are initialized successfully,
-       call init_default_drivers() to initialize a default driver.
-       (outp_done) Make void.
-       (static var prog) Make const.
-       (parse_options) Make parameter const.
-       (colon_tokenize) Make return value const.
-       (configure_driver) Change prototype to take a broken-down driver
-       configuration instead of a line of text.
-       (configure_driver_line) New function that does what
-       configure_driver() did before.
-
-       * q2c.c: (global var pgmname) Rename program_name.
-
-       * settings.c: (settings_init) Renamed from init_settings().
-       (settings_done) Renamed from done_settings().
-
-       * vfm.c: (global var last_vfm_invocation) Make static.
-       (vfm_last_invocation) New function.  All references to
-       last_vfm_invocation update to call this.
-       (procedure) Call update_last_vfm_invocation().
-       (internal_procedure) Ditto.
-       (update_last_vfm_invocation) New function.
-       
-Sat Dec 10 23:30:19 2005  Ben Pfaff  <blp@gnu.org>
-
-       Separate random numbers from other settings because of GSL
-       dependency.
-
-       * Makefile.am: Add random.c, random.h to sources.
-
-       * glob.c: (init_glob) Call random_init().
-       (done_glob) Call random_done().
-
-       * settings.c: (static var rng) Move to random.c.
-       (done_settings) Move freeing of RNG to random_done().
-       (get_rng) Move to random.c
-       (set_rng) Ditto.
-
-       * random.c: New file.
-
-       * random.h: New file.
-
-Sat Dec 10 18:13:36 2005  Ben Pfaff  <blp@gnu.org>
-
-       Separate settings and the SET command, for modularity.
-       
-       * Makefile.am: Add settings.c to sources.
-
-       * glob.c: (global variable test_mode) Removed.
-
-       * set.q: Remove all the set_* variables.  Remove a lot of obsolete
-       SPSS/PC+ settings.  Remove the aux_*() routines.  Moved the
-       get_*() functions into settings.c.  Rewrite the settings code and
-       functions to call the new set_*() functions.  Rewrite custom
-       currency parsing.  Write new by-hand cmd_show().
-
-       * esttings.c: New file.  Moved the get_*() functions here from
-       set.q.  Created new set_*() functions to correspond with them.
-       Regularized the names and types of some functions and updated
-       their callers.  Added static, file-scope variables to support the
-       settings.
-
-       * q2c.c: Remove "aux" support, which was only needed by set.q.
-       
-Sun Nov 27 06:43:46 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * data-out.c format.h: Added return value to data_out function.
-
-       * value-labels.c: Fixed bug in val_labs_remove.
-
-Sat Nov  5 18:37:26 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Remove devind.c, devind.h from list of source
-       files.
-
-       * devind.c: Removed.
-
-       * devind.h: Removed.
-
-       * list.q: Removed "support" for devind.
-
-       * output.c: Don't add devind class.
-
-Sat Nov  5 18:21:00 2005  Ben Pfaff  <blp@gnu.org>
-
-       * var.h: (struct variable) Make `init', `reinit' bool values.
-       Rearrange fields.
-
-Fri Nov  4 19:43:01 2005  Ben Pfaff  <blp@gnu.org>
-
-       * recode.c: Rewrote whole file, as clean-up.
-
-Fri Nov  4 19:37:50 2005  Ben Pfaff  <blp@gnu.org>
-
-       * pool.c: Don't make alignment exception for x86.
-       (pool_alloc) Return null for 0-size blocks.
-       (pool_alloc_unaligned) New function.
-       (pool_strndup) Removed.  Changed callers to use pool_clone_unaligned().
-       (pool_clone_unaligned) New function.
-       (pool_strdup) Use pool_clone_unaligned().
-
-       * var.h: (enum var_type) Give the NUMERIC, ALPHA enum this name.
-       (struct variable) Use `enum var_type' for `type'.
-
-       * vars-atr.c: (var_type_adj) New function.
-       (var_type_noun) New function.
-
-       * vars-prs: (parse_mixed_vars) Fix freeing code.
-       (parse_mixed_vars_pool) New function.
-
-Wed Nov  2 21:24:48 2005  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle-def.c: Needed another #include, to avoid missing
-       prototype warning.
-
-       * file-handle.q: (cmd_file_handle) Declarations must precede
-       statements.  Free parse data on success as well as on failure, to
-       avoid memory leak.
-
-       * get.c: (parse_write_command) Destroy dict on success, to avoid
-       memory leak.
-       
-       * data-list.c: (cmd_repeating_data) Fix usage of saw_occurs,
-       saw_length, saw_continued, saw_id, which were boolean but
-       incorrectly treated as bitmaps as result of a previous
-       half-finished cleanup.
-
-       * weight.c: (struct weight_trns) Unused, so removed.
-
-       * Makefile.am: Add range-prs.h to sources.
-
-Wed Nov  2 21:24:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       DO IF, LOOP cleanup.
-
-       * Makefile.am: Add ctl-stack.c, ctl-stack.h to source files.
-       Reformat source file list to list one file per file, so that
-       patches for future changes will be easier to read.
-
-       * ctl-stack.c, ctl-stack.h: New files.
-
-       * do-if.c: Rewrote whole file.
-
-       * do-ifP.h: Removed.
-
-       * loop.c: Rewrote whole file.
-
-       * glob.c: (global var ctl_stack) Move into ctl-stack.c.
-
-       * temporary.c: (cmd_temporary) Use ctl_stack_is_empty().
-
-       * vfm.c: (open_active_file) Use ctl_stack_clear().
-
-Wed Nov  2 21:18:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       New pool functions.
-       
-       * pool.c: (pool_create_at_offset) New function.
-       (pool_add_subpool) New function.
-
-       * pool.h: (pool_create_container) New macro.
-       
-       * expressions/parse.c: (expr_parse_pool) New function.
-       
-       * autorecode.c: (recode) Use pool_create_container().
-
-       * count.c: (cmd_count) Ditto.
-
-Wed Nov  2 19:59:32 2005  Ben Pfaff  <blp@gnu.org>
-
-       Clean up transformations, by getting rid of `struct trns_header',
-       replacing it by `struct transformation' that has a void *
-       `private' member.  Updated all uses of transformations to match,
-       which was a lot of code.  Only major related changes listed below.
-
-       * compute.c: (cmd_if) Use get_proc_func().
-       (cmd_compute) Use get_proc_func().
-       (get_proc_func) New function.
-
-       * glob.c: (global var m_trns) Change type to size_t.
-       (global var n_trns) Ditto.
-       (global var f_trns) Ditto.
-       (global var t_trns) Change type to struct transformation *.
-
-       * var.h: (struct trns_header) Removed.
-       (struct transformation) New.
-       (typedef trns_proc_func) Takes a void * instead of a struct
-       trns_header *.
-       (typedef trns_free_func) Ditto.
-
-       * vfm.c: (execute_transformations) Takes an array of
-       transformations instead of trns_headers.
-       (add_transformation) Change prototype from (trns_header *) to
-       (trns_proc_func *, trns_free_func *, void *).
-       (next_transformation) New function.
-
-Sat Oct 29 16:25:36 2005  Ben Pfaff  <blp@gnu.org>
-
-       * count.c: Major cleanups.  Rename practically everything.
-       Rewrite much of the code.  Use pools for memory management.  Use
-       the new parse_num_range().
-
-       * mis-val.c: (cmd_missing_values) Use the new parse_num_range().
-       (parse_number) Removed.
-
-       * missing-values.c: (mv_add_num_range) Don't add out-of-order
-       ranges, e.g. where low > high.
-
-       * pool.c: (pool_2nrealloc) New function.
-
-       * range-prs.c: New file.
-       (parse_num_range) New function.
-       (parse_number) New function.
-       
-Fri Oct 28 22:47:48 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix up potential overflows in size calculations by replacing
-       instances of pool_alloc(p, x * sizeof *y) by pool_malloc(p, x,
-       sizeof *y) everywhere I could find them.  Similarly by
-       pool_malloc(), pool_realloc().
-       (Order is important: pool_alloc(p, sizeof *y, x) will divide by 0
-       if x is 0.)
-
-       * pool.c: (pool_nalloc) New function.
-       (pool_nmalloc) New function.
-       (pool_nrealloc) New function.
-
-Thu Oct 27 11:16:53 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       Separated the definition of a file handle object from the stuff 
-       pertaining to the FILE HANDLE command.
-
-       * file-handle-def.[ch]: New files.
-
-       * dfm-read.c file-handle.h file-handle.q
-       
-Tue Oct 25 21:56:23 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix up potential overflows in size calculations by replacing
-       instances of xmalloc(x * sizeof *y) by xnmalloc(x, sizeof *y)
-       everywhere I could find them.  Similarly by xrealloc(), malloc().
-       (Order is important: xnmalloc(sizeof *y, x) will divide by 0 if x
-       is 0.)
-
-       * alloc.c: (nmalloc) New function.
-       (out_of_memory) Removed.  Replaced references by xalloc_die().
-
-       * sort.c: (allocate_cases) Fix segfault if memory allocation
-       fails.
-
-       * subclist.c: (subc_list_double_create) Use xnmalloc() instead of
-       malloc().
-       (subc_list_double_push) Use xnrealloc() instead of realloc().
-
-Wed Oct 26 08:43:51 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       Dictionary abstraction part #2
-
-       * algorithm.c format.c str.c sysfile-info.c val.h var.h vars-atr.c:
-         Removed unnecessary #include directives
-
-Mon Oct 24 21:35:08 2005  Ben Pfaff  <blp@gnu.org>
-
-       * groff-font.c (font_msg): Use err_vmsg() instead of incorrectly
-       trying to pass a va_list to tmsg().  Thanks to Jason Stover for
-       reporting this bug.
-
-Mon Oct 24 21:24:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       Work to get rid of GCC 4.0 warnings, part 2.
-
-       In many files, change `unsigned char' to `char'.  This often
-       requires adding casts to <ctype.h> functions.
-
-       * data-in.c: (parse_A) Use buf_copy_rpad().
-
-       * str.c: (str_copy_buf_trunc) New function.
-
-       * value-labels.c: (value_to_string) Fix mistaken use of strncpy(),
-       by rewriting.
-
-Mon Oct 24 13:42:32 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       Moved some definitions to make it easier to abstract a dictionary 
-       from the rest of PSPP.
-
-       * format-prs.c lex-def.[ch]:  New files.
-
-       * Makefile.am lexer.[ch] dictionary.c vars-atr.c vfm.c algorithm.c 
-         format.c:  Moved some functions between modules.
-       
-Sun Oct 23 19:28:08 2005  Ben Pfaff  <blp@gnu.org>
-
-       Work to get rid of GCC 4.0 warnings, part 1.
-       
-       In many files, change count parameters to parse_variables(),
-       etc. from `int' to `size_t'.  Also change related variables and
-       struct members.  Also change messages as needed (e.g. %d to %u
-       with cast to unsigned).  Also change arithmetic as necessary
-       (e.g. n >= m - 1 to n + 1 >= m). 
-
-       * crosstabs.q: (crs_custom_tables) Check for size_t overflow in
-       multiplication.
-
-       * q2c.c: (dump_declarations) Generate code for size_t instead of
-       int.
-       
-Thu Oct 20 18:18:40 2005  Ben Pfaff  <blp@gnu.org>
-
-       * output.c: (outp_read_devices) Fix message.
-
-Sat Sep 17 11:13:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       * matrix-data.c: (cmd_matrix_data) Change type of variable whose
-       address is passed to dict_get_vars() from size_t to int to match
-       John's change below.
-
-       * modify-vars.c: (validate_var_modification) Ditto.
-
-Mon Sep 12 19:26:06 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.[ch]  Changed cnt from size_t* to int* since that's
-       what it's called as, and on  x86_64 machines they're different sizes.
-       
-       * str.c: (ds_vprintf) Copied va_list args so they can be re-used
-       
-Sun Aug 21 00:12:24 2005  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (lex_sbc_only_once) New function.
-       (lex_sbc_missing) New function.
-
-Sun Aug 21 00:00:47 2005  Ben Pfaff  <blp@gnu.org>
-
-       * case.h: (case_str) Make it return `unsigned char'.
-
-Sat Aug 20 23:56:14 2005  Ben Pfaff  <blp@gnu.org>
-
-       Revamp SAVE, XSAVE, EXPORT.  Add (or at least parse) all the
-       subcommands that we didn't support.  Fix bug 13911.  Fix bug
-       reported by Adam Pierson (COMPRESSED and other subcommands didn't
-       work on SAVE).  Refactor all related code.
-       
-       * command.def: Add XEXPORT command.
-
-       * dictionary.c: (dict_delete_scratch_vars) New function.
-
-       * get.c: (cmd_get) Fix parsing.
-       (struct save_trns) Removed.
-       (cmd_save_internal) Removed.
-       (cmd_save) Removed.
-       (do_write_case) Removed.
-       (save_write_case_func) Removed.
-       (save_trns_proc) Removed.
-       (save_trns_free) Removed.
-       (trim_dictionary) Removed.
-       (struct export_proc) Removed.
-       (cmd_export) Rewrote.
-       (export_write_case_func) Removed.
-       (export_proc_free) Removed.
-       (enum writer_type) New enum.
-       (enum command_type) New enum.
-       (struct any_writer) New struct.
-       (any_writer_destroy) New function.
-       (parse_write_command) New function.
-       (any_writer_write_case) New function.
-       (parse_output_proc) New function.
-       (output_proc) New function.
-       (cmd_save) Rewrote.
-       (cmd_xsave) Rewrote.
-       (struct output_trns) New struct.
-       (parse_output_trns) New function.
-       (output_trns_proc) New function.
-       (output_trns_free) New function.
-       (cmd_xsave) Rewrote.
-       (cmd_xexport) New function.
-       (parse_dict_trim) New function.
-       (struct mtf_proc) Change `by_cnt' member type to `int'.
-       (cmd_import) Rewrote.
-
-       * pfm-write.c: (struct pfm_writer) Add `digits' member.
-       (pfm_writer_default_options) New function.
-       (pfm_open_writer) Add `opts' argument and handle options.
-       (write_float) Write only as many digits as `digits' member says.
-       (format_trig_double) Limit base-10 precision to LDBL_DIG.
-
-       * pfm-write.h: (enum pfm_type) Moved here from pfm-read.h.
-       (struct pfm_write_options) New struct.
-
-       * sfm-write.c: (sfm_writer_default_options) New function.
-       (sfm_open_writer) Remove `compress', `omit_long_names' args.  Add
-       `opts' argument.  Implement options.
-
-       * sfm-write.h: (struct sfm_write_options) New struct.
-
-       * expressions/helpers.c: (copy_string) Make `old' arg `unsigned
-       char *' instead of `char *'.
-       
-Sat Aug  6 21:29:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       * factor_stats.c: Needed <config.h> included earlier.
-
-       * percentiles.c: Needed to include <config.h>.
-
-       * val.h: Don't include "config.h".
-
-Sat Aug  6 21:26:27 2005  Ben Pfaff  <blp@gnu.org>
-
-       Clean up treatment of missing values by moving all the code into
-       one place.  All references to the missing value function were
-       updated, but only major changes are detailed below.
-
-       * Makefile.am: Add missing-values.c, missing-values.h to sources.
-
-       * apply-dict.c: (cmd_apply_dictionary) Use mv_resize().
-
-       * dictionary.c: (dict_create_var) Initialize `miss' member with
-       mv_init().
-       (dict_clone_var) Copy `miss' member with mv_copy().
-       
-       * get.c: (mtf_merge_dictionary) Use mv_copy().
-
-       * missing-values.c: New file.
-       
-       * missing-values.h: New file.
-
-       * mis-val.c: Rewrite.  New version implements updated semantics.
-
-       * pfm-read.c: (read_variables) Rewrite missing value handling.
-
-       * pfm-write.c: (write_variables) Rewrite missing value handling.
-
-       * sfm-read.c: (read_variables) Rewrite missing value handling.
-
-       * sfm-write.c: (write_variable) Rewrite missing value handling.
-
-       * sfmP.h: Include "magic.h" to get definition of
-       second_lowest_value.
-
-       * sysfile-info.c: (describe_variable) Rewrite missing value
-       handling.
-
-       * val.h: Include "magic.h" to get definition of
-       second_lowest_value.
-
-       * var.h: Include "missing-values.h".  Drop MISSING_* enums.
-       (struct variable) Remove `miss_type', `missing'.  Add `miss'.
-
-       * vars-atr.c: (is_num_user_missing) Removed--use
-       mv_is_num_user_missing().
-       (is_str_user_missing) Removed--use mv_is_str_user_missing().
-       (is_system_missing) Removed--use mv_is_value_system_missing().
-       (is_missing) Removed--use mv_is_value_missing().
-       (is_user_missing) Removed--use mv_is_value_user_missing().
-       
-Sun Jul 31 14:09:57 2005  Ben Pfaff  <blp@gnu.org>
-
-       Adopt use of gnulib for portability.
-
-       * Make.build: Add $(top_srcdir)/gl and $(top_builddir)/gl to
-       include path.
-
-       * Makefile.am: Remove bool.h, stat.h and change getline.[ch] to
-       getl.[ch] in pspp_SOURCES.  Remove libmisc, add libgl in
-       pspp_LDADD.
-
-       * In many source files, added an explicit inclusion of gettext.h
-       and definition of _ macro.  These are no longer in pref.h because
-       it interfered with definitions in a few gnulib source files.
-
-       * In many source files, changed #include "bool.h" to #include
-       <stdbool.h>, which is provided by gnulib.
-
-       * alloc.c: Removed functions defined in gnulib:
-       (xmalloc) Removed.
-       (xcalloc) Removed.
-       (xrealloc) Removed.
-       (xstrdup) Removed.
-       (out_of_memory) Redefined as wrapper for xalloc_die().
-
-       * alloc.h: Replace prototypes by #include "xalloc.h".
-
-       * casefile.c: Use full_read() and full_write() from gnulib instead
-       of our home-grown versions.
-       (full_read) Removed.
-       (full_write) Removed.
-
-       * getline.c: Renamed getl.c.
-
-       * getline.h: Renamed getl.h, updated all references.
-
-       * filename.c: (fn_readlink) Change to wrapper around xreadlink()
-       from gnulib.
-
-       * glob.c: Just #include <time.h> instead of the crazy rigmarole
-       here before.
-       (init_glob) Call set_program_name() to initial gnulib progname
-       module.
-
-       * html.c: (postopen) Use getlogin_r(), gethostname() from gnulib.
-
-       * permissions.c: Use "stat-macros.h" from gnulib.
-
-       * postscript.c: Just #include <time.h> instead of the crazy
-       rigmarole here before.
-
-       * q2c.c: (main) Make generated code #include "gettext.h".
-
-       * str.h: Get rid of most explicit declarations of standard
-       functions, in favor of including gnulib header files.
-
-       * expressions/evaluate.c: Ditto.
-
-       * expressions/operations.h.pl: Make generated code #include
-       <stdbool.h>, not "bool.h".
-
-Sat Jul 30 23:13:17 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/parse.c: (validate_function_args) Fix two msg() bugs
-       found by -Wformat.
-
-Sat Jul 30 23:10:01 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/evaluate.c: (expr_debug_print_postfix) Don't pass
-       null pointer to printf for %.*s.
-
-Sat Jul 30 23:05:33 2005  Ben Pfaff  <blp@gnu.org>
-
-       * vars-atr.c: (var_is_valid_name) Fix three msg() bugs found by
-       -Wformat.
-
-Sat Jul 30 22:58:33 2005  Ben Pfaff  <blp@gnu.org>
-
-       * rank.q: (parse_rank_function) Fix msg() bug found by -Wformat.
-
-Sat Jul 30 22:56:12 2005  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: (postopen) Cast `char' to `unsigned char' before
-       passing to isspace().
-
-Sat Jul 30 22:52:09 2005  Ben Pfaff  <blp@gnu.org>
-
-       * pfm-read.c: (read_variables) Fix msg() bug found by -Wformat.
-
-Sat Jul 30 22:50:57 2005  Ben Pfaff  <blp@gnu.org>
-
-       * histogram.c: Include <config.h>.
-
-Sat Jul 30 22:48:50 2005  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_match_files) Fix msg() bug found by -Wformat.
-
-Sat Jul 30 22:46:10 2005  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (check_common_specifier) Fix msg() bug found by
-       -Wformat.
-       (check_output_specifier) Ditto.
-
-Sat Jul 30 22:43:57 2005  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.q: (cmd_file_handle) Fix msg() bug found by
-       -Wformat.
-
-Sat Jul 30 22:41:44 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: (parse_Z) [WORDS_BIGENDIAN] Don't declare buf[], to
-       avoid "unused variable" warning.
-
-Sat Jul 30 22:38:46 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (find_word) Cast `char' to `unsigned char' before
-       passing to isspace().
-
-Sat Jul 30 22:36:29 2005  Ben Pfaff  <blp@gnu.org>
-
-       * case.c: (case_compare) Implement as delegating to
-       case_compare_2dict().
-
-Sat Jul 30 22:34:18 2005  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: Inclusion of <alloca.h> is unneeded.
-
-Sat Jul 30 22:01:32 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Make.build: Don't append -ansi to AM_CFLAGS for GCC.  Using
-       -ansi changes the behavior of header files significantly.  It
-       causes __STRICT_ANSI__ to be defined, and some headers interpret
-       that as cause to e.g. not use `long long' or __attribute__.  The
-       former example is bad when off_t is supposed to be `long long',
-       and the latter prevents -Wformat from working.
-
-Sun Jul 24 20:26:59 2005  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of dependency on libgmp by writing our own routine for
-       floating-point base conversion.
-
-       * pfm-write.c: (write_float) Rewrote.
-       (write_int) Rewrote.
-       (pow30_nonnegative) New function.
-       (pow30) New function.
-       (trig_to_char) New function.
-       (format_trig_digits) New function.
-       (recurse_format_trig_int) New function.
-       (format_trig_int) New function.
-       (should_round_up) New function.
-       (try_round_up) New function.
-       (format_trig_double) New function.
-
-Sun Jul 24 18:49:20 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: (parse_numeric) Allow "1+23" even for F format, for
-       compatibility.
-
-Sun Jul 24 18:47:37 2005  Ben Pfaff  <blp@gnu.org>
-
-       * pfm-read.c: (read_version_data) Read and ignore author field.
-
-Wed Jul  6 20:44:27 2005  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (mtf_processing) Don't assume that
-       mtf_compare_BY_values() always returns -1, 0, or 1.  Actually, it
-       returns a negative, zero, or positive result.  Fixes MATCH FILES
-       bug on Mac OS X reported by "Marshall DeBerry" <mdb@radix.net>.
-
-Mon Jul  4 18:01:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: [HAVE_SYS_TYPES_H] Really include <sys/types.h>.  The
-       preprocessor test for sys/types.h was accidentally inverted.  This
-       was bug 12789.
-
-Sun Jul  3 22:47:39 2005  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_match_files) Fix memory leak on `by' and on
-       `vfm_source'.
-
-       * getline.c: [HAVE_LIBREADLINE] (read_console) Fix memory leak on
-       `line'.
-
-       * vfm.c: (close_active_file) Remove unnecessary test.
-
-Sun Jul  3 21:45:32 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix NDEBUG compile errors.
-
-       * hash.h: Needed explicit #include <assert.h>.
-
-       * linked-list.c: (ll_next) First arg is UNUSED when NDEBUG is
-       defined.
-
-Sun Jun 12 23:44:38 2005  Ben Pfaff  <blp@gnu.org>
-
-       Implement embedding for PostScript driver.  Fixes bug 12970.
-
-       * ascii.c: Fix compiler warnings.
-
-       * html.c: Ditto.
-
-       * chart.h: Add `file' member.
-
-       * output.h: (struct outp_class) initialise_chart, finalise_chart
-       should take outp_driver *, not outp_class *.  Update all
-       references.
-
-       * plot-chart.c: (chart_create) Fix segfault when there are no
-       output drivers at all.
-       (chart_submit) Call d->class->finalise_chart.
-
-       * postscript.c: (ps_open_page) Set cp_y to 0.
-       (ps_submit) New function.
-       (ps_chart_initialise) Implement.
-       (ps_chart_finalise) Implement.
-       (static var postscript_class) Add ps_submit.
-       (static var epsf_class) Add ps_submit.
-       
-
-Sun Jun 12 14:54:40 2005  Ben Pfaff  <blp@gnu.org>
-
-       Did some more work on bug 12859 and then realized that a *good*
-       solution would require some fundamental restructuring.  For now,
-       I'm marking REPEATING DATA unimplemented, and then we can revisit
-       it post-0.4.0.
-       
-       * command.def: Make REPEATING DATA unimplemented.
-
-       * data-list.c: (cmd_repeating_data) Assume inline file is 80
-       characters wide.
-       (realize_value) Revert previous changes; no longer needed.
-       Updated all callers.
-
-       * error.c: (err_hcf) Set nfile_loc, mfile_loc to 0 after freeing
-       file_loc, to avoid bad references later.
-
-       * str.c: Fix typo.
-
-Tue Jun  7 00:14:09 2005  Ben Pfaff  <blp@gnu.org>
-
-       Make some code tolerant of reentry.  Should not be needed if other
-       code is correct but it is good to be generally tolerant.
-       
-       * error.c: (err_hcf) Set file_loc to null after free().
-
-       * output.c: (outp_done) Similar changes.
-
-       * str.c: (ds_destroy) Ditto.
-       
-Tue Jun  7 00:10:20 2005  Ben Pfaff  <blp@gnu.org>
-
-       Continue work on bug 12859, plus some code cleanup.
-       
-       * data-list.c: (cmd_repeating_data) Replace `seen' bitmap by
-       boolean variables.  Don't try to compute starts_end, cont_end for
-       inline file.  Calculate length only after parsing variable
-       specifications.  Add proper transformation to list.
-       (realize_value) If the rpd_num_or_var has no value, return new
-       DEFAULT_MEMBER argument (for use with inline file).
-       (repeating_data_trns_proc) Pass default values.
-
-       * dfm-read.c: (dfm_close_reader) Only skip data if *not* still
-       open, and only if we actually started reading data.
-
-Sun Jun  5 18:39:36 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 11894.
-       
-       * output.c: (outp_read_devices) Fix message.
-
-Fri May 27 12:34:43 WST 2005 John Darrington <john@darrington.wattle.id.au>
-       
-       * sort-prs.[ch] (newfiles), aggregate.c, sort.[ch]: Separated the guts 
-       of the sort algorithm from the parser for the SORT command.
-       
-       * rank.q: Added the parser for the RANK command.
-       
-Thu May 26 12:29:21 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 13192.
-
-       * sort.c: (sort_parse_criteria) Only set *saw_direction if
-       saw_direction is non-null.  Thanks to John Darrington for
-       reporting this bug.
-
-Tue May 24 21:52:55 2005  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (mtf_processing) Handle case of a lookup table as the
-       active file.  Thanks to John Darrington for reporting this bug.
-
-Wed May 25 10:27:02 WST 2005 John Darrington <john@darrington.wattle.id.au>
-       
-       * alloc.c alloc.h: (xcalloc) changed signature to imitate the
-       POSIX  calloc function.
-       
-       * crosstabs.q get.c vars-prs.c: Updated calls to xcalloc to
-       reflect new signature.
-
-       * sfm-read.c: Now much more robust in the face of badly formed
-       system files.
-
-Mon May 23 11:57:31 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       *sfm-read.c: Fixed some bugs regarding long string continuation
-       records, which the previous fix uncovered.
-
-Sat May 21 12:48:34 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * sfm-read.c, sfmP.h:  Allow reading of system files when the 
-       case_size value in the header is -1.  Also changed some Errors to 
-       Warnings when reading system files.
-
-Tue May 17 21:00:57 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c: (data_list_trns_free) Don't free the argument
-       because cancel_transformations() will do that itself.
-       (data_list_source_destroy) Destroy the argument to
-       data_list_trns_free(), because it no longer does so itself.
-
-Tue May 17 18:29:35 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c: (format_and_round) Don't output leading `-' if value
-       rounds to zero.
-
-Tue May 17 00:06:43 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 11119.
-
-       * som.c: (output_encodings) If some cell in the table won't fit
-       with the horizontal or vertical headers, cancel those headers.
-
-       * som.h: (struct som_table_class) Add fits_width, fits_length,
-       set_headers members.
-
-       * tab.c: (tabi_fits_width) New function.
-       (tabi_fits_length) New function.
-       (tabi_set_headers) New function.
-       (global var tab_table_class) Add the new functions as appropriate
-       members.
-       
-Mon May 16 22:34:06 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix rest of bug 13054.
-
-       * format.def: Fix EDATE, SDATE, ADATE, JDATE, QYR, MOYR, WKYR,
-       DATETIME, TIME system/portable file values.
-
-Mon May 16 22:31:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c: (parse_free) Use make_input_format().
-       
-       * data-out.c: (num_to_string) Use make_output_format().
-
-       * dictionary.c: (dict_create_var) Ditto.
-
-       * format.c: (global var f8_2) New var.
-       (make_input_format) New function.
-       (make_output_format) New function.
-
-       * get.c: (cmd_match_files) Use make_output_format().
-
-       * list.q: (cmd_list) Ditto.
-
-       * matrix-data.c: Ditto.
-
-       * sfm-read.c: (parse_format_spec) Check output specifier
-       thoroughly.
-
-       * tab.c: (tab_float) Use make_output_format().
-
-Sun May 15 23:38:10 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix more of bug 13054.
-       
-       * format.def: FMT_A should allow 255-character output.  FMT_AHEX
-       should allow 510-character input and output.
-
-       * data-out.c: (num_to_string) Get rid of NEW_STYLE option.
-       (convert_E) Handle non-finite values.
-       (try_F) Rewrite.
-       (format_and_round) New function.
-       (convert_infinite) New function used by try_F() and convert_E().
-
-Sun May 15 23:36:55 2005  Ben Pfaff  <blp@gnu.org>
-
-       Regularize string and buffer function names so that they make some
-       kind of sense.
-
-       * str.c: (mm_reverse) Rename buf_reverse().  Update all
-       references.
-       (mm_find_reverse) Rename buf_find_reverse().  Update all
-       references.
-       (mm_case_compare) Rename buf_compare_case().  Update all
-       references.
-       (st_compare_pad) Rename buf_compare_rpad().  Update all
-       references.
-       (str_compare_rpad) New function.
-       (st_bare_pad_copy) Rename buf_copy_str_rpad().  Update all
-       references.
-       (buf_copy_str_lpad) New function.
-       (st_bare_pad_len_copy) Rename buf_copy_rpad().  Update all
-       references.
-       (st_pad_copy) Rename str_copy_rpad().  Update all references.
-       (st_trim_copy) Rename str_copy_trunc().  Update all references.
-       (st_uppercase) Renamed str_uppercase().  Update all references.
-       
-Sat May 14 08:22:26 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * dfm-read.c: Fixed polarity of test in dfm-close-reader.  Closes 
-       Bug #13082
-
-Tue May 10 20:08:18 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: (data_in) Add assertion to check input specifier.
-
-       * data-out.c: (data_out) Add assertion to check output specifier.
-
-Tue May 10 19:56:35 2005  Ben Pfaff  <blp@gnu.org>
-
-       Start to fix bug 13054.
-
-       * format.c: (check_input_specifier) Improve error message.
-       (check_input_specifier) Check F, COMMA, and DOLLAR formats for
-       valid decimal places.
-       (check_output_specifier) Ditto (but different criteria).
-       (convert_fmt_ItoO) Assert valid input and output specifiers.
-       Also, if input specifier has *any* decimal places, make the output
-       specifier 1 place wider.
-
-Mon May  9 07:14:29 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * sysfile-info.c: Fixed bug [# 13024 ]
-
-Sun May  8 13:52:12 2005  Ben Pfaff  <blp@gnu.org>
-
-       "Fix" bug 13021 by disabling FILE TYPE.  Eventually, we should
-       actually implement it.
-
-       * command.c: (FILE_TYPE_okay) Always return 1.
-
-       * command.def: Change FILE TYPE, END FILE TYPE into UNIMPL.
-
-       * file-type.c: Add prototypes to get rid of warnings.
-
-Sun May  8 08:08:07 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * barchart.c box-whisker.c cartesian.c piechart.c plot-hist.c: Fixed 
-        more ISO/IEC 9899:1990 conformance issues.
-
-Wed May  4 23:54:02 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 12948.  See also new test in
-       tests/bugs/match-file-scratch.sh.
-       
-       * get.c: (mtf_merge_dictionary) Don't compact dictionary because
-       that deletes scratch variables that someone else might be using,
-       and because we can't reassign our sources' value indexes.
-       Instead, simply don't copy scratch variables into the master
-       dictionary.
-
-       * dictionary.c: (dict_compact_values) Delete variables from the
-       dictionary passed in, not from default_dict (!).
-
-Tue May  3 22:25:17 2005  Ben Pfaff  <blp@gnu.org>
-
-       Improve hash.c comments, error-checking.
-       
-       * hash.c: (struct hsh_table) [NDEBUG] Add hash_ordered member.
-       (hsh_create) size == 0 should *not* return NULL!  Set
-       hash_ordered.
-       (hsh_clear) Set hash_ordered.
-       (locate_matching_entry) Check hash_ordered.
-       (hsh_rehash) Rename rehash().  Add assertion.  Set hash_ordered.
-       (hsh_data) Set hash_ordered.  Add const-ness to return value and
-       update all callers.
-       (hsh_sort) Ditto.       
-
-Wed May  4 08:50:11 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile.c: Removed unnecessary #include <valgrind/valgrind.h>
-
-Tue May  3 19:14:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * copyleft.c: Updated copyright date.
-
-       * Makefile.am: Removed erroneous explicit "-lplot"
-
-       * examine.q oneway.q: Made these files conform to ISO/IEC 9899:1990
-
-Tue May  3 16:20:31 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * command.c command.def: Added description string for unimplemented commands.
-
-       * oneway.q: Sorted the hash tables before shipping out the results. Closes 
-       bug [#12931].
-
-Mon May  2 23:45:01 2005  Ben Pfaff  <blp@gnu.org>
-
-       Code improvements.
-       
-       * data-list.c:  (parse_fixed) Use lex_end_of_command().
-       (parse_free) Ditto.
-       (cmd_repeating_data) Set cont_end.num in right situations.
-       (parse_repeating_data) Remove redundant test.
-
-Mon May  2 23:37:19 2005  Ben Pfaff  <blp@gnu.org>
-
-       Partial fix for bug 12859.
-       
-       * data-list.c: (cmd_data_list) Add transformation properly in
-       vfm_source == NULL case.
-
-Mon May  2 23:27:28 2005  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (lex_error) Improve error messages.
-
-Mon May  2 22:28:17 2005  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_match_files) Check token type before trying to match
-       tokid.  Fixes bug 12923.
-
-Mon May  2 22:16:51 2005  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: [HAVE_SYS_TYPES_H] Include <sys/types.h>.  Fixes bug
-       12789.
-
-Mon May  2 22:02:52 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/generate.pl: (get_token) Make use of /g
-       backward-compatible with Perl 5.6.1.
-
-Sun May  1 23:00:19 2005  Ben Pfaff  <blp@gnu.org>
-
-       * var-display.c: (cmd_variable_alignment) Fix memory leak.
-       (cmd_variable_level) Ditto.
-
-Sun May  1 22:49:04 2005  Ben Pfaff  <blp@gnu.org>
-
-       Hash table had buggy deletion function.  The fix required changing
-       other functions to do probing in the required order.
-
-       * hash.c: (locate_matching_entry) Rewrite and change interface.
-       (hsh_rehash) Rewrite to use locate_matching_entry().
-       (hsh_probe) Ditto.
-       (hsh_find) Ditto.
-       (hsh_delete) Ditto.  Also, fix stupid bugs.
-
-Sun May  1 22:24:58 2005  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c: (dict_clone) Properly copy vectors.
-
-Sun May  1 22:07:58 2005  Ben Pfaff  <blp@gnu.org>
-
-       New implementation of long variable names.  Each variable has a
-       "normal" name, which may be up to 64 bytes long and which is used
-       for all normal operations.  Variables may have a "short" name,
-       which is limited to 8 bytes and used only for system and portable
-       file input and output.
-       
-       Make tokid case-preserving.  Update most uses of tokid to treat it
-       case-insensitively.
-
-       Update many commands to deal with long variable names.
-
-       * autorecode.c: (cmd_autorecode) Use strcasecmp() instead of strcmp().
-
-       * command.c: (cmd_parse) Ditto.
-       (match_strings) Use toupper() before comparing characters.
-       (conflicting_3char_prefixes) Use mm_case_compare() instead of
-       memcmp().
-       (cmd_match_words) Ditto.
-
-       * compute.c: (lvalue_parse) Use st_trim_copy() instead of
-       strncpy().
-
-       * count.c: (struct cnt_var_info) Change n[] to fit long var name.
-       Use st_trim_copy() instead of strcpy().
-
-       * data-in.c: (parse_enum) Use mm_case_compare() instead of
-       memcmp().
-
-       * data-list.c: (struct dls_var_spec) Change name[] to fit long var
-       name.
-       (parse_free) Use st_trim_copy() instead of strcpy().
-
-       * descript.c: (struct dsc_var) Change z_name[] to fit long var
-       name.
-       (try_name) Use strcasecmp() instead of strcmp().
-       (generate_z_varname) Use st_trim_copy() instead of strcpy().
-       (descriptives_compare_dsc_vars) Use strcasecmp() instead of
-       strcmp().
-
-       * dictionary.c: (struct dictionary) Removed `long_name_tab'
-       member.
-       (compare_long_names) Removed.
-       (hash_long_name) Removed.
-       (dict_create) Don't initialize `long_name_tab' member.
-       (dict_clone) Copy short names into new dictionary. 
-       (dict_clear) Don't clear `long_name_tab' member.
-       (dict_get_varname_block) Removed.
-       (dict_add_longvar_entry) Removed.
-       (free_nte) Removed.
-       (dict_destroy) Don't destroy `long_name_tab' member.
-       (dict_create_var_from_short) Removed.
-       (dict_create_var_x) Removed.
-       (dict_create_var) Get rid of longname handling.
-       Clear short name.
-       (dict_clone_var) Get rid of longname parameter and longname
-       handling.
-       (dict_lookup_var) Get rid of longname handling.
-       (dict_reorder_var) New function.
-       (dict_rename_var) Clear short name.
-       (dict_rename_vars) Get rid of longname handling.  Clear short
-       names.
-       (dict_create_vector) Support long vector names.
-       (dict_lookup_vector) Use strcasecmp() instead of strcmp().
-       (quasi_base27) Removed.
-       (make_short_name) Removed.
-       (compare_strings) New function.
-       (hash_string) New function.
-       (dict_assign_short_names) New function.
-
-       * file-handle.q: (get_handle_with_name) Use strcasecmp() instead
-       of strcmp().
-       (get_handle_for_filename) Support long handle names.
-
-       * file-type.c: (struct col_spec) Make `name' fit long var names.
-       (cmd_file_type) Use strcasecmp() instead of strcmp().
-
-       * flip.c: (make_new_var) Rewrite.
-       (flip_sink_write) Use st_trim_copy() instead of strncpy().
-
-       * format.c: (parse_format_specifier_name) Use mm_case_compare()
-       instead of memcmp().
-
-       * get.c: (cmd_save_internal) Rephrase.
-       (rename_variables) Drop test for identical variable name.
-       (struct mtf_proc) Change `first', `last' to fit long var name.
-
-       * hash.c: (hsh_hash_case_string) New function for case-insensitive
-       string hashing.
-
-       * lexer.c: (restore_token) Use st_trim_copy() instead of
-       strncpy().
-       (lex_get) Don't uppercase string when copying into tokid.
-       (lex_put_back_id) Use st_trim_copy() instead of
-       strncpy().
-
-       * list.q: (determine_layout) Consider length of variable names in
-       choosing vertical layout.
-
-       * matrix-data.c: (cmd_matrix_data) Use strcasecmp() instead of
-       strcmp().
-       (string_to_content_type) Ditto.
-
-       * modify-vars.c: (compare_variables_given_ordering) Ditto.
-       (struct var_renaming) Change `new_name' to fit long var name.
-       (compare_var_renaming_by_new_name) Use strcasecmp() instead of
-       strcmp().
-
-       * pfm-read.c: (read_variables) Disallow system variables in system
-       files.
-       (write_variables) Call dict_assign_short_names() and use
-       short_name[] members.
-
-       * repeat.c: (internal_cmd_do_repeat) Use strcasecmp() instead of
-       strcmp().
-
-       * sfm-read.c: (sfm_open_reader) Rewrite code for long variable
-       map.  Reorder variables into same order as long variable map.
-       (read_variables) Set short name.
-
-       * sfm-write.c: (sfm_open_writer) Call dict_assign_short_names().
-       (write_variable) Use st_bare_pad_copy().
-       (write_longvar_table) Rewrite.
-
-       * str.c: (mm_case_compare) New function.
-
-       * sysfile-info.c: (compare_vectors_by_name) Use strcasecmp()
-       instead of strcmp().
-
-       * t-test.q: (tts_custom_groups) Remove redundant test.
-       (tts_custom_pairs) Ditto.
-
-       * var.h: (struct variable) Change `name' to fit long var names.
-       Remove `longname'.  Add `short_name' member.  Reorder some
-       variables.
-       (struct name_table_entry) Removed.
-       (struct vector) Change `name' to fit long vector names.
-
-       * vars-atr.c: (var_is_valid_name) Allow long var names.
-       (compare_var_names) Use strcasecmp() instead of strcmp().
-       (compare_var_ptr_names) Ditto.
-       (hash_var_name) Use hsh_hash_case_string().
-       (hash_var_ptr_name) Ditto.
-       (var_set_short_name) New function.
-       (var_clear_short_name) New function.
-       (var_set_short_name_suffix) New function.
-
-       * vars-prs.c: (parse_DATA_LIST_vars) Support long names.
-       Use strcasecmp() instead of strcmp().
-       (struct array_var_set) Removed `longname_tab'.
-       (array_var_set_lookup_var_idx) Drop longname_tab support.
-       (array_var_set_destroy) Don't destroy `longname_tab'.
-       (var_set_create_from_array) Don't create `longname_tab'.
-
-       * vector.c: (cmd_vector) Use strcasecmp() instead of strcmp().
-       Support long names.
-
-       * expressions/parse.c: (word_matches) Use mm_case_compare()
-       instead of memcmp().
-       (compare_strings) New function.
-       (lookup_function) Use compare_strings() instead of strcmp().
-       
-Sun May  1 22:07:43 2005  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: (move_element) New function.
-
-Sun May  1 22:05:35 2005  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (parse_aggregate_functions) Always initialize
-       destvar.
-
-Sun May  1 22:03:47 2005  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (cmd_aggregate) Use dict_clone_var_assert().
-
-       * dictionary.c: (dict_clone) Ditto.
-       (dict_clone_var_assert) New function.
-
-       * get.c: (mtf_merge_dictionary) Use dict_clone_var_assert().
-
-Sun May  1 15:05:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * error.c: Added a string for the compiler version to the
-       request_bug_report_and_abort function.
-
-       * groff_font.c, font.c: Removed manpage(1) style references from 
-       comments, because RMS frowns upon them.
-
-Thu Apr 28 18:52:06 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/parse.c: Improve previous fix for bug 12858 (LAG).
-
-Fri Apr 29 09:28:00 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * expressions/parse.c: Added handler for OP_LAG_Vn and OP_LAG_Vs.  
-       Fixed bug [#12858] .
-
-Wed Apr 27 12:42:34 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * loop.c recode.c repeat.c: Fixed a couple of instances of SHORT_NAME_LEN 
-       which should be LONG_NAME_LEN
-
-Wed Apr 27 07:43:50 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * command.def echo.c:  Added the ECHO command.
-
-Mon Apr 25 22:55:59 2005  Ben Pfaff  <blp@gnu.org>
-
-       Finish fixing MATCH FILES (bug 11677).
-
-       * get.c: (trim_dictionary) Rewrite in terms of drop_variables(),
-       keep_variables(), rename_variables().
-       (drop_variables) New function.
-       (keep_variables) New function.
-       (struct mtf_file) Rename `in' to `in_name'.  Add `in_var'.
-       (cmd_match_files) Deal with in_var.  Use drop_variables(),
-       keep_variables().  When IN is specified, require BY.  Set master
-       variables after master dictionary is complete.  Add IN variables
-       after master dictionary is complete.
-       (mtf_free_file) Free `in_name'.
-       (mtf_delete_file_in_place) Set in_var value to 0.
-       (mtf_read_nonactive_records)  Rephrase.
-       (mtf_processing) Support IN.  Rephrase.  Fix bugs.
-       (mtf_merge_dictionary) Don't set master variables; we do that
-       later now.
-       (get_master) Don't insist that there's a master variable.
-       
-Mon Apr 25 22:55:22 2005  Ben Pfaff  <blp@gnu.org>
-
-       Kluge to make some variable renaming sort of work.
-       Needs real fix.
-
-       * dictionary.c: (dict_rename_var) Call dict_add_longvar_entry().
-
-Mon Apr 25 22:52:28 2005  Ben Pfaff  <blp@gnu.org>
-
-       Add functions for comparing sets of variables between cases.
-       Use the functions.
-
-       * case.c: (case_compare) New function.
-       (case_compare_2dict) New function.
-       
-       * aggregate.c: (struct agr_proc) Remove `prev_break' member.  Add
-       `break_case'.
-       (cmd_aggregate) Nullify break_case.  Don't call
-       initialize_aggregate_info().
-       (agr_destroy) Destroy break_case.
-       (aggregate_single_case) Rewrite.  Use case_compare().
-       (dump_aggregate_info) Copy from break_case into output.
-       (initialize_aggregate_info) Copy break_case from input.
-
-       * get.c: (mtf_compare_BY_values) Use case_compare_2dict().
-
-       * vfm.c: (equal_splits) Use case_compare().
-
-Sat Apr 23 17:01:04 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c vars-prs.c sfm-write.c: Fixed some memory leaks
-
-Sun Apr 17 23:08:15 2005  Ben Pfaff  <blp@gnu.org>
-
-       Start work on fixing MATCH FILES.
-
-       * get.c: (enum operation) Remove OP_MATCH.
-       (trim_dictionary) Change return value to bool.  Don't support
-       OP_MATCH.
-       (struct mtf_file) Remove `first', `last' members.
-       (struct mtf_proc) Add `first', `last' members.  Change mtf_case
-       from `struct ccase *' to `struct ccase'.  Remove `by' member.
-       (cmd_match_files) Essentially rewrite.
-       (mtf_free) Don't free `by' member.  Destroy `mtf_case' member.
-       (mtf_read_nonactive_records) mtf_ parameter is not unused.
-       (mtf_processing) Ditto.  Also rephrase some code.
-       (mtf_merge_dictionary) Rewrite for easy comprehension.  
-
-Sun Apr 17 23:06:00 2005  Ben Pfaff  <blp@gnu.org>
-
-       * matrix-data.c: (wr_output_data) [DEBUGGING] Fix compilation
-       error.
-
-       * q2c.c: (dump_token) [DEBUGGING] Fix compilation error.
-       
-Thu Apr 14 2005 John Darrington
-
-        * var-display.c: New file.
-
-       * format.h var.h sfm-read.c sfm-write.c dictionary.c :  Added 
-         display_width, measure and alignment parameters to variables.
-
-       * aggregate.c command.def compute.c count.c data-list.c descript.c
-         dictionary.c dictionary.h expr-prs.c file-type.c flip.c get.c 
-         lexer.c lexer.h loop.c modify-vars.c pfm-read.c recode.c repeat.c 
-         sfm-read.c sfm-write.c sfm-write.h sfmP.h val-labs.c val.h var.h 
-         vars-prs.c vector.c :  
-             - Replaced literal constants representing maximum variable name 
-               length with macro definitions. 
-             - Added support for long variable names.
-             - Changed lexer such that it no longer makes tokens upper
-               case, but relies upon case insensitive behaviour of commands.
-
-Mon Apr  4 22:27:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (parse_aggregate_functions) If dict_create_var()
-       fails, don't dereference the resulting null pointer (bug 12427).
-       Also, fix double free error.
-
-Sat Mar 19 23:06:02 2005  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (parse_aggregate_functions) Fix N_NO_VARS format.
-       (accumulate_aggregate_info) Set int1 to 1 for SUM.
-       (dump_aggregate_info) Only make SUM non-missing if there was at
-       least one variate.
-
-Sat Mar 19 14:48:19 2005  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (dump_aggregate_info) Properly test whether the
-       destination variable is numeric, when making the result
-       system-missing for columnwise missing values.
-
-Mon Mar 14 21:52:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * misc.h: Remove GCC specializations.
-
-Mon Mar 14 21:07:23 2005  Ben Pfaff  <blp@gnu.org>
-
-       Make sort stable (bug 12313).
-       
-       * sort.c: Don't need to include some headers anymore.
-       (static var min_buffers) New variable.
-       (static var max_buffers) New variable.
-       (static var allow_internal_sort) New variable.
-       (cmd_sort_cases) Add test mode.
-       (sort_execute) Rephrase.
-       (do_internal_sort) Don't try internal sorting if
-       allow_internal_sort is set.
-       (struct external_sort) Renamed `initial_runs' to `runs' and
-       updated all references.
-       (macro MIN_BUFFER_TOTAL_SIZE_RECS) Removed.
-       (macro MIN_BUFFER_SIZE_BYTES) Removed.
-       (macro MIN_BUFFER_SIZE_RECS) Removed.
-       (compare_initial_runs) Removed.
-       (struct record_run) Add member `idx'.
-       (write_initial_runs) Pass increasing values to process_case() as
-       index.
-       (process_case) Add `idx' parameter and use it to initialize new
-       `idx' member.
-       (allocate_cases) Limit allocated buffers to max_buffers.
-       (compare_record_run) Use new `idx' member for last resort
-       comparison, for stability.
-       (end_run) Call casefile_sleep() on irs->casefile, to prevent
-       running out of file descriptors.
-       (struct merge_state) Removed.
-       (merge) Don't need to allocate cases.  Always use MAX_MERGE_ORDER
-       unless we have fewer runs left.  Always merge consecutive runs,
-       for stability.  Return the final run.
-       (mod) Removed.
-       (choose_merge) New function.
-       (merge_once) Rewritten.
-
-Mon Mar 14 21:05:42 2005  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: (static var testing_mode) Move into
-       parse_command_line().
-       
-Mon Mar 14 21:05:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: (remove_range) New function.
-       (remove_element) New function.
-
-       * dictionary.c: (dict_delete_var) Use remove_element().
-
-       * flip.c: (cmd_flip) Ditto.
-
-Sun Mar 13 22:52:05 2005  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.q: (struct file_handle) `open_mode' should not be
-       const.
-       
-Sun Mar 13 22:40:54 2005  Ben Pfaff  <blp@gnu.org>
-
-       First phase of making SORT CASES stable (bug 12313).
-
-       * sort.c: (struct indexed_case) New structure.
-       (do_internal_sort) Rewrite to make internal sorting stable.
-       (compare_case_dblptrs) Removed.
-       (compare_indexed_cases) New function.
-
-Sun Mar 13 22:38:40 2005  Ben Pfaff  <blp@gnu.org>
-
-       Clean-ups.
-
-       * casefile.c: (casereader_read_xfer_assert) New function.
-
-       * dictionary.c: (dict_compact_case) New function.
-
-       * flip.c: (struct flip_pgm) New member idx_to_fv.
-       (cmd_flip) Initialize idx_to_fv member.
-       (destroy_flip_pgm) Free idx_to_fv member.
-       (flip_sink_write) Use struct flip_pgm member instead of case_sink
-       member.
-       (flip_sink_write) Ditto.
-
-       * vfm.c: (write_case) Use dict_compact_case() instead of
-       compact_case().
-       (compact_case) Removed.
-       (storage_source_create) Removed `dict' parameter.  All references
-       updated.
-
-       * vfm.h: (struct case_source) Removed `value_cnt' member.  All
-       references removed.
-       (struct case_sink) Removed `dict', `idx_to_fv' members.  All
-       references removed.
-
-Sun Mar 13 22:35:55 2005  Ben Pfaff  <blp@gnu.org>
-
-       More AGGREGATE fixes.
-
-       * aggregate.c: (accumulate_aggregate_info) Implement NMISS and
-       NUMISS for strings.  Fix FOUT, POUT, FGT, FLT, FIN, FOUT for
-       strings.
-       (initialize_aggregate_info) Fix initialization for MIN, MAX for
-       strings.
-
-Sat Mar 12 23:26:21 2005  Ben Pfaff  <blp@gnu.org>
-
-       Start work on testing and debugging AGGREGATE.
-
-       * aggregate.c: (cmd_aggregate) Use discrete bool variables instead
-       of a bit-map.  Require proper subcommand ordering.  Make OUTFILE
-       subcommand mandatory.
-       (parse_aggregate_functions) Check that PIN, POUT, FIN, FOUT
-       functions' arguments are in the correct order and swap them if
-       not.
-       (accumulate_aggregate_info) Make SUM include weights.  Add various
-       string functions.
-       (dump_aggregate_info) Add various string functions.
-       (initialize_aggregate_info) Initialize int1 for MIN, MAX.
-
-       * sort.c: (sort_parse_criteria) Add parameter for returning
-       whether any directions were specified.  All callers updated.
-
-Sun Mar 13 14:54:27 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q: Fixed erroneous logic in compare_group_binary.
-
-Sat Mar 12 13:29:21 2005  Ben Pfaff  <blp@gnu.org>
-
-       * split-file.c: (cmd_split_file) Ignore LAYERED and SEPARATE
-       keywords (bug 11628).
-
-Sat Mar 12 13:17:12 2005  Ben Pfaff  <blp@gnu.org>
-
-       * vfm.c: (procedure_with_splits) Fix bug 11492: end_func() must be
-       called *before* close_active_file().
-
-Sat Mar 12 12:20:57 2005  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.q: (struct file_handle) Change open_mode from
-       character pointer to 3-char array, for safety.  Updated all
-       references.
-
-Sat Mar 12 12:15:49 2005  Ben Pfaff  <blp@gnu.org>
-
-       Thanks to Ben Kujala <bkujala@oregonchildcare.org> for reporting
-       these bugs.
-       
-       * pfm-read.c: (read_header) Improve error message for many cases
-       in which the input is not actually a portable file.
-
-       * file-handle.q: (fh_open) When we give an error message, actually
-       return NULL.
-
-Fri Mar 11 11:50:30 2005  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (check_common_specifier) New function for checks
-       common to check_input_specifier() and check_output_specifier().
-       (check_input_specifier) Use check_common_specifier().
-       (check_output_specifier) Use check_common_specifier().
-       (check_string_specifier) Removed.
-       (check_specifier_type) New function.
-       (check_specifier_width) New function.
-       (get_format_var_width) Fix bug.
-
-       * formats.c: (internal_cmd_formats) Only accept numeric variables.
-
-       * lexer.c: (check_id) Rename lex_id_to_token(), make public,
-       update all references.  Make case-insensitive.
-
-       * pfm-read.c: Essentially rewrite the whole file.  Now much
-       cleaner.
-
-       * print.c: (check_string_width) New function.
-       (fixed_parse_compatible) Use check_string_width(),
-       check_specifier_type().
-       (dump_fmt_list) Ditto.
-
-       * str.c: (st_trim_copy) New function.
-       (st_uppercase) New function.
-
-       * vars-atr.c: (var_is_valid_name) New function.
-       
-       * expressions/parse.c: (type_coercion_core) Use
-       check_specifier_type().
-       
-Fri Mar 11 11:31:24 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/evaluate.c: (cmd_debug_evaluate) Fix memory leaks.
-
-       * expressions/parse.c: (no_match) Ditto.
-
-Wed Mar  9 09:54:27 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pspp_LDADD) Add libgsl-extras.a.
-
-       * expressions/helpers.c: (struct func_params) Removed.
-       (generalized_idf) Removed.
-       (cdf_beta) Removed.
-       (idf_beta) Removed.
-       (idf_fdist) Use gslextras_cdf_beta_Pinv() instead of idf_beta().
-
-       * expressions/operations.def: Implement IDF.BETA, CDF.BINOM,
-       CDF.GEOM, CDF.HYPER, CDF.NEGBIN, CDF.POISSON using gsl-extras.
-       Implement SIG.F, which I had overlooked previously.
-
-Tue Mar  8 12:47:53 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * command.c command.def glob.[ch] cmdline.c: Made DEBUG cmds
-       available only in testing mode.
-
-Sun Mar  6 23:25:40 2005  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: Use `bool' throughout, where relevant.
-
-Sun Mar  6 19:52:22 2005  Ben Pfaff  <blp@gnu.org>
-
-       DATA LIST with free-field formats should not have implied decimal
-       places (bug 12035).  Also clean up data-in.c a bit.
-
-       * data-in.h: (enum) Add DI_IMPLIED_DECIMALS.
-
-       * data-in.c: (apply_implied_decimals) New function.
-       (parse_numeric) Don't adjust exponent if DI_IMPLIED_DECIMALS not
-       set.  Also, get rid of gotos.
-       (parse_Z) Use apply_implied_decimals() if the field doesn't
-       contain a decimal point.
-       (parse_N) Use apply_implied_decimals().
-       (parse_IB) Ditto.
-       (parse_PIB) Ditto.
-       (parse_P) Ditto.
-       (parse_PK) Ditto.
-       (to_roman) Removed.
-       (parse_enum) New function.
-       (macro CHAR_IS_ROMAN) Removed.
-       (macro ROMAN_VALUE) Removed.
-       (parse_month) Use parse_enum().
-       (parse_weekday) Use parse_enum().
-       (parse_DATETIME) Use long for weekday.
-
-       * data-list.c: (read_from_data_list_fixed) Use
-       DI_IMPLIED_DECIMALS.
-
-Sun Mar  6 17:07:20 2005  Ben Pfaff  <blp@gnu.org>
-
-       When the lexer sees something like `-5' in the input, it has to
-       decide whether it's a negative numeric constant token or a '-'
-       token followed by a positive numeric constant token.  It always
-       decides on the former, and then the parser can call
-       lex_negative_to_dash() if it wants the latter.  However, this
-       doesn't work for the case of `-0', because negative zero is
-       (portably) indistinguishable from positive zero.  So now we divide
-       T_NUM into two tokens, T_POS_NUM and T_NEG_NUM, to make the
-       distinction clear.  This requires a little bit of extra effort,
-       because there were several references to T_NUM in the code base.
-       
-       * lexer.c: (lex_get) Use T_NEG_NUM and T_POS_NUM to distinguish
-       positive and negative numeric constants.
-       (lex_double_p) Renamed lex_is_number().  Changed return type to
-       bool.  Updated all relevant references to T_NUM to instead use
-       this function.
-       (lex_double) Renamed lex_number().  All references updated.
-       (lex_integer_p) Renamed lex_is_integer().  Changed return type to
-       bool.  All references updated.
-       (lex_token_representation) Understand T_NEG_NUM and T_POS_NUM.
-       (lex_negative_to_dash) Ditto.
-       (dump_token) Ditto.
-       
-       * lexer.h: (enum) Add T_POS_NUM, T_NEG_NUM.  Remove T_NUM.
-
-Sun Mar  6 22:09:20 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/operations.def: (NUMBER) Use DI_IMPLIED_DECIMALS.
-
-Sun Mar  6 19:33:24 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/operations.def: (VEC_ELEM_NUM) Treat user-missing
-       values as system-missing.
-
-       * expressions/parse.c: (parse_vector_element) Fix order of
-       arguments in call to expr_allocate_binary().
-
-Sun Mar  6 17:51:05 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/optimize.c: (optimize_tree) Fix optimization bug for
-       x**2.
-
-       * expressions/parse.c: (type_coercion_core) Set *node to NULL on
-       failure, as indicated by function comment.
-       (parse_binary_operators) Always return NULL on type_coercion()
-       failure.  Should have been doing this anyway, but bug in
-       type_coercion_core() filtered through.
-       (parse_add) Fix typo in user message.
-       (parse_primary) Understand T_NEG_NUM and T_POS_NUM.
-
-Sun Mar  6 10:47:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/operations.def: Add VALUE function.
-
-       * expressions/parse.c: (parse_function) Need an unary composite
-       node for variables in A TO B, not a variable node.  Use
-       allocate_unary_variable().
-       (parse_primary) Use allocate_unary_variable().
-       (allocate_unary_variable) New function.
-
-Thu Mar  3 23:53:32 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/PSPP_expressions.pm: Renamed it back to generate.pl
-       but fixed the real problem that was preventing the build from a
-       separate directory.  I liked it my way better ;-)
-       
-Thu Mar  3 23:17:51 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/parse.c: (expr_parse) Fix parameter type.  Thanks to
-       John Darrington <john@darrington.wattle.id.au> for reporting this
-       bug.
-
-Thu Mar  3 22:10:25 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * expressions/Makefile.am expressions/evaluate.h.pl
-         expressions/evaluate.inc.pl expressions/operations.h.pl
-         expressions/optimize.inc.pl expressions/parse.inc.p:
-
-         Renamed generate.pl to PSPP_expressions.pm and adjusted *.pl
-         to suit. 
-
-         Fixed everything so that it can be built from an arbitrary
-         directory.
-       
-Thu Mar  3 22:08:35 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * Makefile.am : Fixed up CLEANFILES target.
-
-Mon Feb 28 23:49:56 2005  Ben Pfaff  <blp@gnu.org>
-
-       * str.h: Changed `struct len_string' to `struct fixed_string', a
-       more accurate name.  Updated all references.
-
-Mon Feb 28 23:35:30 2005  Ben Pfaff  <blp@gnu.org>
-
-       Redo calendar support.  Should now be bug-for-bug compatible.
-       
-       * calendar.c: New file.
-
-       * calendar.h: New file.
-
-       * data-in.c: Use new calendar functions.
-       (parse_sign) Change sense of return value.
-       (calendar_error) New function.
-       (ymd_to_ofs) New function.
-       (ymd_to_date) New function.
-       (parse_DATE) Use new function.
-       (parse_ADATE) Ditto.
-       (parse_EDATE) Ditto.
-       (parse_SDATE) Ditto.
-       (parse_JDATE) Ditto.
-       (parse_QYR) Ditto.
-       (parse_MOYR) Ditto.
-       (parse_WKYR) Ditto.
-       (parse_TIME) Ditto.
-       (parse_DTIME) Ditto.
-       (parse_DATETIME) Ditto.
-
-       * data-out.c: (convert_date) Use new calendar functions.
-
-       * error.c: (err_vmsg) Changed interface to be more sensible.
-       Updated all callers.
-       (dump_message) Don't double new-lines (why did we do this
-       anyway?).
-
-Mon Feb 28 23:30:25 2005  Ben Pfaff  <blp@gnu.org>
-
-       * sfmP.h: (macro flt64) Moved here from pref.h.orig.
-       (macro FLT64_MAX) Moved here from pref.h.orig.
-
-Mon Feb 28 23:28:01 2005  Ben Pfaff  <blp@gnu.org>
-
-       * set.q: Support SET EPOCH.
-       (static var set_epoch) New var.
-       (aux_stc_custom_epoch) New function.
-       (stc_custom_epoch) New function.
-       (get_epoch) New function.
-       (stc_custom_pager) [USE_INTERNAL_PAGER] Fix bug.
-
-       * format.c: Make it possible just to check whether a specifier is
-       valid without emitting an error message.
-       (parse_format_specifier_name) Change interface, update all
-       callers.
-       (check_input_specifier) Ditto.
-       (check_output_specifier) Ditto.
-       (parse_format_specifier) Ditto.
-
-Mon Feb 28 23:24:08 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add DEBUG POOL.
-
-       * pool.c: (pool_destroy) Fix bug in deleting this pool from its
-       parent.
-       (pool_clear) Properly account for size of pool gizmo.
-       (pool_realloc) Ditto.
-       (pool_clone) New function.
-
-       * pool.h: Mark our allocation functions MALLOC_LIKE.
-
-Mon Feb 28 23:21:26 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Move many definitions into new top-level
-       Make.build.  Add expressions to SUBDIRS.  Add calendar.c,
-       calendar.h.  Remove expr-evl.c, expr-opt.c expr-prs.c, expr.h,
-       exprP.h, expr.def.
-
-       * case.c: (case_resize) New function.
-       (case_swap) New function.
-
-       * casefile.c: Include mkfile.h.
-
-Fri Feb 25 21:11:35 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * sfm-read.c: Fixed a buglet which caused a crash when trying
-       to read a non-existent file.
-
-Sun Feb 13 16:11:13 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 11955.
-
-       * aggregate.c: (parse_aggregate_functions) Code cleanup.
-       Important part: get rid of spurious copying of function->format to
-       destvar->print and destvar->write.
-
-Fri Feb 11 00:08:36 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug 11916, which was confusing a variable's `index' member
-       with the variable's position in a var_set.  Although these are
-       usually the same, they are not for array `var_set's.
-       
-       Took advantage of this bug as an opportunity to clean up and
-       rewrite parse_var_set_vars().
-
-       * vars-prs.c: (parse_vs_variable_idx) New function.
-       (parse_vs_variable) Reimplement in terms of
-       parse_vs_variable_idx().
-       (parse_var_idx_class) New function.
-       (add_variable) New function.
-       (add_variables) New function.
-       (parse_var_set_vars) Rewritten.
-       (struct var_set) Change `lookup_var' member that returns a
-       variable into `lookup_var_idx' member that returns an int.
-       Updated the var set implementations in obvious corresponding ways.
-       Used compare_var_ptr_names(), hash_var_ptr_name() just added.
-       
-Fri Feb 11 00:06:03 2005  Ben Pfaff  <blp@gnu.org>
-
-       Use our global variable compare & hash functions and give them
-       better names.  Add similar functions for dealing with double
-       pointers to variables.
-       
-       * vars-atr.c: (compare_variables) Renamed compare_var_names().
-       (hash_variable) Renamed hash_var_name().
-       (compare_var_ptr_names) New function.
-       (hash_var_ptr_name) New function.
-       
-       * t-test.q: (cmd_t_test) Use global compare_var_names(),
-       hash_var_name().
-       (compare_var_name) Removed.
-       (hash_var_name) Removed.
-
-Fri Feb 11 00:04:39 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fix dictionary bug.
-       
-       * dictionary.c: (compare_variable_dblptrs) Rename
-       compare_var_ptrs() and fix it to properly dereference the double
-       pointers.
-
-Mon Feb  7 09:58:15 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       crosstabs.q examine.q oneway.q q2c.c:  Added a q2c feature to 
-       declare subcommands as mandatory.  Closed bug #11843
-
-Sat Feb  5 20:35:10 WST 2005 John Darrington <john@darrington.wattle.id.au>
-       
-       * getline.c command.[ch] command.def:  Added (very rudimentary)
-       support for line  completion when in interactive mode.  Partially 
-       addresses bug #11693
-       
-Mon Jan 31 09:52:51 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q factor_stats.c oneway.q output.c pfm-read.c: Fixed some
-       problems revealed by valgrind.
-
-
-Wed Jan 26 11:44:11 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * set.q: Affixed a fix to the previous fix such that we'll be OK now
-       whether or not PAGER is set.
-
-Wed Jan 26 09:25:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * set.q: Copied the string produced by getenv("PAGER") thus avoiding
-       "invalid free" errors.  Hopefully fixes bug #11722
-
-       * compute.c expr-prs.c: Check that lvalues are populated before 
-       attempting to destroy them.  Closes bug #11676
-
-Tue Jan 25 21:01:43 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * aggregate.c: Initialised the complete agr_proc structure.
-       Closes bug #11675
-
-
-Sun Jan 23 23:02:21 2005  Ben Pfaff  <blp@gnu.org>
-
-       * print.c: (print_trns_free) Close the dfm writer if there is one,
-       fixing a memory leak.
-
-Mon Jan 24 12:24:36 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * glob.c oneway.q q2c.c t-test.q vfm.c: Still *more* memory leaks 
-       fixed.
-
-
-Fri Jan 21 19:54:14 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * linked-list.[ch] Added
-
-       * examine.q file-handle.[hq] font.h glob.c groff-font.c postscript.c 
-         set.q:    Yet more memory leaks
-
-Tue Jan 18 23:12:40 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q examine.q : More memory leaks fixed.
-
-Tue Jan 18 19:26:59 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q  factor_stats.[ch] get.c pfm-read.c: Plugged numerous
-       memory leaks.
-
-Mon Jan 10 14:43:45 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * ascii.c cartesian.c casefile.c chart.h devind.c 
-         examine.q frequencies.q
-         html.c output.h piechart.c plot-chart.c plot-hist.c
-
-         Integrated the chart rendering into the output stream
-         (currently only works for html).
-         
-         Removed gratuitous use of ifndef NO_CHARTS, and replaced with
-         dummy-chart.c for compiling without charts.
-
-       * mkfile.[ch] Created.  
-
-       * som.[ch] tab.[ch]: Changed name of som_table to som_entity
-       Added type element so we can tell if it's a chart or a table.
-
-       * chart.h examine.q piechart.c plot-chart.c plot-hist.c: changed the 
-       API of charts to be more like that of tables.
-
-Thu Jan 13 21:00:02 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile.c main.c: Moved the SIGINT handler from casefile.c to
-       main.c. Removed the handler for SIGQUIT.
-
-Mon Jan 10 14:43:45 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile.c: Added a signal handler to delete temp files on 
-       SIGINT and SIGQUIT
-
-       * permissions.c Inhibited the PERMISSIONS command when SAFER is on.
-
-       * command.def Added a lot more unimplemented commands.
-
-       * copyleft.[ch] cmdline.c Moved legal information to copyleft.c
-
-Sat Jan  8 23:58:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: (compare_initial_runs) Needed additional level of
-       dereferencing.
-       (merge_once) Fix plenty of stupid mistakes.
-
-Sat Jan  8 23:55:27 2005  Ben Pfaff  <blp@gnu.org>
-
-       * casefile.c: (casefile_sleep) Need to flush_buffer() after
-       calling casefile_to_disk() or we will lose the last block in the
-       file if the casefile started out as disk-based.
-       (casefile_get_reader) Initialize reader->destructive to 0.
-       (cmd_debug_casefile) Add new test pattern.
-       (test_casefile) Define new test pattern to make sure
-       casefile_sleep() works properly.
-
-Fri Jan  7 08:00:05 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * Makefile.am chart.[ch]  histogram.[ch] piechart.c (Modified);
-          plot-hist.c plot-chart.c (Added) Reorganised these files in an
-          attempt to seperate the creation and processing of charts from their
-          actuall renedering.
-
-        * examine.q frequencies.q generated charts conditional upon the NO_CHARTS
-          macro.
-
-Thu Jan  6 18:48:58 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * main.c Added a signal handler for SIGFPE
-
-       * sort.c Somewhat more robust fix to the previous entry.
-
-Wed Jan  5 21:23:31 2005  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: (merge) Fix assertion for proper Huffman merge pattern:
-       0 == 1 modulo 1.  See Knuth 5.4.9 (vol. 3, 2nd ed.,
-       pp. 361).  Thanks to John Darrington <john@cellform.com.au> for
-       reporting the bug.
-
-Wed Jan  5 22:42:26 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * case.h Fixed bug # 11307
-       
-Wed Jan  5 08:30:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * val-labs.c Fixed bug which caused a crash if VALUE LABELS had
-       a trailing slash.
-
-Mon Jan  3 17:44:37 2005  Ben Pfaff  <blp@gnu.org>
-
-       * pfm-read.c: (read_variables) Remove direct manipulation of
-       v->aux, which is no longer needed.  Fixes bug 11483.
-
-Sat Jan  1 19:01:16 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * data-list.c Fixed a bug in parsing delimiters.
-
-       * group.c vars-atr.c Fixed buglet in hash/compare functions for alpha
-       values.
-
-       * percentiles.c Properly handled calculation of Tukey hinges where
-       the number of data is small.
-
-       * oneway.q Used the generic value_to_string function for independent
-       variable instead of trying to do it ourselves.
-
-       * box-whisker.c Fixed a buglet which caused a crash if the number of
-       data was zero
-
-
-Fri Dec 31 16:47:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q box-whisker.c chart.h Implemented boxplots in EXAMINE
-
-       * percentiles.c Fixed some bugs when calculating percentiles when
-       there's a small number of cases.
-
-Wed Dec 29 08:18:08 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * percentiles.[ch] Added. Calculates percentiles and Tukey hinges
-
-       * examine.q factor_stats.[ch]  Added calculation of percentiles
-
-Fri Dec 24 15:09:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q Fixed bug #11227 Made t-test work when the independent
-       variable is alpha
-
-Sat Dec 11 11:43:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * factor_stats.c Fixed calculation of trimmed mean under various
-       special conditions.
-
-Sat Dec  4 17:14:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * histogram.c chart.[ch] factor_stats.c frequencies.q
-
-       Added code to calculate sensible histogram ranges and limits.
-
-Thu Dec  2 13:37:43 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * chart.h Updated to reflect many API changes.
-
-       * cartesian.c chart.c Moved the definitions of chart_write_{xy}scale from 
-       cartesian.c and into chart.c
-
-       * factorstats.[ch] Added the histogram calculations
-
-       * casefile.c Removed an unused variable.
-
-       * frequencies.q examine.q histogram.c  Reworked the API for 
-       histograms.
-
-       * piechart.c  Revised the API for piecharts.
-
-       * var.h  Moved the definitions of freq_tab and freq out of var.h
-       and into frequencies.q where they belong.
-       
-Tue Nov 30 21:10:20 2004  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: (flip_file) Check for off_t separately from fseeko(),
-       using AC_TYPE_OFF_T.
-
-Tue Nov 30 08:47:41 2004  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: (flip_file) If fseeko() is not available, use long int
-       for off_t.  Thanks to "Marshall DeBerry" <mdb@radix.net> for
-       reporting the problem.
-
-Mon Nov 29 12:20:59 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q factor_stats.[ch] Changed stderr to se_mean to avoid
-       conflict with stdio.
-
-Sun Nov 21 10:32:41 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * var-labs.c (var_to_string) Now returns null if the variable is null
-
-       * value-labels.c (value_to_string) Made it return null if either the 
-       value or the variable is null.
-
-       * hash.c (hsh_clear) Fixed a buglet.
-
-       * examine.q  factor_stats.[ch] Largely  rewrote, because I'd started 
-       with  the wrong model.
-
-       * casefile.[ch] Added a function to return the casereader.case_idx 
-       member
-
-       * examine.q  Implemented the extreme values results.
-
-John Darrington <john@darrington.wattle.id.au>
-
-       * settings.h set.c glob.[ch] frequencies.q q2c.c error.c lexer.[ch] 
-          output.[ch] getline.c 
-
-          Plugged some memory leaks
-
-Mon Nov 15 23:47:40 2004  Ben Pfaff  <blp@gnu.org>
-
-       Adopt GSL random number generators, paving the way for providing
-       the complete suite of random number generators on expressions.
-       
-       * Makefile.am: Remove random.c, random.h.
-
-       * random.c: Removed.
-
-       * random.h: Removed.
-
-       * algorithm.c: (algo_default_random) Use GSL functions.
-
-       * casefile.c: (test_casefile) Use GSL RNG functions.
-
-       * expr-evl.c: (expr_evaluate) Use GSL RNG functions for OP_NORMAL,
-       OP_UNIFORM.
-
-       * sample.c: (cmd_sample) Use GSL RNG functions.
-       (sample_trns_proc) Ditto.
-
-       * set.q: (static var set_seed) Removed.
-       (static var seed_flag) Removed.
-       (static var rng) New variable.
-       (aux_stc_custom_seed) No seed value anymore, don't print anything.
-       (stc_custom_seed) Use new seed functions.
-       (seed_is_set) Removed.
-       (get_rng) New function that composes the entire external
-       interface.
-       (set_rng) New function.
-       (random_seed) New function.
-
-Mon Nov 15 22:08:25 2004  Ben Pfaff  <blp@gnu.org>
-
-       * expr-evl.c: (expr_evaluate) Fix XDATE.JDAY formula.  Thanks to
-       John Darrington <john@darrington.wattle.id.au> for reporting this
-       bug.
-
-Tue Nov 16 13:19:18 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * permissions.c command.def Added the PERMISSIONS command
-
-Mon Nov 15 01:33:32 2004  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: (dump_header) Don't try to emit #includes at very top of
-       output file because that will precede #include <config.h>, which
-       is bad.
-       (main) Add needed headers to /* (header) */ code.
-
-Mon Nov 15 01:21:36 2004  Ben Pfaff  <blp@gnu.org>
-
-       Instead of making system or portable file readers responsible for
-       dropping and reordering variables, make them read full cases and
-       let the caller take care of any changes.
-
-       * get.c: New "case map" structure to handle this.  Use for GET,
-       IMPORT, MATCH FILES.  Essentially rewrite the whole file.
-
-       * pfm-read.c: (pfm_read_case) Read into provided case.  Signature
-       changed appropriately.
-
-       * sfm-read.c: (sfm_read_case) Ditto.
-
-Mon Nov 15 00:47:45 2004  Ben Pfaff  <blp@gnu.org>
-
-       Decided that case_serialize() and case_unserialize() were too
-       abstract.  Also we need a couple more functions to avoid excessive
-       copying for data in/out fast paths.
-
-       * case.c: (case_serial_size) Removed.
-       (case_serialize) Rename case_to_values() and make its argument
-       explicitly an array of union values.
-       (case_unserialize) Rename case_from_values() and make its argument
-       explicitly an array of union values.
-       (case_data_all) New function.
-       (case_data_all_rw) New function.
-
-       * casefile.c: (struct casefile) Change buffer from array of
-       unsigned char to array of union value for better accuracy.
-       Redefine buffer_used and buffer_size in terms of values, not
-       bytes.  Remove case_size because it is now redundant with
-       value_cnt.  Fix up all references to these members.
-
-Mon Nov 15 00:45:46 2004  Ben Pfaff  <blp@gnu.org>
-
-       * barchart.c: (struct subcat) Make `label' member const to silence
-       GCC warning with -Wwrite-strings.
-
-       * cartesian.c: (struct dataset) Ditto.
-
-       * case.c: Don't re-define NDEBUG if already defined.
-       Add lots of comments.
-
-       * str.c: Fix includes.
-
-       * crosstabs.q: Fix includes.
-
-       * examine.q: Fix includes.  Fix GCC warning about unused
-       variables.
-       
-       * frequencies.q: (stat macro) Removed and replaced where used by
-       its expansion.
-
-       * list.q: Fix includes.
-
-       * oneway.q: Fix includes.
-
-       * piechart.c: Fix includes.  Only define M_PI if not already
-       defined.
-
-       * sfm-read.c: (bswap) New function.
-       (bswap_int32) Write in terms of bswap.
-       (bswap_flt64) Ditto.
-
-       * str.c: (ds_data) Add external definition here, needed because
-       str.h has only an `extern inline' version.
-
-       * value-labels.c: Fix includes.
-
-Mon Nov 15 00:40:55 2004  Ben Pfaff  <blp@gnu.org>
-
-       Instead of providing a system or portable file writer with a raw
-       case in the format needed for output, provide it with a regular
-       case.  The writer takes care of any needed translation.
-
-       * aggregate.c: Adopt new scheme for AGGREGATE.
-       (struct agr_proc) sfm_agr_case member removed.
-       (write_case_to_sfm) Removed because the new interface is easier to
-       use.
-
-       * get.c: Adopt new scheme for SAVE, XSAVE, EXPORT.
-
-       * pfm-write.c: Implement new scheme.
-
-       * sfm-write.c: Ditto.
-
-Mon Nov 15 00:32:24 2004  Ben Pfaff  <blp@gnu.org>
-
-       Instead of treating `struct file_handle' as a class to subclass
-       into data files, system files, and portable files, instead use it
-       as a helper that coordinates access.  Now it is opaque, too.
-
-       This means that most references to a struct file_handle are now
-       changed into references to one of struct dfm_reader, struct
-       dfm_writer, struct sfm_reader, struct sfm_writer, struct
-       pfm_reader, or struct pfm_writer, according to what's being read
-       or written.
-
-       Most related changes are only worth summarizing briefly.
-
-       * dictionary.c: (dict_clear) Destroy aux data in deleted
-       variables.
-       (dict_clear_aux) New function.
-       (dict_create_var) Initialize aux, aux_dtor.
-       (dict_delete_var) Destroy aux data in deleted variable.
-
-       * file-handle.h: (struct fh_ext_class) Removed.
-       (struct file_handle) Removed.
-       (fh_init_files) Removed.
-
-       * file-handle.q: Changed references to a handle's `private' member
-       to direct references.
-       (struct private_file_handle) Renamed file_handle.
-       Add next, open_cnt, type, open_mode, aux members.
-       (struct file_handle_list) Removed.
-       (extern var inline_file) Removed.
-       (static var file_handles) Changed from file_handle_list * to
-       file_handle *.
-       (create_file_handle) Initialize new members.
-       (fh_close_handle) Removed.
-       (mode_name) New function.
-       (fh_open) New function.
-       (fh_close) New function.
-       (fh_parse_file_handle) Renamed fh_parse().
-
-       * glob.c: (init_glob) Remove fh_init_files() call.
-       
-       * aggregate.c: use sfm_writer.
-       (create_sysfile) Removed because the new interface is simpler.
-       
-       * apply-dict.c: Use sfm_reader.
-
-       * data-list.c: Use dfm_reader.
-
-       * file-type.c: Use dfm_reader.
-
-       * get.c: Use sfm_reader, sfm_writer, pfm_reader, pfm_writer.
-
-       * inpt-pgm.c: Use dfm_reader.
-
-       * print.c: Use dfm_writer.
-
-       * sysfile-info: Use sfm_reader.
-
-       * dfm-read.c: Adopt new file handle infrastructure.
-
-       * dfm-write.c: Ditto.
-
-       * pfm-read.c: Ditto.
-       
-       * pfm-write.c: Ditto.
-
-       * sfm-read.c: Ditto.
-
-       * sfm-write.c: Ditto.
-       
-Mon Nov 15 00:31:44 2004  Ben Pfaff  <blp@gnu.org>
-
-       Break dictionary functions into separate header file.
-
-       * dictionary.h: New file.
-
-       * var.h: Moved dict_*() functions to dictionary.h.
-
-Mon Nov 15 00:30:33 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of procedure-specific union in struct variable, using
-       instead a void * pointer and a destructor function.
-
-       Most related changes are only worth brief summaries.
-
-       * crosstabs.q: Fix includes.  Use new struct var_range in lieu of
-       old p.crs member in struct variable.
-       
-       * frequencies.q: Fix includes.  Use new struct var_freqs in lieu
-       of old p.frq member in struct variable.
-
-       * histogram.c: (draw_histogram) Takes new freq_tab arg because
-       it's no longer possible to grab this from var->p.frq.
-
-       * piechart.c: (draw_piechart) Ditto.
-
-       * group.c: (group_proc_get) New function.
-
-       * levene.c: Use group_proc_get() in lieu of old p.grp_data member
-       in struct variable.
-
-       * oneway.q: Ditto.
-
-       * t-test.q: Ditto.
-
-       * main.c: (execute_command) Clear aux data in default_dict after
-       each command.  (It's debatable whether this should be done.)
-
-       * matrix-data.c: Use new struct mxd_var in lieu of old p.mxd
-       member in struct variable.
-
-       * means.q: Get rid of integer mode, which is not included in
-       recent SPSS and was the only code that wanted per-variable private
-       data.
-
-       * var.h: (struct crosstab_proc) Removed.
-       (struct frequencies_proc) Removed.
-       (struct list_proc) Removed.
-       (struct get_proc) Removed.
-       (struct means_proc) Removed.
-       (struct matrix_data_proc) Removed.
-       (struct match_files_proc) Removed.
-       (lots of enums) Removed.
-       (struct variable) Removed members `p', `get'.  Add member
-       `aux_dtor'.
-
-       * vars-atr.c: (var_attach_aux) New function.
-       (var_detach_aux) New function.
-       (var_clear_aux) New function.
-       (var_dtor_free) New function.
-       (discard_variables) Use NULL instead of inline_file.
-
-Fri Nov 12 10:07:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * value-labs.c  Fixed the implmentation of value_to_string, so 
-       that it properly handles alpha values.
-
-       * oneway.q  Changed instances where labels were being probed manually, 
-       to use the canonical {var,value}_to_string functions
-
-Thu Nov 11 21:01:31 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q cartesian.c chart.[ch]   Added normal and detrended normal
-       plots.  Changed the API of the cartesian plot to be a much lower level
-       thing.
-
-Sun Nov  7 17:25:04 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q Added some of the parametric calculations
-
-       * factor_stats.[ch]  Created
-       
-Sat Nov  6 21:24:31 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q  Changed the definition of factors to be a composite, and
-       dealt with the consequences.
-
-Sat Nov  6 20:40:38 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q Fixed problem where examine wasn't dealing properly with 
-       splits
-
-Sat Nov  6 14:49:47 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * oneway.q Fixed problem where oneway wasn't dealing properly with 
-       splits
-
-Thu Nov  4 11:09:01 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * q2c.c examine.q  Fixed a bug (feature?) whereby arrays in the
-       command which had settings didn't get the appropriate code
-       generated.
-
-       * val.h value-labels.[ch] var-labs.c Added v*to_string functions
-       to convert variables/values to strings.
-
-       * examine.q  Added framework for the EXAMINE command.
-
-Mon Nov  1 12:46:17 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * q2c.c frequencies.q set.q t-test.q  Fixed the q2c parsing of DBL 
-       subcommand types.  Changed frequencies.q to use it rather then the 
-       custom parser.  Dealt with the consequences.  Added a test for NTILES
-       subcommand of frequencies.
-
-Sat Oct 30 09:16:29 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * oneway.q   Fixed up the behaviour when given missing values
-
-       * levene.c oneway.q Fixed a buglet with the levene statistic and
-       incorporated the levene test into the oneway command.
-
-        * group.h  t-test.q  Moved the CMP_EQ and CMP_LE symbols out of 
-       global scope, since they're only relevant to T-TEST
-
-Fri Oct 29 17:39:03 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-        * group.c group.h group_proc.h levene.c oneway.q t-test.q
-
-       Made the t-test more consistent
-       with the way it handles groups.  That is, it now uses a hash instead
-       of an array of 2.  Also, made the levene.c file independent of the 
-       implementation of the t-test.  So now levene should be fine for both
-       t-test and anova.
-
-       * Added an oneway.q file for one way anova
-
-Wed Jun  2 22:08:02 2004  Ben Pfaff  <blp@gnu.org>
-
-       * descript.c: (cmd_descriptives) Remove harmless but bogus test in
-       STATISTICS parsing.
-
-Mon May 31 20:45:24 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fix memory leaks.
-
-       * data-list.c: (cmd_data_list) Free dls->delims on lossage.
-       (data_list_trns_free) Free dls->delims.
-
-       * t-test.q: (tts_custom_pairs) Free vars.
-       (ssbox_one_sample_init) Fix tab_vline() argument.
-       (ssbox_independent_samples_init) Ditto.
-       (trbox_paired_init) Ditto.
-       (trbox_one_sample_init) Ditto.
-
-Mon May 31 17:19:27 2004  Ben Pfaff  <blp@gnu.org>
-
-       Generalize casefiles to the extent that we can use them for
-       sorting and other kinds of data transformations.  Change cases to
-       be copy-on-write to improve memory efficiency in common cases.
-       Every access to a member of a `struct ccase' was changed to be a
-       call to a case_*() function, especially case_data(), case_num(),
-       case_str(), or case_data_rw().  Many instances of a local variable
-       named "case_num" were changed to "case_idx" as a consequence.
-       Many `struct ccase *' were changed to actual `struct ccase'
-       because of copying semantics of cases.  In several places there
-       was a choice between updating debug code to work with the new ADTs
-       or just deleting it because it was useless; I chose to delete it.
-       * Makefile.am: (pspp_SOURCES) Add case.c, case.h.
-
-       * case.c: New file.
-
-       * case.h: New file.
-
-       * aggregate.c: (struct agr_proc) Change type of `sort' to
-       sort_criteria *.  Add `break_vars', `break_var_cnt' members.
-       Rename `vars' to `agr_vars', all references updated.  Change
-       `agr_case' to type `struct ccase'.
-       (cmd_aggregate) Deal with new members.  Use case_create(),
-       sort_active_file_in_place(), sort_active_file_to_casefile().
-       (agr_destroy) Deal with new members.
-       (aggregate_single_case) Ditto.
-       (dump_aggregate_info) Ditto.
-       (initialize_aggregate_info) Ditto.
-       (agr_to_active_file) Ditto.
-       (presorted_agr_to_sysfile) Ditto.
-       (sort_agr_to_sysfile) Removed.
-
-       * alloc.c: (out_of_memory) Make non-static.
-
-       * alloc.h: Prototype out_of_memory().
-
-       * casefile.c: Switched from a linked list in-memory representation
-       to a two-level array-style representation.  The linked list was
-       appropriate when we could stick a header onto cases, but that's no
-       longer the case.  Also, the two-level array will allow for random
-       in-memory access in case that's ever wanted.  Also added the
-       concept of a `destructive casereader', one that destroys cases in
-       the underlying casefile as they are read out.
-       (macro CASES_PER_BLOCK) New macro.
-       (struct casefile) New members `value_cnt', `case_list_size',
-       `case_acct_size', `being_destroyed', `cases'.  Removed `head',
-       `tail'.
-       (struct casereader) Removed `cur'.  Added `destructive', `c'.
-       (global var casefiles) Made static.
-       (static var case_bytes) New var.
-       (casefile_create) Takes a value count, not a case size in bytes,
-       to conform to the case interface.  All callers updated.  Deal with
-       new and removed members.
-       (casefile_destroy) Deal with new and removed members.
-       (casefile_sleep) New function.
-       (casefile_get_case_size) Removed.
-       (casefile_get_value_cnt) New function.
-       (casefile_append) Rewritten to deal with new and removed members.
-       (casefile_append_xfer) New function.
-       (write_case_to_disk) Use case_serialize().
-       (call_posix_fadvise) Removed because posix_fadvise64 segfaults.
-       Couldn't figure out why.
-       (casefile_to_disk) Don't call call_posix_fadvise.  Rewritten to
-       deal with new and removed members.
-       (merge) Removed.
-       (merge_sort) Removed.
-       (casefile_sort) Removed.
-       (casefile_get_reader) Deal with new and removed members.
-       (casefile_get_destructive_reader) New function.
-       (reader_open_file) Make code more readable.  Create case for
-       reader.
-       (casereader_get_casefile) New function.
-       (casereader_read) Deal with new and removed members.  Now returns
-       a copy of the case, so that the caller is responsible for
-       destroying the returned case.
-       (casereader_read_xfer) New function.
-       (casereader_destroy) Destroy reader's case.
-       (test_casefile) Second arg is now a value count, all callers
-       updated.  Now tests destructive readers too.
-       (get_random_case) Deal with new case ADT.
-       (write_random_case) Ditto.
-       (read_and_verify_random_case) Ditto.
-
-       * crosstabs.q: Remove debug code.
-
-       * descript.q: (calc_descriptives) Deal with new case, casefile
-       ADTs.
-
-       * dfm.c: (cmd_begin_data) There's no storage_source_class anymore.
-
-       * do-if.c: Remove unneeded header inclusion.
-
-       * expr-prs.c: Remove debug code.
-
-       * exprP.h: Remove debug code.
-
-       * flip.c: (flip_file) Use fseeko() if available.
-
-       * formats.c: Remove debug code.
-
-       * get.c: Remove debug code.
-       (struct mtf_file) Change `input' from `union value *' to `struct
-       ccase', all references updated.
-
-       * levene.c: (levene) Deal with new case, casefile ADTs.
-
-       * list.q: Remove debug code.
-
-       * loop.c: Remove debug code.
-       
-       * matrix-data.c: Remove debug code.
-
-       * means.q: Remove debug code.
-
-       * mis-val.c: Remove debug code.
-
-       * pfm-read.c: Remove debug code.
-       (pfm_read_code) Change second arg from `union value *' to `struct
-       ccase *', all references updated.
-
-       * recode.c: (string_to_long) Make first arg const.
-       (convert_to_double) Ditto.
-
-       * repeat.c: Remove debug code.
-
-       * sample.c: Remove debug code.
-
-       * sfm-read.c: Remove debug code.
-       (sfm_read_case) Change second arg from `union value *' to `struct
-       ccase *'.
-
-       * sort.c: Redone in terms of casefiles.
-       (enum sort_direction) Moved here from sort.h.
-       (struct sort_criterion) New structure.
-       (struct sort_criteria) New structure.
-       (cmd_sort_cases) Rewritten.
-       (prepare_to_sort_active_file) New function.
-       (sort_active_file_in_place) New function.
-       (sort_active_file_to_casefile) New function.
-       (parse_sort) Renamed sort_parse_criteria(), rewritten & interface
-       changed, all callers updated.
-       (destroy_sort_cases_pgm) Renamed sort_destroy_criteria(),
-       rewritten & interface changed, all callers updated.
-       (sort_cases) Renamed sort_execute(), rewritten & interface
-       changed, all callers updated.
-       (struct internal_sort) Removed.
-       (do_internal_sort) Rewritten, interface changed.
-       (destroy_internal_sort) Removed.
-       (compare_case_dblptrs) Use sort_criteria instead of sort_case_pgm.
-       (struct initial_run) Removed; an initial run is now just a
-       casefile.
-       (compare_initial_runs) Rewritten.
-       (struct external_sort) Changed almost completely.
-       (do_external_sort) Rewritten, interface changed.
-       (destroy_external_sort) Rewritten.
-       [HAVE_MKDTEMP] (make_temp_dir) Removed.
-       [!HAVE_MKDTEMP] (do_mkdir) Removed.
-       [!HAVE_MKDTEMP] (make_temp_dir) Removed.
-       (init_external_sort) Removed.
-       (simulate_error) Removed.
-       (rmdir_temp_dir) Removed.
-       (get_temp_file_name) Removed.
-       (open_temp_file) Removed.
-       (close_temp_file) Removed.
-       (remove_temp_file) Removed.
-       (write_temp_file) Removed.
-       (read_temp_file) Removed.
-       (struct record_run) Change `record' from `struct case_lit *' to
-       `struct ccase'.
-       (struct initial_run_state) Remove `idx_to_fv', `free_list',
-       `file_idx', `output_file'.  Add `run', casefile'.  Change
-       `last_output' from `struct case_list *' to `struct ccase'.
-       (write_initial_runs) Change interface, rewrite.
-       (sort_sink_write) Renamed process_case(), changed interfaced,
-       rewrote.
-       (destroy_initial_run_state) Rewritten.
-       (allocate_cases) Rewritten.
-       (compare_record) Interface changed, rewritten.
-       (start_run) Rewritten.
-       (end_run) Rewritten.
-       (output_record) Rewritten.
-       (grab_case) Removed.
-       (release_case) Removed.
-       (struct merge_case) Change `cases' from double pointer to single
-       pointer.
-       (merge) Deal with new case and casefile ADTs.
-       (struct run) Removed.
-       (merge_once) Rewritten, interface changed.
-       (fill_run_buffer) Removed.
-       (sort_sink_make_source) Removed.
-       (sort_sink_class) Removed.
-       (struct sort_source_aux) Removed.
-       (sort_source_read_helper) Removed.
-       (sort_source_read) Removed.
-       (read_sort_output) Removed.
-       (read_internal_sort_output) Removed.
-       (read_external_sort_output) Removed.
-       (sort_source_destroy) Removed.
-       (sort_source_class) Removed.
-
-       * sort.h: (struct sort_cases_pgm) Removed.
-       (enum sort_direction) Moved to sort.c.
-
-       * t-test.q: (calculate) Deal with new case, casefile ADTs.
-
-       * tab.c: Remove debug code.
-
-       * var-labs.c: Remove debug code.
-
-       * var.h: (struct ccase) Removed.
-       (struct case_list) Removed.
-
-       * vars-atr.c: (discard_variables) Use free_case_source().
-
-       * vars-prs.c: (parse_vs_variable) Make arg const.
-       (parse_dict_variable) Ditto.
-       (parse_variables) Make struct dictionary * arg const.
-       (parse_var_set_vars) Make struct var_set * arg const.
-       (struct var_set) Add const to some of the function pointers' args.
-       (var_set_get_cnt) Make arg const.
-       (var_set_get_var) Make first arg const.
-       (var_set_lookup_var) Make first arg const.
-       (dict_var_set_get_cnt) Make arg const.
-       (dict_var_set_get_var) Make first arg const.
-       (dict_var_set_lookup_var) Make first arg const.
-       (var_set_create_from_dict) Make arg const.  Add cast to aux
-       assignment.
-       (struct array_var_set) Add const to var member.
-       (array_var_set_get_cnt) Make arg const.
-       (array_var_set_get_var) Make first arg const.
-       (array_var_set_lookup_var) Make first arg const.
-       (var_set_create_from_array) Make first arg const.  Insert cast.
-
-       * vfm.c: (struct write_case_data) Change trns_case, sink_case
-       members from `struct ccase *' to `struct ccase'.
-       (static var lag_queue) Change from double to single pointer.
-       (procedure) Optimize trivial case.
-       (internal_procedure) Deal with changed case, case_source ADTs.
-       (create_trns_case) Changed interface, rewrote.
-       (open_active_interface) Initialize modified lag queue.
-       (write_case) Deal with changed case ADT.
-       (lag_case) Deal with modified lag queue.
-       (close_active_file) Destroy modified lag queue.
-       Deal with changed case_source, case_sink ADTs.
-       (destroy_storage_stream_info) Make null arg into no-op.
-       (storage_sink_make_source) Set aux in created source.
-       (storage_source_read) Deal with changed case, casefile ADTs.
-       (storage_source_create) New function.
-       (lagged_case) Rewrite.
-       (free_case_source) New function.
-       (free_case_sink) Rewrite.
-       (struct split_aux_data) Changed prev_case from `struct ccase *' to
-       `struct ccase'.
-       (procedure_with_splits) Deal with changed prev_case.
-       (procedure_with_splits_callback) Ditto.
-       (multipass_split_aux_data) Changed prev_case from `struct ccase *' to
-       `struct ccase'.
-       (multipass_procedure_with_splits) Deal with changed prev_case.
-       (multipass_split_callback) Ditto.
-       
-       
-Mon May 31 17:19:06 2004  Ben Pfaff  <blp@gnu.org>
-
-       The workspace idea didn't work out.
-
-       * Makefile.am: (pspp_SOURCES) Remove workspace.c, workspace.h.
-       
-       * workspace.c: Removed.
-
-       * workspace.h: Removed.
-
-Sun May 30 18:35:19 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fully implement arbitrary delimiters on DATA LIST, extending the
-       half implementation that was already there.
-
-       * data-list.c: (struct data_list_pgm) Remove `delim', add
-       `delims', `delim_cnt'.
-       (cmd_data_list) Initialize new members.  Parse delimiters and
-       clean up code a bit.
-       (cut_field) Extract fields with arbitrary delimiters.  Also, fix
-       handling of leading commas.
-       (read_from_data_list_fixed) Expand tabs.  Adapt to new DFM
-       interfaces.
-       (read_from_data_list_free) Adapt to new DFM interfaces.
-       (read_from_data_list_list) Ditto.
-       (repeating_data_trns_proc) Ditto.
-
-       * dfm.c: Split up reader and writer into separate code, because
-       they do different things.  Use struct string instead of explicit
-       allocation code, for clarity.
-       (enum dfm_reader_flags) New enum.
-       (struct dfm_fhuser_ext) Removed.
-       (struct dfm_reader_ext) New.
-       (get_reader) New function, used by just about all the reader
-       functions.
-       (dfm_close) Removed.
-       (close_reader) New function.
-       (dfm_open_for_reading) Rewrite initialization of dfm_fhuser_ext.
-       (dfm_open_for_writing) Ditto.
-       (macro force_line_buffer_expansion) Removed.
-       (count_tabs) Removed.
-       (tabs_to_spaces) Removed.
-       (read_record) Deal with new dfm_reader_ext.  Use struct string
-       functions.  Don't convert tabs to spaces.
-       (dfm_eof) New function.
-       (dfm_get_record) Changed interface, rewrote.
-       (dfm_expand_tabs) New function.
-       (dfm_fwd_record) Renamed dfm_forward_record(), updated to new
-       dfm_reader_ext, rewritten.
-       (dfm_bkwd_record) Renamed dfm_reread_record(), updated to new
-       dfm_reader_ext, rewritten.
-       (dfm_set_record) Removed in favor of dfm_forward_columns().
-       (dfm_forward_columns) New function.
-       (dfm_get_cur_col) Renamed dfm_column_start, updated to new
-       dfm_reader_ext, rewritten.
-       (static var dfm_r_class) Use close_reader for the destructor.
-       (struct dfm_writer_ext) New.
-       (dfm_put_record) Updated to new dfm_writer_ext, rewritten.  Uses
-       bounce buffer now instead of local allocation.
-       (close_writer) New function.
-       (static var dfm_writer_ext) Use close_writer for destructor.
-       (cmd_begin_data) Adapt to new dfm_reader_ext.
-
-       * file-handle.q: Add support for per-file tab width.
-       (struct private_file_handle) Add tab_width member.
-       (q2c specifications) Add tabwidth subcommand.
-       (cmd_file_handle) Put parsed tab width into private_file_handle.
-       (create_file_handle) Set default tab width.
-       (handle_get_tab_width) New function.
-
-       * file-type.c: (file_type_source_read) Adapt to new DFM interface.
-
-       * inpt-pgm.c: (reread_trns_proc) Ditto.
-
-       * matrix-data.c: (context) Ditto.
-       (another_token) Ditto.
-       (mget_token) Ditto.
-       (force_eol) Ditto.
-
-Sun May 30 18:33:59 2004  Ben Pfaff  <blp@gnu.org>
-
-       * casefile.c: (casefile_destroy) Fix memory leak by freeing
-       cf->filename.
-       (casereader_destroy) Don't close file descriptor -1.
-
-       * recode.c: (cmd_recode) Fix memory leak.
-
-       * set.q: (q2c specifications) Fix typo in user message.
-
-       * str.c: (st_bare_pad_len_copy) Change memcpy to memmove to avoid
-       undefined behavior for overlapping arguments.
-
-Sun May 30 18:31:48 2004  Ben Pfaff  <blp@gnu.org>
-
-       * casefile.c: valgrind doesn't implement posix_fadvise() yet, so
-       don't call it when we're running under valgrind.
-       (call_posix_fadvise) New function.
-       (casefile_to_disk) Use call_posix_fadvise().
-       (reader_open_file) Ditto.
-       
-Sun May 30 18:20:12 2004  Ben Pfaff  <blp@gnu.org>
-
-       Update our string ADTs, struct string and struct len_string.  Get
-       rid of pool support, which was largely unused.  Rename lots of
-       functions to have more obvious or consistent names.
-       
-       * ascii.c: Get rid of ascii_pool.  It was only used for string
-       allocations.
-       (ascii_open_global) Don't create ascii_pool.
-       (ascii_close_driver) Don't destroy ascii_pool.
-       (ascii_postopen_driver) Don't use pool.
-       (ascii_close_driver) Destroy strings manually.
-
-       * str.c: (ds_create) Remove pool argument, all references updated.
-       (ds_init) Ditto.
-       (ds_replace) Remove pool support, make more efficient when we
-       don't need to reallocate.
-       (ds_destroy) Remove pool support.
-       (ds_rpad) New function.
-       (ds_size) Renamed ds_capacity(), all references updated.
-       (ds_value) Renamed ds_c_str(), all references updated.
-       (ds_concat) Renamed ds_puts(), all references updated.
-       (ds_concat_buffer) Renamed ds_concat(), all references updated.
-       (ds_putchar) Renamed ds_putc(), all references updated.
-       (ds_getline) Renamed ds_gets(), all references updated.
-       (ls_create) Remove pool argument, all references updated.
-       (ls_create_buffer) Ditto.
-       (ls_destroy) Removed pool support.
-       (ls_value) Renamed ls_c_str(), all references updated.
-
-       * str.h: (ls_length) [__GNUC__] Add inline version.
-       (ls_c_str) [__GNUC__] Add inline version.
-       (ls_end) [__GNUC__] Add inline version.
-       (struct string) Remove pool member.  Rename `size' to `capacity',
-       all references updated.
-
-       * tab.c: (text_format) Instead of using pool argument to
-       ls_create_buffer(), call pool_register() on allocated data.
-
-Mon Apr 26 22:40:07 2004  Ben Pfaff  <blp@gnu.org>
-
-       We're abusing the current ASCII driver by telling it to allocate a
-       9999-line, 9999-character page in the tests.  This causes some
-       systems to curl up and die because it allocates 20 MB of
-       contiguous RAM.  This change alleviates at least part of the
-       problem.  It is mostly a stop-gap until the new output system is
-       ready.
-       
-       * ascii.c: (struct line) New structure.
-       (struct ascii_driver_ext) Remove `page', `page_size', `line_len',
-       `line_len_size', `n_output' members.  Add `lines', `lines_cap'.
-       (ascii_preopen_driver) Initialize new members, not old ones.
-       (ascii_close_driver) Destroy new members, not old ones.
-       (ascii_open_page) Allocate new members, not old ones.
-       (expand_line) Allocate room in line.
-       (draw_line) Use new members.
-       (ascii_line_horz) Ditto.
-       (ascii_line_vert) Ditto.
-       (ascii_line_intersection) Ditto.
-       (text_draw) Ditto.
-       (output_lines) Ditto.
-       (ascii_close_page) Ditto.
-
-Sun Apr 25 23:40:15 2004  Ben Pfaff  <blp@gnu.org>
-
-       * matrix.c: Dead code.  Removed.
-
-       * matrix.h: Dead code.  Removed.
-
-Fri Apr 16 23:59:51 2004  Ben Pfaff  <blp@gnu.org>
-
-       Contrary to what I'd always understood, there is an efficient
-       algorithm for deletion from a hash table populated via linear
-       probing.  This change implements it.
-       
-       * hash.c: (hsh_rehash) Probe in increasing order.
-       (hsh_probe) Ditto.
-       (locate_matching_entry) Ditto.
-       (hsh_delete) Use Knuth's Algorithm 6.4R for deletion.
-
-Tue Apr 13 19:24:15 2004  Ben Pfaff  <blp@gnu.org>
-
-       * moments.c (calc_moments): Adjust calculation of kurtosis to
-       avoid subtracting huge numbers from huge numbers, on Michael
-       Kiefte's advice.
-
-Sun Apr 11 14:22:12 2004  Ben Pfaff  <blp@gnu.org>
-
-       Rework moments routines for improved numerical stability based on
-       Michael Kiefte's advice.  Any bugs or remaining numerical problems
-       are still mine though.
-
-       There is now a struct moments1 for use with one-pass moments.  It
-       uses a provisional means algorithm as an attempt to improve
-       accuracy of higher moments.  The older struct moments now only
-       handles two-pass moments.
-       
-       * aggregate.c: Use moments1 instead moments.
-
-       * descript.c: Revert previous change, which is no longer needed
-       due to the moments revision.
-
-       * moments.c: (calc_moments) New function for calculating variance,
-       skewness, kurtosis.
-       (moments_pass_one) Only accumulate weights bigger than zero.
-       (moments_calculate) Allow calculating the mean on pass one, others
-       require pass two.  Implement in terms of calc_moments().
-       (struct moments1) New structure.
-       (init_moments1) New function.
-       (moments1_clear) Ditto.
-       (moments1_create) Ditto.
-       (moments1_add) Ditto.
-       (moments1_calculate) Ditto.
-       (moments1_destroy) Ditto.
-       (cmd_debug_moments) Deal with `struct moments' or `struct
-       moments1' as requested by user.
-
-Sun Apr 11 14:21:55 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am (pspp_SOURCES): Remove debug.c.
-
-       * debug.c: Removed.  It was empty anyway.
-
-Fri Apr  9 20:04:49 2004  Ben Pfaff  <blp@gnu.org>
-
-       * descript.c (calc_descriptives): Fix assert failure when only
-       MOMENT_MEAN is needed.
-
-2004-04-09  Michael Kiefte  <mkiefte@dal.ca>
-
-       * descript.c: 
-
-       fixed problem with parsing in match_statistic() causing
-       "DESCRIPTIVE STAT=MEAN." to barf.
-
-       "MEAN" is now default if "SORT" given without specification.
-
-       Fixed infinite loop with "DESCRIPT GIBBERISH=ALL."  Parsing is
-       generally less forgiving of syntax errors: better to have it do
-       nothing and type it in again then to not know what it actually did
-       instead.  
-
-       z-score transformation now checks score for user-missing values
-       and checks std_dev for SYSMIS.
-
-2004-04-06  Michael Kiefte  <mkiefte@dal.ca>
-
-       * aggregate.c, crosstabs.q, descript.c, dictionary.c, frequencies.q, levene.c, t-test.q, var.h: 
-       Changed dict_get_case_weight() to accept an additional int * flag
-       to complain about system-missing, user-missing, zero, or negative
-       weights and updated existing functions to pass int * to
-       dict_get_case_weight().
-
-2004-04-05  jmd  <jmd@gnu.org>
-
-       * main.c: Fixed configuration problems with gsl
-
-       * t-test.q: Fixed some problems encountered when compiling under Cygwin
-
-2004-04-03  blp  <blp@gnu.org>
-
-       * lexer.c, ChangeLog:
-       Fix infinite loop on comment at end of file, add test.
-
-2004-04-03  jmd  <jmd@gnu.org>
-
-       * settings.h, var.h, ChangeLog, Makefile.am, cmdline.c, command.c, command.h, error.h, filename.c, frequencies.q, lexer.h, main.c, q2c.c, set.q:
-       Fixed the calculation of percentiles and added --syntax and --algorithm options
-
-Sat Apr  3 11:43:37 2004  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (lex_skip_comment) Handle end-of-file correctly (I
-       hope).
-
-Sat Apr  3 15:00:18 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-        * frequencies.q:  Fixed the calculation of percentiles
-
-       * Makefile.am:  Added the --ansi flag and dealt with the
-       consequences.  Added some entries to PSPP_sources so that
-       make distcheck would pass
-
-       * cmdline.c:   Added the --syntax and --algorithm options
-
-       * q2c.c:  Added an implicit /ALGORITHM subcommand to everything.
-
-Fri Apr  2 11:25:22 WAST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q, levene.c, levene.h  Converted t-test (incl levene) to 
-       use the new multipass_split_... mechanism.
-
-Wed Mar 31 22:36:22 2004  Ben Pfaff  <blp@gnu.org>
-
-       * frequencies.q: (calc_stats) Use moments data structure and
-       calc_seskew(), calc_sekurt() functions.
-
-       * set.q main.c settings.h Added support for --syntax and --algorithm 
-       options
-
-Tue Mar 30 22:04:19 2004  Ben Pfaff  <blp@gnu.org>
-
-       * vfm.c: Had to get last call to multipass_split_output() inside
-       open_active_file()/close_active_file() pairing, so introduce new
-       function.
-       (internal_procedure) Move procedure() code here, except for calls
-       to open_active_file() and close_active_file().
-       (procedure) Wrap open_active_file() and close_active_file() around
-       internal_procedure().
-       (multipass_procedure_with_splits) Wrap open_active_file() and
-       close_active_file() around internal_procedure().
-
-Tue Mar 30 22:01:57 2004  Ben Pfaff  <blp@gnu.org>
-
-       * descript.c: (cmd_descriptives) Free `vars' to avoid memory leak.
-
-Mon Mar 29 16:26:40 2004  Ben Pfaff  <blp@gnu.org>
-
-       * debug.c: Removed.  Moved cmd_debug_evaluate() into expr-evl.c.
-
-       * expr-evl.c: (cmd_debug_evaluate) Moved here from debug.c.
-
-Mon Mar 29 16:03:08 2004  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: By default turn off some of the more expensive
-       assertions.
-       (expensive_assert) New macro which expands to assert if
-       EXTRA_CHECKS is defined, to nothing otherwise.
-       (unique) Use expensive_assert().
-       (binary_search) Ditto.
-       (push_heap) Ditto.
-       (pop_heap) Ditto.
-       (make_heap) Ditto.
-       (sort_heap) Ditto.
-
-       * command.c: (conflicting_3char_prefixes) Words that are the same
-       don't cause conflicts when they are abbreviated to the first three
-       letters.
-
-       * expr-evl.c: (CONCAT_func) Fix memory leak by incrementing struct
-       nonterm_node's n earlier.
-       (generic_str_func) Ditto.
-       
-Mon Mar 29 15:32:17 2004  Ben Pfaff  <blp@gnu.org>
-
-       Add support for multipass procedures.  Rewrite DESCRIPTIVES to
-       test multipass support, take advantage of new moments
-       calculation, and to not be such crappy code.  Get rid of q2c
-       processing for DESCRIPTIVES.
-
-       * vfm.c: (struct multipass_split_aux_data) New structure.
-       (multipass_procedure_with_splits) New function.
-       (multipass_split_callback) New function.
-       (multipass_split_output) New function.
-       * descript.q: Removed.
-
-       * descript.c: New file.
-
-       * var.h: Removed descriptives enums.
-       (struct descriptives_proc) Removed.
-       (struct variable) Removed p.dsc.
-
-       * Makefile.am: (q_sources_c) Remove descript.c.
-       (q_sources_q) Removed descript.q.
-       
-Mon Mar 29 15:31:55 2004  Ben Pfaff  <blp@gnu.org>
-
-       New manager for keeping track of used workspace.
-       
-       * workspace.c: New file.
-
-       * workspace.h: New file.
-
-       * Makefile.am: (pspp_SOURCES) Add workspace.c, workspace.h.
-
-       * sort.c: (do_internal_sort) Use workspace_malloc().
-       (destroy_internal_sort) Use workspace_free().
-
-Mon Mar 29 15:31:08 2004  Ben Pfaff  <blp@gnu.org>
-
-       New `struct casefile' for managing sets of cases.
-
-       * casefile.c: New file.
-
-       * casefile.h: New file.
-
-       * command.def: Add DEBUG CASEFILE command.
-
-       * Makefile.am: (pspp_SOURCES) Add casefile.c, casefile.h.
-
-       * sort.c: (sort_cases) Move logic for sending storage file to disk
-       into do_external_sort().
-       (struct internal_sort) Use an array of ccase pointers instead of a
-       case_list.
-       (do_internal_sort) Rewrite to handle casefiles.
-       (compare_case_list) Removed.
-       (compare_cases) New function.
-       (compare_case_dblptrs) New function.
-       (read_internal_sort_output) Deal with new struct internal_sort.
-
-       * vfm.c: (static var workspace_overflow) Removed.
-       (struct storage_stream_info) Removed all the members.  Added
-       struct casefile * member.
-       (storage_sink_open) Use casefile.
-       (open_storage_file) Removed.
-       (write_storage_file) Removed.
-       (storage_to_disk) Removed.
-       (destroy_storage_stream_info) Use casefile.
-       (storage_sink_write) Use casefile.
-       (storage_sink_make_source) Use casefile.
-       (storage_source_count) Use casefile.
-       (storage_source_read) Use casefile.
-       (storage_source_on_disk) Removed.
-       (storage_source_get_cases) Removed.
-       (storage_source_set_cases) Removed.
-       (storage_source_get_casefile) New function.
-       
-Mon Mar 29 15:30:09 2004  Ben Pfaff  <blp@gnu.org>
-
-       New `struct moments' for calculating moments.
-
-       * stats.c: Removed.
-
-       * stats.h: Removed.
-
-       * moments.c: New file.
-
-       * moments.h: New file.
-
-       * command.def: Add DEBUG MOMENTS command.
-
-       * Makefile.am: (pspp_SOURCES) Add moments.c, moments.h.  Remove
-       stats.c, stats.h.
-
-       * aggregate.c: Modify AGGREGATE to use the new moments
-       calculation, even if not in such a great way.
-       (struct agr_var) Add `moments' member.
-       (parse_aggregate_functions) Set `moments' member to null.
-       (agr_destroy) Destroy `moments' member.
-       (accumulate_aggregate_info) Use `moments' for standard deviation.
-       (dump_aggregate_info) Ditto.
-       (initialize_aggregate_info) Create or clear `moments'.
-
-       * misc.h: Add pow2(), pow3(), pow4() functions in place of sqr(),
-       cube(), pow4() that were in stats.h.  All references updated.
-
-       * crosstabs.q: stats.h had chi-square significance functions.  Use
-       GSL instead.
-       (display_chisq) Use gsl_cdf_chisq_Q() instead of chisq_sig().
-
-       * expr-evl.c: (expr_evaluate) Use moments_of_values() for
-       OP_CFVAR, OP_MEAN, OP_SD, OP_VARIANCE.
-               
-Fri Mar 26 14:21:23 2004  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c: (dict_compact_values) Compacted values need to
-       start off from 0.
-
-Fri Mar 26 00:54:57 2004  Ben Pfaff  <blp@gnu.org>
-
-       * var-labs.c: (cmd_variable_labels) For compatibility, don't allow
-       `/' at start.  Check return value of parse_variables() for error
-       return.
-
-Fri Mar 26 00:19:27 2004  Ben Pfaff  <blp@gnu.org>
-
-       Revamp expressions: make the code a little nicer, and fix bugs
-       found in testing.
-       
-       * expr-evl.c: (expr_evaluate) Make expression argument const.
-       Support OP_ADD, OP_SUB, OP_MUL, OP_DIV instead of OP_PLUS, OP_MUL.
-       OP_POW is missing for arg 2 <= 0.  OP_LOG is natural log, not
-       base-10 log.  Fix OP_ANY, OP_ANY_STRING, OP_RANGE, OP_RANGE_STRING
-       off-by-ones.  Add OP_MAX_STRING, OP_MIN_STRING.  Fix OP_TIME_HMS,
-       OP_DATE_WKYR boundary conditions.  Add OP_CTIME_DAYS,
-       OP_CTIME_HOURS, OP_CTIME_MINUTES, OP_CTIME_DAYS, OP_CTIME_SECONDS.
-       Support OP_INDEX_2, OP_INDEX_3, OP_RINDEX_2, OP_RINDEX_3 instead
-       of OP_INDEX, OP_INDEX_OPT, OP_RINDEX, OP_RINDEX_OPT.  Merge
-       OP_LPAD_OPT into OP_LPAD, OP_RPAD_OPT into OP_RPAD, OP_LTRIM_OPT
-       into OP_LTRIM, OP_RTRIM_OPT into OP_RTRIM, OP_NUMBER_OPT into
-       OP_NUMBER.  Fix OP_RTRIM fragility.  Support OP_SUBSTR_2,
-       OP_SUBSTR_3 instead of OP_SUBSTR, OP_SUBSTR_OPT.  Remove OP_INV.
-       Simplify OP_SYSMIS.  Remove OP_STR_MIS.
-
-       * expr-opt.c: (optimize_expression) Rewrite.
-       (macro n0) Removed.
-       (macro n1) Removed.
-       (macro n2) Removed.
-       (macro s0) Removed.
-       (macro s0l) Removed.
-       (macro s1) Removed.
-       (macro s1l) Removed.
-       (macro s2) Removed.
-       (macro s2l) Removed.
-       (macro s) Removed.
-       (macro sl) Removed.
-       (eq_num_con) New function.
-       (optimize_tree) New function.
-       (macro rnc) Removed.
-       (macro frnc) Removed.
-       (str_search) Add const to string params.
-       (str_rsearch) Ditto.
-       (evaluate_tree_no_missing) Renamed from evaluate_tree.  Add num[],
-       str[], str_len[] locals to substitute for most of removed macros.
-       Support OP_ADD, OP_SUB, OP_MUL, OP_DIV instead of OP_PLUS, OP_MUL.
-       Removed support for missing values because we're never called with
-       missing values.  Use set_number() or set_number_errno() instead of
-       rnc or frnc.  Removed any stuff that caused trouble in testing.
-       We can re-add it later if it really slows anything.  Fix some
-       random problems.
-       (evaluate_tree_with_missing) Not yet supported.  To be added later
-       if it's important.
-       (repl_num_con) Removed.
-       (collapse_node) New function.
-       (force_repl_num_con) Removed.
-       (set_number) New function.
-       (set_number_errno) New function.
-       (repl_str_con) Removed.
-       (set_string) New function.
-       (yrmoda) Tighten boundary conditions.  Adopt 2030 cut-off for
-       2-digit years.
-       (dump_node) No special case for OP_AND, OP_OR.
-
-       * expr-prs.c: (expr_prs) Honor EXPR_NO_OPTIMIZE bit.  Rewrite.
-       (expr_get_type) New function.
-       (type_check) Rewrite.
-       (type_coercion) New function.
-       (struct operator) New structure.
-       (match_operator New function.
-       (parse_binary_operators) New function.
-       (parse_inverting_unary_operator) New function.
-       (parse_or) Rewritten.
-       (parse_and) Rewritten.
-       (parse_not) Rewritten.
-       (parse_rel) Rewritten.
-       (parse_add) Rewritten.
-       (parse_mul) Rewritten.
-       (parse_neg) Rewritten.
-       (parse_exp) Rewritten.
-       (parse_sysvar) Add $TRUE, $FALSE system variables.
-       Get $LENGTH, $WIDTH from get_viewlength(), get_viewwidth().
-       (parse_primary) Use allocate_var_node(), allocate_num_con(),
-       allocate_str_con().
-       (struct function) Remove desc, change `func' prototype.
-       (unary_func) Remove special cases.
-       (MISSING_func) Reduce to unary_func() that just returns a boolean.
-       (SYSMIS_func) Handle SYSMIS((x)) like SYSMIS(x).
-       (VALUE_func) Use allocate_var_node().
-       (nary_num_func) Allow MIN and MAX for strings.
-       Use allocate_var_node().  Properly clean up.
-       Fix return type.
-       (generic_str_func) Use local table instead of removed `desc'
-       member.  Mostly rewrite.
-       (get_num_args) Revise error message.
-       (parse_function) Return EXPR_ERROR, not 0 on error.
-       (macro op) Removed.
-       (macro varies) Removed.
-       (ops[]) Use expr.def.
-       (free_node) Do nothing if node is null.
-       (allocate_num_con) New function.
-       (allocate_str_con) New function.
-       (allocate_var_node) New function.
-       (allocate_binary_nonterminal) New function.
-       (append_nonterminal_arg) Removed.
-       (static var func_tab[]) Revised.
-       (expr_debug_print_postfix) Make parameter const.
-       Use printf() instead of debug_printf().
-
-       * expr.def: New file.
-       
-       * expr.h: Change PXP_* to EXPR_*, all references updated.  Also
-       use named enum instead of unnamed, all references updated.  Add
-       EXPR_ANY, EXPR_NO_OPTIMIZE.
-
-       * exprP.h: Remove EX_*.  Add DEFINE_OPERATOR.  Use expr.def
-       instead of defining OP_* directly.
-       (macro IS_TERMINAL) New macro.
-       (macro IS_NONTERMINAL) New macro.
-       (enum OP_NO_FLAGS) New.
-       
-Fri Mar 26 00:18:01 2004  Ben Pfaff  <blp@gnu.org>
-
-       * error.c: (err_assert_fail) msg variable needs to be non-const.
-
-Fri Mar 26 00:17:24 2004  Ben Pfaff  <blp@gnu.org>
-
-       * debug.c: (cmd_debug_evaluate) Rewrite.
-
-Fri Mar 26 00:15:13 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fix some CROSSTABS bit rot stupidity.
-
-       * crosstabs.q: Reorder the CELLS subcommands for compatibility.
-       (internal_cmd_crosstabs) Initializes cells[] correctly.
-       (float_M_suffix) Rename format_cell_entry(), change prototype,
-       rewrite.
-       (display_crosstabulation) Fix cell formatting.
-
-Fri Mar 26 00:14:09 2004  Ben Pfaff  <blp@gnu.org>
-
-       Make lex_rest_of_line(), lex_entire_end() not discard lines.  Have
-       to call lex_discard_line() to do that.
-
-       * command.c: (run_command) Call lex_discard_line() after
-       lex_rest_of_line().
-
-       * lexer.c: (lex_entire_end) Change behavior.
-       (lex_rest_of_line) Change behavior.  Return const char *.
-       (lex_discard_line) Don't clear getl_buf, don't emit message.
-
-       * main.c: (handle_error) Emit message here.
-
-       * repeat.c: (internal_cmd_do_repeat) Use lex_discard_line()
-       instead of lex_entire_line().
-
-       * str.c: (mm_find_reverse) Make length params size_t.  Rewrite.
-
-       * title.c: (get_title) Call lex_discard_line() after
-       lex_rest_of_line().
-       (cmd_file_label) Ditto.
-       (cmd_document) Deal with const char * return value.
-
-Fri Mar 26 00:10:16 2004  Ben Pfaff  <blp@gnu.org>
-
-       Removed REMARK command.
-
-       * command.c: (extract_prefix) Removed.
-       (output_line) Removed.
-       (cmd_remark) Removed.
-
-       * command.def: Remove REMARK.
-
-Fri Mar 26 00:08:38 2004  Ben Pfaff  <blp@gnu.org>
-
-       Added abort() after lots of assert(0) invocations to avoid some
-       compiler warnings.  We really need a NOT_REACHED macro.
-
-Tue Mar 23 08:00:42 WAST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * sort.c: Added missing call to temp_file_close.  Changed error 
-       messages to warnings.
-
-       * set.q: Improved setting of set_view{length,width} to be more tolerant
-       of buggy OSes.
-
-Sun Mar 21 10:11:14 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-        * val-labs.c: Fixed a bug where PSPP would crash, if VALUE LABELS was
-       used with incorrect syntax.
-
-       * error.c, error.h et al:  Overridden definition of assert for a
-       custom one.
-
-       * test-q.c: Fixed a buglet where it would crash if no /VARIABLES
-       subcommand was given when it ought to have been.
-
-Sat Mar 20 22:19:08 2004  Ben Pfaff  <blp@gnu.org>
-
-       * tab.c: (tab_vline) Fix assertions to respect row_ofs and
-       col_ofs.
-       (tab_hline) Ditto.
-       (tab_box) Ditto.
-       (tab_joint_text) Ditto.
-
-Sat Mar 20 17:57:23 2004  Ben Pfaff  <blp@gnu.org>
-
-       * levene.c: Add #include.
-
-       * set.q: (set_viewport) Add `int' argument to make its prototype
-       correct for signal().
-
-Sat Mar 20 15:35:17 2004  Ben Pfaff  <blp@gnu.org>
-
-       * expr-evl.c: (expr_evaluate) Assert that `c' is nonzero before
-       using it.
-
-Sat Mar 20 15:18:16 2004  Ben Pfaff  <blp@gnu.org>
-
-       Changed DFM from open-at-first-access to explicit-open.  Before,
-       calling dfm_get_record() or dfm_put_record() would automatically
-       open the file.  Now, you have to call dfm_open_for_reading() or
-       dfm_open_for_writing() explicitly.  This makes it possible to
-       check permissions, file existence, etc. earlier.
-
-       Also made struct file_handle more opaque, and clean up in general.
-
-       * data-list.c: (cmd_data_list) Open handle for reading.
-
-       * dfm.c: (struct dfm_fhuser_ext) Add `where', `saw_begin_data'
-       members.
-       (open_file_r) Renamed dfm_open_for_reading(), rewrote.
-       (open_file_w) Renamed dfm_open_for_writing(), rewrote.
-       (open_inline_file) Removed.
-       (read_record) For inline_file, if we haven't seen BEGIN DATA, read
-       it.  Deal with line_number in extension record instead of file
-       handle.
-       (dfm_get_record) Rewrote.
-       (dfm_put_record) Rewrote.
-       (dfm_push) Assert file is open and one of ours.  Deal with
-       line_number in extension record instead of file handle.
-       (dfm_pop) Assert file is open and one of ours.  Deal with
-       line_number in extension record instead of file handle.
-       (cmd_begin_data) Use dfm_open_for_reading().  Mark that we saw
-       BEGIN DATA.     
-
-       * file-handle.h: (enum constants RH_RF_*) Removed.
-       (enum constants FH_MD_*) Removed.
-       (struct file_handle) Removed `name', `norm_fn', `fn', `where',
-       `recform', `lrecl', `mode' members.  Public references to
-       `recform' changed to use handle_get_mode(), references to `lrecl'
-       changed to use handle_get_record_width().  Added `private' member.
-       (enum file_handle_mode) New.
-
-       * file-handle.q: (struct private_file_handle) New structure.
-       (struct file_handle_list) New structure.
-       (static var files) New.
-       (static var file_handles) Removed.
-       (init_file_handle) Removed.
-       (create_file_handle) Removed.
-       (get_handle_with_name) New function.
-       (get_handle_for_filename) New function.
-       (cmd_file_handle) Rewritten.
-       (hash_file_handle) Removed.
-       (cmp_file_handle) Removed.
-       (fh_init_files) Rewritten.
-       (fh_parse_file_handle) Rewritten.  Allows identifiers as
-       filenames.
-       (fh_get_handle_by_name) Renamed handle_get_name(), all references
-       updated.  Rewritten.
-       (fh_get_handle_by_filename) Renamed handle_get_filename(), all
-       references updated.  Rewritten.
-       (fh_record_width) Renamed handle_get_record_width(), all
-       references updated.  Rewritten.
-       (handle_get_mode) New function.
-
-       * file-type.c: (cmd_file_type) Open handle for reading.
-
-       * filename.c: [unix] (struct file_identity) New structure.
-       [unix] (fn_get_identity) New function.
-       [unix] (fn_free_identity) New function.
-       [unix] (fn_compare_file_identities) New function.
-       [!unix] (struct file_identity) New structure.
-       [!unix] (fn_get_identity) New function.
-       [!unix] (fn_free_identity) New function.
-       [!unix] (fn_compare_file_identities) New function.
-
-       * lexer.c: (static var put) Renamed put_token, all references
-       updated.
-       (static var put_tokstr) New.
-       (static var put_tokval) New.
-       (lex_init) Initialize put_tokstr().
-       (restore_token) New function.
-       (save_token) New function.
-       (lex_get) Use restore_token().
-       (lex_put_back) Use save_token().
-       (lex_put_back_id) New function.
-       (lex_put_forward) Removed.
-       (lex_preprocess_line) Set put_token instead of using
-       lex_put_forward().
-       (lex_negative_to_dash) Use save_token(), set put_token directly.
-       (dump_token) Use stderr instead of stdout.
-
-       * main.c: (main) Remove call to cmd_init().
-       
-       * matrix-data.c: (cmd_matrix_data) Open file for reading.
-
-       * pfm-read.c: Use handle_get_filename() instead of trying to use
-       h->fn directly, all over.
-
-       * pfm-write.c: Ditto.
-
-       * print.c: (internal_cmd_print) Open handle for writing.
-       (dump_table) Use handle_get_filename().
-       (print_trns_proc) Use handle_get_mode().
-       (cmd_print_space) Use fh_parse_file_handle().
-       Open handle for writing.
-       [0] (debug_print) Removed.
-
-       * sfm-read.c: Use handle_get_filename() instead of trying to use
-       h->fn directly, all over.
-
-       * sfm-write.c: Ditto.
-
-Sat Mar 20 14:35:48 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fix memory leaks.
-       
-       * autorecode.c: (arc_free) Free arc->src_values.
-
-       * error.c: (msg) Free buf.
-
-       * val-labs.c: (do_value_labels) Always free vars.
-
-       * vfm.c: (close_active_file) If sink has no make_source then call
-       its destroy function.
-
-Sat Mar 20 14:00:24 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fixed cmd_parse() so that it always skips past a full command
-       name.  A few special commands for which this would be bad get
-       special treatment.  This lets us drop code for skipping past the
-       end of a command name in most cmd_*() functions.  It's not worth
-       listing all the commands affected.
-
-       * command.c: (struct command) Remove `cmd' member, replace by
-       `name' member, all references updated.  Remove `word', `next',
-       `skip_entire_name' members.
-       (macro DEFCMD) Deal with revised `struct command'.
-       (macro UNIMPL) Ditto.
-       (macro SPCCMD) New macro for commands whose last word shouldn't be
-       skipped.
-       (static array cmd_table[]) Make const, rename `commands', remove
-       sentinel element.
-       (macro COMMAND_CNT) New macro.
-       (split_words) Removed.
-       (cmd_init) Removed.
-       (FILE_TYPE_okay) Make parameter const.
-       (cmd_parse) Improve error messages.
-       (match_strings) New function.
-       (next_word) New function.
-       (enum command_match) New enum.
-       (conflicting_3char_prefixes) New function.
-       (conflicting_3char_prefix_command) New function.
-       (cmd_match_words) New function.
-       (count_matching_commands) New function.
-       (get_command_name) New function.
-       (free_words) New function.
-       (unknown_command_error) New function.
-       (figure_out_command) Renamed parse_command_name(), rewritten.
-
-       * command.def: Removed @ command.  Marked BEGIN DATA, DOCUMENT,
-       FILE LABEL, REMARK, SUBTITLE, TITLE as special.  Renamed EVALUATE
-       to DEBUG EVALUATE.  Added N alias for N OF CASES, SORT alias for
-       SORT CASES.
-
-       * command.h: (macro SPCCMD) New.
-
-       * include.c: (cmd_include_at) Removed.
-       (cmd_include) Allow identifier to be used as filename.
-
-       * inpt-pgm.c: (cmd_reread) Use fh_parse_file_handle().
-
-       * t-test.q: (cmd_t_test) Command name is now parsed for us.
-       
-
-Sat Mar 20 13:56:00 2004  Ben Pfaff  <blp@gnu.org>
-
-       Start work on better test framework.
-       
-       * Makefile.am: (pspp_sources) Add debug.c.
-       
-       * debug.c: New file.
-
-       * compute.c: (cmd_evaluate) Moved to debug.c, renamed
-       cmd_debug_evaluate().
-
-       * expr-prs.c: (expr_parse) Remove PXP_DUMP support.
-
-       * expr.h: (enum constant PXP_DUMP) Removed.
-
-Sat Mar 20 00:05:42 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * set.q:  Implemented the SHOW command, and synced it to the existing 
-       SET cmd.
-
-       Added a handler for SIGWINCH so that viewlength and viewwidth follow
-       changes as the window size is changed.
-
-       Added fallback to set viewlength and viewwidth from LINES and COLUMS
-       environment variables if other methods are not available.
-
-       glob.c: Removed a lot of global variables from glob.c and encapsulated 
-       them in set.q
-
-       random.c: Tidied up the way the random seed is set.
-
-       str.c: Added a ds_vprintf function.
-
-       error.c: Extended dump_message so that messages are always broken at
-       '\n' characters.
-       
-Thu Mar 18 11:07:14 2004  Ben Pfaff  <blp@gnu.org>
-
-       * pfm-write.c: (bufwrite) Write out the correct element for string
-       variables.  From Andreas Streichardt <streichardt@globalpark.de>.
-
-Mon Mar 15 20:48:03 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static and global (!) vars in matrix-data.c.
-
-       * matrix-data.c: (static var nr_data) Removed.
-       (static var nr_factor_values) Removed.
-       (static var max_cell_index) Removed.
-       (static var split_values) Removed.
-       (struct nr_aux_data) New structure.
-       (read_matrices_without_rowtype) Use a local struct nr_aux_data in
-       place of static vars, pass to create_case_source() and procedure()
-       as aux data.
-       (nr_read_data_lines) Use struct nr_aux_data * parameter instead of
-       struct matrix_data_pgm *.
-       (nr_read_splits) Ditto.
-       (nr_read_factors) Ditto.
-       (nr_output_data) Ditto.
-       (static var wr_content) Removed.
-       (global var wr_data) Removed.
-       (global var wr_current) Removed.
-       (struct wr_aux_data) New structure.
-       (read_matrices_with_rowtype) Use a local struct wr_aux_data in
-       place of static vars, pass to create_case_source() and procedure()
-       as aux data.
-       (matrix_data_read_with_rowtype) Use struct wr_aux_data * parameter
-       instead of matrix_data_pgm *.
-       (wr_read_splits) Ditto.
-       (wr_output_data) Ditto.
-       (wr_read_rowtype) Ditto.
-       (wr_read_factors) Ditto.
-       (wr_read_indeps) Ditto.
-       
-Mon Mar 15 20:07:29 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static vars in autorecode.c.
-
-       * autorecode.c: (struct autorecode_trns) Rename `arc' to `specs',
-       `n_arc' to `spec_cnt'.  All references updated.
-       (static var v_src) Removed.
-       (static var v_dest) Removed.
-       (static var h_trns) Removed.
-       (static var nv_src) Removed.
-       (static var descend) Removed.
-       (static var print) Removed.
-       (enum direction) New enum.
-       (struct autorecode_pgm) New structure.
-       (cmd_autorecode) Use struct autorecode_pgm instead of static vars.
-       Move n_dest local var into struct autorecode_pgm for ease of
-       clean-up.  Use arc_free().
-       (arc_free) New function.
-       (recode) Modify to take struct autorecode_pgm * parameter instead
-       of using statics.  Let the caller clean up.
-       (autorecode_proc_func) Use struct autorecode_pgm * auxiliary data
-       instead of statics.  Rearrange code a little.
-
-Mon Mar 15 00:25:02 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static, global vars in recode.c.  Remove debug code.
-
-       * recode.c: (static var head) Removed.
-       (global var v) Removed.
-       (global var nv) Removed.
-       (cmd_recode) New local variables head, v, nv.  Initialize and free
-       v.  Don't call debug_print().
-       [DEBUGGING] (dump_dest) Removed.
-       [DEBUGGING] (debug_print) Removed.
-
-Mon Mar 15 00:14:49 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static vars in expr-opt.c.
-
-       * expr-opt.c: (static var e) Removed.
-       (static var nop) Removed.
-       (static var mop) Removed.
-       (static var ndbl) Removed.
-       (static var mdbl) Removed.
-       (static var nstr) Removed.
-       (static var mstr) Removed.
-       (static var nvars) Removed.
-       (static var mvars) Removed.
-       (struct expr_dump_state) New structure.
-       (dump_expression) Use new struct expr_dump_state instead of static
-       vars and pass to functions we call.
-       (dump_node) Use struct expr_dump_state * parameter.
-       (emit) Ditto.
-       (emit_num_con) Ditto.
-       (emit_str_con) Ditto.
-       (emit_var) Ditto.
-       
-Mon Mar 15 00:03:51 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static var in COUNT.
-
-       * count.c: (static var head) Move into cmd_count().
-       (cmd_count) [DEBUGGING] Don't call debug_print.
-       [DEBUGGING] (debug_print) Removed.
-
-Sun Mar 14 23:56:09 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static vars in VALUE LABELS, ADD VALUE LABELS.
-
-       * val-labs.c: (static var v) Removed.
-       (static var nv) Removed.
-       [DEBUGGING] (debug_print) Removed.
-       (verify_val_labs) Add struct variable **, int parameters.
-       (get_label) Ditto.  Improve error messages, streamline.
-       (erase_labels) New function for erasing value labels, taking over
-       part of verify_val_labs()'s function.
-       (init) Removed.
-       (done) Removed.
-       (cmd_value_labels) No need to call init() or done() anymore.
-       (cmd_add_value_labels) Ditto.
-       (do_value_labels) Add vars, var_cnt local variables.  Clean up
-       after them internally.  Call erase_labels() if we should.  Don't
-       call debug_print().
-
-Sun Mar 14 23:33:53 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of static vars in MATCH FILES.
-       
-       * get.c: (static var mtf_head) Removed.
-       (static var mtf_tail) Removed.
-       (static var mtf_by) Removed.
-       (static var mtf_n_by) Removed.
-       (static var mtf_master) Removed.
-       (static var mtf_seq_num) Removed.
-       (static var mtf_seq_nums) Removed.
-       (static var mtf_sink) Removed.
-       (static var mtf_case) Removed.
-       (struct mtf_proc) New structure.
-       (cmd_match_files) Use struct mtf_proc instead of static vars.
-       (mtf_processing_finish) Ditto.
-       (mtf_free) Ditto.
-       (mtf_delete_file_in_place) Ditto.
-       (mtf_read_nonactive_records) Ditto.
-       (mtf_compare_BY_values) Ditto.
-       (mtf_processing) Ditto.
-       (mtf_merge_dictionary) Ditto.
-
-Sun Mar 14 22:48:12 2004  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add CASESTOVARS, VARSTOCASES unimplemented commands.
-
-       * dictionary.c: (dict_rename_var) Add assertion.
-       (dict_contains_var) Check by index instead of name.
-
-Sun Mar 14 22:01:02 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of compaction_necessary, compaction_nval, compaction_case.
-       Redo VFM interface.  Replace disk_sink and memory_sink by
-       storage_sink, disk_source and memory_source by storage_source.
-
-       * vfm.h: (struct case_sink) Add `dict', `idx_to_fv', `value_cnt'
-       members.
-
-       * vfm.c: 
-       (struct write_case_data) Remove `begin_func', `end_func',
-       `func_aux' members.  Add `aux', `trns_case', `sink_case',
-       `cases_written', `cases_analyzed' members.
-       (global var compaction_necessary) Make static.
-       (global var compaction_nval) Removed.
-       (global var compaction_case) Removed.
-       (static var case_count) Removed.
-       (struct procedure_aux_data) Removed.
-       (struct split_aux_data) Removed.
-       (procedure) Remove begin_func, end_func parameters.  Rewrite.
-       (static var not_canceled) Removed.
-       (process_active_file) Removed.
-       (process_active_file_write_case) Removed.
-       (process_active_file_output_case) Removed.
-       (prepare_for_writing) Moved into open_active_file().
-       (arrange_compaction) Ditto.
-       (setup_lag) Ditto.
-       (open_active_file) Rewrote.
-       (write_case) New function.
-       [DEBUGGING] (index_to_varname) Removed.
-       (execute_transformations) New function.
-       (exclude_this_case) Renamed filter_case(), changed interface.
-       (clear_case) Added struct ccase * parameter to interface.
-       (close_active_file) Added struct write_case_data * parameter,
-       rewrote.
-       (disk_sink_create) Removed.
-       (disk_sink_destroy) Removed.
-       (disk_sink_make_source) Removed.
-       (disk_sink_write) Removed.
-       (disk_source_count) Removed.
-       (disk_source_destroy) Removed.
-       (disk_source_read) Removed.
-       (global var disk_sink_class) Removed.
-       (global var disk_source_class) Removed.
-       (global var memory_sink_class) Removed.
-       (global var memory_source_class) Removed.
-       (memory_sink_create) Removed.
-       (memory_sink_destroy) Removed.
-       (memory_sink_make_source) Removed.
-       (memory_sink_write) Removed.
-       (memory_source_count) Removed.
-       (memory_source_destroy) Removed.
-       (memory_source_get_cases) Removed.
-       (memory_source_read) Removed.
-       (memory_source_set_cases) Removed.
-       (struct disk_stream_info) Removed.
-       (struct memory_sink_info) Removed.
-       (struct memory_source_info) Removed.
-       (write_active_file_to_disk) Removed.
-       (destroy_storage_stream_info) New function.
-       (global var null_sink_class) New var.
-       (global var storage_sink_class) New var.
-       (global var storage_source_class) New var.
-       (open_storage_file) New function.
-       (storage_sink_destroy) New function.
-       (storage_sink_make_source) New function.
-       (storage_sink_open) New function.
-       (storage_sink_write) New function.
-       (storage_source_count) New function.
-       (storage_source_destroy) New function.
-       (storage_source_get_cases) New function.
-       (storage_source_on_disk) New function.
-       (storage_source_read) New function.
-       (storage_source_set_cases) New function.
-       (storage_source_to_disk) New function.
-       (storage_to_disk) New function.
-       (struct storage_stream_info) New structure.
-       (write_storage_file) New function.
-       (procedure_write_case) Removed.
-       (create_case_source) Add `struct dictionary *' parameter, all
-       references updated.
-       (create_case_sink) Ditto.
-       (free_case_sink) New function.
-       (struct split_aux_data) New structure.
-       (procedure_with_splits) New function implementing what procedure()
-       used to.
-       (SPLIT_FILE_proc_func) Removed.
-       (procedure_with_splits_callback) New function.
-       (equal_splits) New function.
-       
-       * aggregate.c: Pass around a struct instead of using statics.
-       (static var outfile) Remove.
-       (enum type) Give it tag `missing_treatment'.
-       (static var missing) Remove.
-       (static var sort) Remove.
-       (static var agr_first) Remove.
-       (static var agr_next) Remove.
-       (static var case_count) Remove.
-       (static var prev_case) Remove.
-       (static var buf64_1xx) Remove.
-       (static var buf_1xx) Remove.
-       (struct agr_proc) New structure incorporating the above.
-       (cmd_aggregate) Use new struct.  Clean up error handling using
-       agr_destroy().  Completely rewrite actual implementation of
-       aggregation.
-       (create_sysfile) Add struct agr_proc * parameter, modify
-       accordingly.
-       (parse_aggregate_functions) Ditto.
-       (free_aggregate_functions) Ditto.  Rename agr_destroy().
-       (aggregate_single_case) Add struct agr_proc * parameter, modify
-       accordingly.
-       (accumulate_aggregate_info) Ditto.
-       (dump_aggregate_info) Ditto.
-       (initialize_aggregate_info) Ditto.
-       (agr_00x_trns_proc) Removed.
-       (agr_00x_end_func) Removed.
-       (agr_10x_trns_proc) Removed.
-       (agr_10x_trns_free) Removed.
-       (agr_10x_end_func) Removed.
-       (agr_11x_read) Removed.
-       (agr_11x_finish) Removed.
-       [DEBUGGING] (debug_print) Removed.
-       (write_case_to_sfm) Add struct agr_proc * parameter, modify
-       accordingly.
-       (agr_to_active_file) New function.
-       (presorted_agr_to_sysfile) New function.
-       (sort_agr_to_sysfile) New function.
-
-       * autorecode.c: (cmd_autorecode) Use procedure_with_splits().
-
-       * crosstabs.q: (internal_cmd_crosstabs) Ditto.
-
-       * descript.q: (cmd_descriptives) Ditto.
-
-       * dfm.c: (cmd_begin_data) Check for storage_source_class.  Adapt
-       to new procedure() interface.
-
-       * command.c: (cmd_execute) Adapt to new procedure() interface.
-
-       * dictionary.c: (dict_compact_values) Also delete scratch
-       variables.
-       (dict_get_compacted_value_cnt) New function.
-       (dict_get_compacted_idx_to_fv) New function.
-
-       * flip.c: (cmd_flip) Warn about and cancel TEMPORARY.
-       (cmd_flip) Adapt to new procedure() interface.
-       (flip_sink_write) Use sink->idx_to_fv.
-
-       * frequencies.q: (internal_cmd_frequencies) Use
-       procedure_with_splits().
-
-       * get.c: (cmd_save_internal) Adapt to new procedure() interface.
-       (static var mtf_sink) New static var.
-       (static var mtf_case) New static var.
-       (cmd_match_files) Warn about and cancel TEMPORARY.  Redo the way
-       we actually implement the matching.
-       (mtf_delete_file_in_place) Use mtf_case.
-       (mtf_processing) Use mtf_case and mtf_sink.
-       (cmd_export) Adapt to new procedure() interface.
-
-       * levene.c: (levene) Use procedure_with_splits().
-
-       * list.q: (cmd_list) Use procedure_with_splits().
-
-       * matrix-data.c: (read_matrices_without_rowtype) Adapt to new
-       procedure() interface.
-       (read_matrices_with_rowtype) Ditto.
-
-       * modify-vars.c; (cmd_modify_vars) Warn about and cancel
-       TEMPORARY.  Adapt to new procedure() interface.
-
-       * rename-vars.c: Warn about and cancel TEMPORARY.
-
-       * sort.c: (cmd_sort_cases) Warn about TEMPORARY.
-       (sort_cases) Use dict_get_compacted_value_cnt() instead of
-       compaction_nval.  Adapt to new procedure() interface.  Use
-       storage_source_to_disk().
-       (do_internal_sort) Don't try to dump the cases to memory.
-       (compare_case_lists) Pass null idx_to_fv.
-       (struct initial_run_state) Add `idx_to_fv' member.  Remove
-       `case_size' member.
-       (write_initial_runs) Don't initialize irs->case_size.  Adapt to
-       new procedure() interface.  Reset irs->idx_to_fv after calling
-       procedure().
-       (sort_sink_write) Set irs->idx_to_fv.  Use case_size from struct
-       sort_cases_pgm.  Pass irs, not struct sort_cases_pgm to
-       push_heap().
-       (destroy_initial_run_state) Don't dereference irs after freeing
-       it.
-       (allocate_cases) Don't calculate case_size locally.
-       (compare_record) Add idx_to_fv parameter.
-       (compare_record_run) Change parameter from struct sort_cases_pgm *
-       to struct initial_run_state *.  Pass irs->idx_to_fv to
-       compare_record().
-       (compare_record_run) Third parameter now a struct
-       initial_run_state *.
-       (output_record) No need for out_case anymore.  Pass irs, not
-       struct sort_cases_pgm to pop_heap().  Use case_size from struct
-       sort_cases_pgm.
-       (merge) Use case_size from struct sort_cases_pgm.
-       (merge_once) Use case_size from struct sort_cases_pgm.
-       Pass null pointer to compare_record() as idx_to_fv.
-       (global var sort_sink_class) Make static.
-
-       * t-test.q: (cmd_t_test) Use procedure_with_splits().
-
-       * temporary.c: Remove debugging crap.
-
-Sat Mar 13 14:19:52 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q, levene.c: Fixed up the handling of MISSING values
-       int the T-TEST
-
-Fri Mar 12 16:23:35 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q, levene.c: Added support for T-TEST /GROUP where only 
-       one value is given.
-
-Wed Mar 10 23:25:13 2004  Ben Pfaff  <blp@gnu.org>
-
-       Change explicit variable name checks into use of
-       dict_class_from_id().
-
-       * dictionary.c: (dict_create_var)  Change explicit variable name
-       check into use of dict_class_from_id().
-
-       * get.c: (trim_dictionary) Ditto.
-
-       * sel-if.c: (cmd_filter) Ditto.
-
-       * sysfile-info.c: (cmd_display) Ditto.
-
-       * vars-prs.c: (parse_DATA_LIST_vars) Ditto.
-
-       * vfm.c: (arrange_compaction) Ditto.
-
-       * weight.c: (cmd_weight) Ditto.
-
-Wed Mar 10 21:16:34 2004  Ben Pfaff  <blp@gnu.org>
-
-       * temporary.c: (cmd_temporary) When TEMPORARY was the first
-       transformation following the input program, if any, for some
-       reason we special-cased f_trns.  That's just wrong.  It should
-       always be set to n_trns.
-
-Tue Mar  9 23:44:40 2004  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (parse_format_specifier_name) Fix brown-bag bug
-       introduced in last check-in.
-
-Tue Mar  9 23:10:41 2004  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (global array translate_fmt[]) Removed.
-       (translate_fmt) New function as replacement.
-       (parse_format_specifier_name) Rewrite.
-
-       * pfm-read.c: (convert_format) Use translate_fmt() instead of
-       translate_fmt[].
-
-       * sfm-read.c: (parse_format_spec) Ditto.
-
-       * postscript.c: (text) Fix handling of fonts with missing
-       ligatures.
-
-       * sort.c: (struct external_sort) Add temp_name member.
-       (destroy_external_sort) Free temp_dir, temp_name members.
-       (init_external_sort) Allocate temp_name.
-       (get_temp_file_name) Change prototype.
-       (open_temp_file) Deal with change to get_temp_file_name().
-       (close_temp_file) Ditto.
-       (remove_temp_file) Ditto.
-       (write_temp_file) Ditto.
-       (read_temp_file) Ditto.
-       (sort_sink_destroy) Removed.
-       (sort_sink_class) Change destroy member to null.
-
-Tue Mar  9 22:36:34 2004  Ben Pfaff  <blp@gnu.org>
-
-       Eliminate temp_case.
-
-       * aggregate.c: (cmd_aggregate) No need to save/restore temp_case
-       anymore.  Use agr_11x_finish().
-       (aggregate_single_case) Make first param const.
-       (accumulate_aggregate_info) Ditto.
-       (agr_00x_end_func) Use compaction_case, not temp_case.
-       (agr_11x_func) Break into agr_11x_read(), agr_11x_finish().
-
-       * data-list.c: (struct data_list_pgm) Add `case_size' member.
-       (cmd_data_list) Initialize case_size.
-       (read_from_data_list_fixed) Add struct ccase * param, use instead
-       of temp_case.
-       (read_from_data_list_free) Ditto.
-       (read_from_data_list_list) Ditto.
-       (read_one_case) Rename data_list_trns_proc(), all references
-       updated.  Add argument in calling above functions.  Use c
-       argument instead of temp_case.
-       (destroy_dls) Rename data_list_trns_free(), all references
-       updated.
-
-       * expr-evl.c: (expr_evaluate) Make second parameter const.
-
-       * file-type.c: (struct file_type_pgm) Add `case_size' member.
-       (cmd_end_file_type) Initialize `case_size'.
-       (file_type_source_read) Add struct ccase * parameter.  Use instead
-       of temp_case.
-
-       * flip.c: Rewritten.
-
-       * get.c: (struct get_pgm) New structure to keep track of
-       case_size.
-       (cmd_get) Initialize case_size.
-       (cmd_import) Ditto.
-       (get_source) Deal with struct get_pgm.
-       (get_source_read) Add struct ccase * parameter, use instead of
-       temp_case.
-       (import_source_read) Ditto.
-
-       * get.c: Use a null pointer instead of temp_case to represent the
-       "current case" in a struct mtf_file's input member.
-       (mtf_processing_finish) Pass null to mtf_processing(), not
-       temp_case.
-       (mtf_read_nonactive_records) Don't set iter->input to temp_case.
-       (mtf_compare_BY_values) Add extra arg, use instead of null input
-       members.
-       (mtf_processing) Use c parameter instead of temp_case.  Pass
-       compaction_case to process_active_file_output_case().
-       
-       * glob.c: (global variable temp_case) Removed.
-
-       * inpt-pgm.c: (struct input_program_pgm) Add `case_size' member.
-       (cmd_input_program) Initialize case_size.  Set
-       vfm_source->value_cnt.
-       (init_case) Add struct ccase * parameter, use instead of
-       temp_case.
-       (clear_case) Ditto.
-       (input_program_source_read) Ditto.
-
-       * matrix-data.c: (matrix_data_read_without_rowtype) Ditto.
-       (dump_cell_content) Ditto.
-       (nr_output_data) Ditto.
-       (read_matrices_without_rowtype) Ditto.
-       (matrix_data_read_with_rowtype) Ditto.
-       (wr_read_splits) Ditto.
-       (wr_output_data) Ditto.
-
-       * sort.h: (struct sort_cases_pgm) New member `case_size'.
-       
-       * sort.c: (sort_cases) Initialize scp->case_size.
-       (struct external_sort) Remove `case_size' member.
-       (write_initial_runs) Only call vfm_sink->class_destroy if
-       non-null.
-       (struct sort_source_aux) New structure.
-       (sort_source_read_helper) New function.
-       (sort_source_read) Use sort_source_read_helper().
-       (read_sort_output) Change interface to be more reasonable.
-       (read_internal_sort_output) Ditto.
-       (read_external_sort_output) Ditto.
-
-       * vars-prs.c: (dict_class_to_name) Pass return value through
-       gettext.
-
-       * vfm.c: (struct procedure_aux_data) Add `trns_case' member.
-       (procedure) Initialize trns_case.
-       (procedure) Pass trns_case to vfm_source->class->read().
-       Free trns_case.
-       (process_active_file) Start using struct procedure_aux_data.
-       (process_active_file_write_case) Pass trns_case to
-       transformations, lag_case(), clear_case().
-       (process_active_file_output_case) Add struct ccase * parameter.
-       (create_trns_case) New function.
-       (make_temp_case) Removed.
-       (vector_initialization) Removed.
-       (close_active_file) Only call make_source if non-null, otherwise
-       set vfm_source to null pointer.  Don't free temp_case.
-       (disk_source_read) Add struct ccase * parameter, use instead of
-       temp_case.
-       (memory_source_read) Ditto.
-       (lag_case) Add const struct ccase * member.
-       (procedure_write_case) Use trns_case instead of temp_case.
-       (clear_case) Add struct ccase * member, use instead of temp_case.
-       (exclude_this_case) Ditto.
-       (create_case_source) Add struct dictionary * parameter, use to
-       initialize source->value_cnt.
-
-       * vfm.h: (struct case_source) Add `value_cnt' member.
-       (struct case_source_class) Add struct ccase * parameter to `read'
-       member function pointer.
-       (struct case_sink_class) Make struct ccase * parameter const in
-       `write' member function pointer.
-       
-Wed Mar  3 20:44:37 2004  Ben Pfaff  <blp@gnu.org>
-
-       Fix a lot of "possibly uninitialized variable" warnings.  Some of
-       them are even real bugs.  A few of them make me wonder how the
-       code ever worked.
-
-       * aggregate.c: (parse_aggregate_functions) Initialize `function.
-
-       * ascii.c: (output_lines) Add default case to switch.
-
-       * crosstabs.q: Remove static variable `expected' and all
-       references to it.
-       (display_crosstabulation) Always calculate expected value.
-       (calc_chisq) Ditto.
-       (output_pivot_table) Initialize `cmp'.
-       (display_crosstabulation) New variable `last_row', which is
-       initialized.
-
-       * data-in.c: (parse_numeric) Always initialize sign.  How did this
-       work at all?!
-
-       * data-list.c: (repeating_data_trns_proc) Always initialize code.
-       Always set info.ofs.  (How did this work?!)
-
-       * expr-opt.c: (optimize_tree) Always initialize `m'.
-       (evaluate_tree) Always initialize `c'.  (How did this work?)
-
-       * frequencies.q: (frq_custom_variables) Always initialize min,
-       max.
-       (frq_custom_grouped) Always initialize `dl'.
-
-       * groff-font.c: (groff_read_font) Always initialize char_set.
-
-       * matrix-data.c: (nr_output_data) Initialize `split'.
-       (wr_read_splits) Remove shadowing split_cnt declaration.
-       (wr_output_data) Initialize `split'.
-
-       * output.c: (tokener) Skip add character on syntax error.
-
-       * pool.c: (pool_strndup) Always set `copy'.  (How did this work?!)
-
-       * postscript.c: (read_ps_encodings) Use line.string instead of
-       uninitialized `bp'.
-       (write_text) Add default case to switch.
-       (text) Always initialize multiple variables.  Fix bug with
-       ligatures.
-
-       * print.c: (fixed_parse_fortran) Initialize head.
-       (alloc_line) Add default case to switch.
-
-       * recode.c: (parse_dest_spec) Handle case where nothing matches.
-       (recode_trns_proc) Move variable declaration inward.  Add default
-       case to switch.
-
-       * sfm-read.c: (read_header) Initialize skip_amt.
-
-       * sysfile-info.c: (display_variables) Always initialize pc.
-
-       * vars-prs.c: Initialized `included'.
-
-Wed Mar  3 09:30:09 2004  Ben Pfaff  <blp@gnu.org>
-
-       * main.c: (main) sigaction()'s sa_flags member was uninitialized.
-       Just use signal() instead.
-
-Wed Mar  3 09:26:30 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of vfm_sink_info and vfm_source_info.
-       
-       * aggregate.c: (agr_00x_end_func) Don't increment
-       sfm_sink_info.ncases.
-
-       * sort.c: (do_internal_sort) Get case count from
-       vfm_source->class->count().
-       (struct external_sort) Add `case_size' member.
-       (do_external_sort) Initialize case_size.
-       (struct initial_run_state) Add `case_size' member.
-       (write_initial_runs) Initialize case_size.
-       (sort_sink_write) Use case_size.
-       (read_external_sort_output) Use case_size.  Get case_cnt from
-       initial_runs.
-
-       * vfm.c: (struct write_case_data) Add underscores to existing arg
-       names, all references updated.  Renamed `aux' as `func_aux', all
-       references updated.  Added new `aux' member.
-       (global var vfm_source_info) Removed.
-       (global var vfm_sink_info) Removed.
-       (struct procedure_aux_data) New.
-       (struct split_aux_data) New.
-       (procedure) Use `aux' fields for procedure_aux_data,
-       split_aux_data.
-       (process_active_file_write_case) Pass case_count + 1 to
-       transformation procedures, exclude_this_case().
-       (process_active_file_output_case) Don't increment
-       vfm_sink_info.ncases.
-       (prepare_for_writing) Don't initialize vfm_sink_info.  Don't try
-       to send data to disk early.
-       (make_temp_case) Don't use vfm_sink_info.case_size.
-       (close_active_file) Don't initialize vfm_source_info.
-       (struct disk_stream_info) New, to allow for case_cnt and case_size fields.
-       (disk_sink_create) Initialize and/or update disk_stream_info.
-       (disk_sink_write) Ditto.
-       (disk_sink_destroy) Ditto.
-       (disk_sink_make_source) Ditto.
-       (disk_source_read) Ditto.
-       (disk_source_destroy) Ditto.
-       (global var disk_source_class) Add disk_source_count().
-       (disk_source_count) New function.
-       (struct memory_sink_info) Add `case_cnt', `case_size' members.
-       (struct memory_source_info) Ditto.
-       (memory_sink_create) Deal with case_cnt, case_size.
-       (memory_sink_write) Ditto.
-       (memory_sink_make_source) Ditto.
-       (memory_source_read) Ditto.
-       (memory_source_count) New function.
-       (memory_source_class) Add memory_source_count().
-       (procedure_write_case) Don't use vfm_sink_info.ncases.  Do use
-       proc_aux->cases_written, and pass it to transformation procedures
-       and exclude_this_case ().
-       (exclude_this_case) Add case_num parameter.  Pass it to
-       expr_evaluate().
-       (SPLIT_FILE_procfunc) Use split_aux->prev_case instead of static
-       variable.
-
-       * vfm.h: (struct case_source_class) Add `count' member.
-
-       * vfmP.h: (struct stream_info) Removed.
-       (global variable vfm_source_info) Removed.
-       (global variable vfm_sink_info) Removed.
-       
-Tue Mar  2 23:38:17 2004  Ben Pfaff  <blp@gnu.org>
-
-       * var.h: (typedef trns_proc_func) New typedef.
-       (trns_free_func) New typedef.
-       (struct trns_header) Change `proc' to type trns_proc_func, `free'
-       to type trns_free_func.  This only changes the actual type of
-       trns_proc_func, adding a `case_num' parameter.  Updated all
-       implementations to use the typedefs instead.
-
-       * compute.c: (compute_num) Pass case_num to expr_evaluate().
-       (compute_num_vec) Ditto.
-       (compute_str) Ditto.
-       (compute_str_vec) Ditto.
-
-       * do-if.c: (do_if_trns_proc) Ditto.
-
-       * expr-evl.c: (expr_evaluate) Add new case_num parameter, use for
-       OP_CASENUM.
-
-       * inpt-pgm.c: (input_program_source_read) Maintain case count,
-       pass to transformation functions.
-       (reread_trns_proc) Pass case_num arg to expr_evaluate().
-
-       * loop.c: (loop_1_trns_proc) Ditto.
-       (loop_2_trns_proc) Ditto.
-       (loop_3_trns_proc) Ditto.
-
-       * print.c: (print_space_trns_proc) Ditto.
-
-       * sel-if.c: (select_if_proc) Ditto.
-
-Tue Mar  2 11:36:52 2004  Ben Pfaff  <blp@gnu.org>
-
-       * frequencies.q: (cleanup_freq_tab) Avoid memory leak by
-       destroying hash table.
-
-       * glob.c: (read_active_file) Variable not referenced, removed.
-       (cancel_input_pgm) Ditto.
-
-       * levene.c: Add #include <stdlib.h> needed to call free().
-
-       * aggregate.c: (parse_aggregate_functions) Make `function'
-       variable const.
-
-Tue Mar  2 11:30:56 2004  Ben Pfaff  <blp@gnu.org>
-
-       Start working to eliminate VFM dependence on static variables.
-
-       * command.c: (cmd_parse) Use case_source_is_class().
-
-       * data-list.c: Rewrite to eliminate use of static variables.
-
-       * dfm.c: (cmd_begin_data) Use case_source_is_class().
-
-       * file-handle.q: (fh_handle_name) Make parameter const.
-
-       * file-type.c: Rewrite to eliminate use of static variables.
-
-       * flip.c: Rewrite to eliminate use of static variables.
-
-       * format.c: (get_format_var_width) New function.
-
-       * get.c: Eliminate use of static variables.
-
-       * inpt-pgm.c: Eliminate use of static variables.
-
-       * matrix-data.c: Eliminate use of static variables.
-
-       * set.q: (set_max_workspace) New variable.
-       (cmd_set) Use SET WORKSPACE to modify set_max_workspace.
-
-       * var.h: (struct case_list) Move here from vfmP.h.
-
-       * vars-atr.c: (discard_variables) Handle new vfm_source type.
-
-       * vfm.c: (vfm_source) Change type from struct case_stream to
-       struct case_source.
-       (vfm_sink) Change type from struct case_stream to struct
-       case_sink.
-       (static var paging) Rename workspace_overflow, all references
-       updated.
-       (procedure) Use new class structures.
-       (process_active_file) Ditto.
-       (process_active_file_write_case) Ditto.
-       (prepare_for_writing) Use set_max_workspace.  Use new class
-       structures.
-       (close_active_file) Use new class structures.  Free old sink.
-       (global var disk_source_file) Removed.
-       (global var disk_sink_file) Removed.
-       (disk_stream_init) Removed.
-       (disk_stream_read) Removed.
-       (disk_stream_write) Removed.
-       (disk_stream_mode) Removed.
-       (disk_stream_destroy_source) Removed.
-       (disk_stream_destroy_sink) Removed.
-       (global var vfm_disk_stream) Removed.
-       (disk_sink_create) New function.
-       (disk_sink_write) New function.
-       (disk_sink_destroy) New function.
-       (disk_sink_make_source) New function.
-       (disk_sink_class) New static var.
-       (disk_source_read) New function.
-       (disk_source_destroy) New function.
-       (global var vfm_source_class) New var.
-       (global var memory_source_cases) Removed.
-       (global var memory_sink_cases) Removed.
-       (global var memory_sink_max_cases) Removed.
-       (struct memory_sink_info) New struct.
-       (memory_stream_init) Removed.
-       (memory_stream_read) Removed.
-       (memory_stream_write) Removed.
-       (memory_stream_mode) Removed.
-       (memory_stream_destroy_source) Removed.
-       (memory_stream_destroy_sink) Removed.
-       (global var vfm_memory_stream) Removed.
-       (page_to_disk) Renamed write_active_file_to_disk().
-       (memory_sink_create) New function.
-       (memory_sink_write) New function.
-       (memory_sink_destroy) New function.
-       (memory_sink_make_source) New function.
-       (memory_sink_class) New static var.
-       (memory_source_read) New function.
-       (memory_source_destroy) New function.
-       (memory_source_get_cases) New function.
-       (memory_source_set_cases) New function.
-       (global var vfm_source_class) New var.
-       (procedure_write_case) Use new class structures.
-       (create_case_source) New function.
-       (case_source_is_complex) New function.
-       (case_source_is_class) New function.
-       (create_case_sink) New function.
-
-       * vfm.h: (global variable reinit_sysmis) Not used, removed.
-       (global variable reinit_blanks) Not used, removed.
-       (global variable init_zero) Not used, removed.
-       (global variable init_blanks) Not used, removed.
-       (struct case_source) New struct.
-       (struct case_source_class) New struct.
-       (struct case_sink) New struct.
-       (struct case_sink_class) New struct.
-       (struct case_stream) Removed.
-
-       * vfmP.h: (struct case_list) Moved to var.h.
-
-Tue Mar  2 11:28:30 2004  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: (count_equal) New function.
-       (count_if) New function.
-       (unique) Add assertions.
-       (partition) Add assertions.
-       (is_partitioned) New function.
-       (copy_if) Add assertions.
-       (remove_equal) Add assertions.
-       (lexicographical_compare) Rename lexicographical_compare_3way.
-       (sort) Add assertions.  Rephrase some code.
-       (is_sorted) New function.
-
-Sun Feb 29 23:24:57 2004  Ben Pfaff  <blp@gnu.org>
-
-       Rewrite SORT CASES.
-
-       * sort.c: Completely rewrite.
-
-       * sort.h: Expose interface via struct sort_cases_pgm, not via
-       global variables.
-
-       * aggregate.c: (sort) New static var.
-       (cmd_aggregate) Use sort.
-       (create_sysfile) Ditto.
-       (aggregate_single_case) Ditto.
-       (dump_aggregate_info) Ditto.
-       (agr_00x_end_func) Ditto.
-       (debug_print) Ditto.
-
-       * var.h: (enum SRT_ASCEND) Removed.
-       (enum SRT_DESCEND) Removed.
-       (struct sort_cases_proc) Removed.
-       (struct variable) Remove p.srt member.
-
-Sun Feb 29 23:22:45 2004  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of the old, crappy heap structure and replace it by a new,
-       shiny, C++ STL-like heap structure.
-       
-       * Makefile.am: (pspp_SOURCES) Remove heap.c, heap.h.
-
-       * algorithm.c: (push_heap) New function.
-       (heapify) Ditto.
-       (pop_heap) Ditto.
-       (make_heap) Ditto.
-       (sort_heap) Ditto.
-       (is_heap) Ditto.
-       
-       * heap.c: Removed.
-
-       * heap.h: Removed.
-
-Sun Feb 29 23:21:53 2004  Ben Pfaff  <blp@gnu.org>
-
-       Increase warning level.
-       
-       * Makefile.am: (AM_CFLAGS) Remove -Wnouninitialized.
-
-Sat Feb 21 17:38:58 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-        * main.c: Added a signal handler for SIGSEGV requesting a bug report.
-        
-Fri Feb 20 23:22:14 2004  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c: (dict_create_var) Fix root cause of bug worked
-       around by previous change log entry.
-       
-       * compute.c: (lvalue_finalize) Remove workaround from previous
-       change log entry.
-
-Fri Feb 20 14:37:41 WAST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * compute.c: Fixed a bug where the Format was not getting set for 
-         computed variables (thus causing a crash when SAVEing).
-
-       * Added a test to stop this bug ever coming back
-
-Wed Feb 18 22:21:35 2004  Ben Pfaff  <blp@gnu.org>
-
-       Got rid of approx.h.  In general, replaced all references to
-       approx_eq() by ==, approx_lt() by <, etc.  Other types of changes
-       noted below.
-
-       * Makefile.am: (pspp_SOURCES) Removed approx.h.
-
-       * data-out.c: (try_F) Replaced test for approx_eq(number, 0.0) by
-       test for mag < EPSILON.
-
-       * misc.h: Add definition of EPSILON.
-
-Wed Feb 18 21:32:44 2004  Ben Pfaff  <blp@gnu.org>
-
-       * vfm.c: (procedure) Add check to prevent recursive call.
-
-Wed Feb 18 21:48:54 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * Moved the declarations relating to values to their own header file
-         (val.h)
-
-       * Added levene.c and levene.h
-
-       * vars-atr.c: Changed the signature of compare_values to 
-       take const * arguments.
-               
-       * t-test.q: Changed the structure of struct t_test_proc 
-       variables now contain their own group statistics information.
-       Eventually, t_test_proc might get renamed, because it'd be 
-       applicable to other commands too.
-
-Mon Feb 16 23:15:51 2004  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c: Clean up.  Changed interface of convert_*() to take
-       either a `double' or a `const char *' instead of a `const union
-       value *'.  Update all implementations of those interfaces.
-       (data_out) Use switch statements instead of a table.
-       (convert_AHEX) Rewrite.
-
-       * format.h: Update comment.
-
-Mon Feb 16 22:14:36 2004  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: (dump_header) Add an Emacs header line to output files
-       that makes generated .c files read-only by default, to make it
-       difficult to accidentally change generated files.
-
-Mon Feb 16 22:12:07 2004  Ben Pfaff  <blp@gnu.org>
-
-       * frequencies.q: (compare_freq_numeric_a) Compare by frequency,
-       not bogus a->v.c <=> b->v.c pointer compare.
-       (compare_freq_alpha_a) Ditto.
-       (compare_freq_numeric_d) Ditto.
-       (compare_freq_alpha_d) Ditto.
-       
-Mon Feb 16 22:00:53 2004  Ben Pfaff  <blp@gnu.org>
-
-       Changed data_out() to store string data directly into a `union
-       value''s s member, not indirectly into c.
-
-       * crosstabs.q: (output_pivot_table) Use format_short() instead of
-       data_out().
-       (table_value_missing) Ditto.
-       (float_M_suffix) Ditto.
-       (format_short) New function.
-
-       * data-in.h: (data_in_finite_line) Remove inline definition.
-
-       * data-list.c: (destroy_dls_var_spec) New function.
-       (destroy_dls) Rewrite in terms of destroy_dls_var_spec().
-       (data_list_source_destroy_source) Avoid cast.
-       (struct repeating_data_trns) New field `id_value'.  Update
-       comments.
-       (cmd_repeating_data) Initialize id_value.  Use new
-       repeating_data_trns_free() for freeing REPEATING DATA
-       transformations.
-       (rpd_parse_record) Rewrite support for record ID to be less bogus.
-       (repeating_data_trns_free) New function.
-
-       * data-out.c: (data_out) Change return type to `void' by replacing
-       error returns by writing a message into the output buffer.
-       (convert_A) Read from v->s instead of v->c.
-       (convert_AHEX) Ditto.
-
-       * expr-evl.c: Update comment.
-       (expr_evaluate) Add assertion in OP_STRING case.
-
-       * format.h: (macro MAX_FORMATTED_LEN) New macro.
-
-       * list.q: (list_cases) Update for new data_out() semantics.
-
-       * print.c: (print_trns_proc) Ditto.
-
-       * tab.c: (tab_value) Ditto.
-       (tab_float) Avoid stupid cast.
-
-       * var.h: Update comments.
-       (macro MAX_STRING) New macro.
-       (macro MAX_ELEMS_PER_VALUE) New macro.
-
-       * vars-atr.c: (compare_values) New function.
-
-       * vfm.c: (dump_splits) Update for new data_out() semantics.
-
-Mon Feb 16 21:45:47 2004  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (struct table_entry) Rename v[] to values[].  All
-       references updated.
-       (struct crosstab) Rename v[] to vars[].  All references updated.
-       (hash_table_entry) Replace the hash algorithm and fix a bug at the
-       same time, which caused the hash value to depend only on a single
-       value, not all of the variables' values.
-       
-Mon Feb 16 12:49:53 2004  Ben Pfaff  <blp@gnu.org>
-
-       Clean up struct dictionary's value_cnt usage.
-
-       * dictionary.c: Add a function comment to each function.
-       (struct dictionary) Rename value_cnt to next_value_idx, which more
-       accurately reflects its meaning.  All references updated.
-       (dict_rename_vars) Add assertion.
-       (dict_get_value_cnt) Rename dict_get_next_value_idx().  All
-       references updated.
-       (dict_get_case_size) New function.
-
-       * aggregate.c: (create_sysfile) Use dict_get_case_size().
-
-       * get.c: (mtf_read_nonactive_records) Ditto.
-
-       * sort.c: (allocate_cases) Ditto.
-       (write_initial_runs) Ditto.
-       (merge) Ditto.
-       (merge_once) Ditto.
-
-       * vfm.c: (prepare_for_writing) Ditto.
-       (setup_lag) Ditto.
-       (lag_case) Ditto.
-
-Mon Feb 16 00:17:55 2004  Ben Pfaff  <blp@gnu.org>
-
-       Make vfm.c slightly less grotesque.
-
-       * vfm.c: (filter_var) Removed.
-       (filter_index) Removed.
-       (FILTERED macro) Removed.
-       (exclude_this_case) New function.
-       (process_active_file_write_case) Use exclude_this_case() instead
-       of FILTERED and inline tests.
-       (procedure_write_case) Ditto.
-       (setup_filter) Removed.
-       (open_active_file) Don't call setup_filter().
-       (close_active_file) Call dict_get_filter() instead of checking
-       filter_var.
-
-Mon Feb 16 00:01:53 2004  Ben Pfaff  <blp@gnu.org>
-
-       * var.h: (struct variable) Update comments.
-
-Sun Feb 15 23:14:59 2004  Ben Pfaff  <blp@gnu.org>
-
-       New functions dict_create_var_assert(), dict_lookup_var_assert().
-       Converted several dict_*_var()/assert pairs into a single
-       dict_*_var_assert().
-
-       * dictionary.c: (dict_create_var_assert) New function.
-       (dict_lookup_var_assert) New function.
-
-Sun Feb 15 23:06:08 2004  Ben Pfaff  <blp@gnu.org>
-
-       Got rid of "struct long_vec", envector(), devector(), etc.  Added
-       two members `init', `reinit' to struct variable as a substitute.
-       
-       * Makefile.am: (pspp_SOURCES) Removed cases.c, cases.h.
-       
-       * cases.c: Removed.
-
-       * cases.h: Removed.
-
-       * aggregate.c: (parse_aggregate_functions) destvar doesn't need
-       init.
-
-       * autorecode.c: (cmd_autorecode) destvars don't need init.
-
-       * compute.c: (lvalue_finalize) Set reinit.
-
-       * data-list.c: (fixed_parse_compatible) Don't need init usually.
-       (dump_fmt_list) Ditto.
-       (parse_free) Ditto.
-
-       * descript.q: (run_z_pass) Don't need init for z-scores.
-
-       * dictionary.c: (dict_create_var) Initialize `init', `reinit'
-       members.
-       (dict_clone_var) Copy `reinit' member, initialize `init' member.
-
-       * glob.c: (init_glob) Remove vec_init() calls.
-
-       * inpt-pgm.c: (cmd_end_input_program) Use `reinit', not `left'.
-       
-       * loop.c: (internal_cmd_loop) Don't need to call envector().
-
-       * numeric.c: (cmd_numeric) Ditto.
-       (cmd_string) Ditto.
-       (cmd_leave) Ditto.  Set `init', `reinit' members.
-
-       * recode.c: (cmd_recode) Don't need to call envector().
-
-       * repeat.c: (internal_cmd_do_repeat) Ditto.
-
-       * var.h: (struct variable) Remove `left'.  Add `init', `reinit'.
-       (force_create_variable) Removed prototype.
-       (force_dup_variable) Ditto.
-
-       * vector.c: (cmd_vector) Don't need to call envector().
-
-       * vfm.c: (reinit_sysmis) Removed.
-       (reinit_blanks) Removed.
-       (init_zero) Removed.
-       (init_blanks) Removed.
-       (process_active_file_write_case) No need to deal with vectors.
-       Call clear_temp_case().
-       (vector_initialization) Rewrite to use `init', `reinit'.
-       (close_active_file) No need to call vec_clear().
-       (procedure_write_case) Call clear_temp_case().
-       (clear_temp_case) New function.
-
-Sun Feb 15 20:50:36 2004  Ben Pfaff  <blp@gnu.org>
-
-       * pfm-write.c: (bufwrite) Get rid of nasty cast that also invoked
-       undefined behavior.
-
-Thu Feb 12 23:35:15 2004  Ben Pfaff  <blp@gnu.org>
-
-       Add auxiliary argument to procedure() interface.  Associated small
-       clean-ups of vfm interface.
-       
-       * Updated every caller of procedure() and process_active_file() to
-       reflect modified interface.  Simple, ordinary changes not listed
-       otherwise below.
-
-       * Updated every function that implements struct case_stream's
-       `read' function to take a write_case_func and a write_case_data.
-       Also updated every caller of write_case() to instead call them
-       through these arguments.  In some cases this meant that the extra
-       args had to be threaded through a couple of extra levels.  This
-       wasn't difficult or interesting so the details won't be given.
-
-       * data-list.c: (struct repeating_data_trns) Add members
-       `write_case', `wc_data' as kluge.
-       (read_one_set_of_repetitions) Rename repeating_data_trns_proc and
-       make non-static.
-       (repeating_data_set_write_case) New function.
-
-       * data-list.h: New file to declare repeating_data_trns_proc() and
-       repeating_data_set_write_case().
-
-       * inpt-pgm.c: (input_program_source_read) Call
-       repeating_data_set_write_case() for all the REPEATING DATA
-       transformations, so that they know where to send their cases.
-       It's a big kluge.  Also kluge in END CASE.
-       (end_case_trns_proc) Never called anymore, but we still need it,
-       so just assert(0).
-
-       * sort.c: (read_sort_output) Update to match struct case_stream
-       `read' member.
-
-       * vfm.c: (struct write_case_data) New structure.
-       (proc_func) Removed.
-       (virt_proc_func) Removed.
-       (begin_func) Removed.
-       (virt_begin_func) Removed.
-       (end_func) Removed.
-       (write_case) Removed.
-       (procedure) Added an auxiliary parameter to each function pointer
-       argument's prototype.  Added an auxiliary data parameter.
-       Rewrote.
-       (process_active_file) Ditto.
-       (process_active_file_write_case) Pass aux data along.
-       (close_active_file) Ditto.
-       (procedure_write_case) Ditto.
-       (SPLIT_FILE_procfunc) Ditto.
-
-       * vfm.h: (typedef write_case_data) New.
-       (typedef write_case_func) New.
-       (struct case_stream) Add parameters to `read' member prototype.
-       
-Thu Feb 12 19:24:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q:  Added calculations for independent samples. (But no Levene
-       test yet!)
-
-       * Makefile.am: Moved q_sources_c into own variable 
-
-Wed Feb 11 23:56:51 2004  Ben Pfaff  <blp@gnu.org>
-
-       Miscellaneous cleanups.
-       
-       * Change unused to UNUSED in many source files to reflect modified
-       pref.h.  Change use of __WIN32__, __MSDOS, __DJGPP__,
-       __CYGWIN32__, __unix__, and unix not to assume that they're
-       defined to a nonzero value.  Change use of __attribute__ to use
-       NO_RETURN or PRINTF_FORMAT instead.
-       
-       * alloc.h: Move definitions for local_alloc(), local_free() here
-       from ../pref.h.orig and simplify.
-
-       * expr-evl.c: Instead of working differently based on PAGED_STACK,
-       use a pool allocator unconditionally.
-       (CHECK_STRING_SPACE) Removed.
-       (ALLOC_STRING_SPACE) Removed.
-       (expr_evaluate) Use e->pool instead of CHECK_STRING_SPACE and
-       ALLOC_STRING_SPACE.
-
-       * expr-opt.c: (dump_expression) Allocate string pool.
-
-       * expr-prs.c: (expr_free) Free string pool.
-
-       * pool.c: (pool_destroy) This pool must be removed from its
-       parent's list of gizmos, not from its own.  Use free_all_gizmos().
-       (pool_clear) New function.
-       (free_all_gizmos) New function.
-       (pool_alloc) Use space in empty block after this one if any.
-       (pool_release) Only empty out blocks, don't actually free() them.
-
-       * print.c: Get rid of PAGED_STACK special case by always
-       dynamically allocating line buffers.
-       (struct print_trns) Always include the `line' member.
-       (internal_cmd_print) Always initialize the `line' member.
-       (alloc_line) Always allocate memory for `line'.
-       (print_trns_proc) Always initialize buf from `line' member.
-       (print_trns_free) Always free `line' memory.
-
-       * sort.c: (allocate_file_handles) Special-case MS-DOS for mkdir()
-       call.
-       
-Wed Feb 11 20:33:18 2004  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: Fixed crash from FLIP when a numeric variable is
-         specified on NEWNAMES and a large value is used, and a couple of
-         other minor bugs besides.
-         (struct varname) Make name a 9-character fixed-size array
-         instead of a 1-character variable size array.
-         (make_new_var) Allow digits in variable names.
-         (flip_stream_write) Limit numeric values to 8 characters and
-         format system missing and very large and small values more
-         appropriately.
-
-Thu Feb  5 13:19:06 WAST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * command.c: Fixed test on command return status for the correct 
-          value,  which had been causing a crash under certain invalid input.
-
-Wed Feb  4 15:34:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q: Added calculations for the one sample variant of the T-TEST
-
-Tue Feb  3 20:09:54 2004  Ben Pfaff  <blp@gnu.org>
-
-       * tab.c: (render_strip) Fix bug that sometimes caused joined text
-         in joined cells to be rendered outside box boundaries.
-
-Tue Feb  3 18:56:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * random.c (rng_create): Fixed seeding so that it gets reseeded after
-       SET seed=xx has been called.
-
-Mon Jan 19 14:08:09 2004  Ben Pfaff  <blp@gnu.org> 
-
-       * random.c (rng_get_double): Fix always-returning-zero bug in my
-       preferred way, and at the same time make sure rounding doesn't
-       bite us.
-
-Thu Jan  1 23:16:41 2004  Ben Pfaff  <blp@gnu.org>
-
-       * html.c: (change_attributes) Dead code, removed.
-       (escape_string) Eliminate code to call change_attributes() that
-       never actually called it.
-       (output_tab_table) Get rid of dependence on tab_hit
-       and struct tab_joined_cell's hit member, which are abominations.
-
-       * tab.c: (tab_output_text) Don't call
-       d->class->text_set_font_by_name if it's a null pointer.
-       (macro UNROLL_LOOP) Eliminate.
-       (macro UNROLL_3_LOOPS) Eliminate.
-       (tabi_render) Rewrite not to use the above macros.
-
-Thu Jan  1 23:09:07 2004  Ben Pfaff  <blp@gnu.org>
-
-       Start working on a new output driver system, one that doesn't suck
-       so much, by adding a "device-independent" output driver.  The idea
-       is to write out only a single output stream, then use separate
-       processes to translate them into whatever formats we want.  This
-       is similar to how "groff" works with its various output drivers
-       (grops, grotty, grodvi, ...).
-       
-       * Makefile.am: (pspp_SOURCES) Add devind.c, devind.h.
-
-       * list.q: (write_all_headers) Stub out devind class.
-       (clean_up) Ditto.
-       (determine_layout) Ditto.
-       (list_cases) Ditto.
-
-       * output.c: (outp_init) Add devind class.
-
-       * devind.c: New file.
-
-       * devind.h: New file.
-
-Thu Jan  1 23:08:14 2004  Ben Pfaff  <blp@gnu.org>
-
-       * frequencies.q: (hash_value_alpha) Fixed up the previous change
-       to use the proper string length.
-
-Wed Dec 31 16:27:33 WAST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * Fixed bug where FREQ would crash on alpha values
-
-Tue Dec 30 22:42:57 2003  Ben Pfaff  <blp@gnu.org>
-
-       * Removed bletcherous alloca() workarounds for AIX from top of
-       many files.  AIX can use the alternative alloca() implementation
-       instead.
-
-Tue Dec 30 22:35:16 2003  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_option) Fix implementation of headers option.
-
-Tue Dec 30 22:32:53 2003  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: Add a "squeeze" option to the ASCII driver to squeeze
-       multiple blank lines into one.
-       (struct ascii_driver_ext) Add squeeze_blank_lines option.
-       (ascii_preopen_driver) Initialize squeeze_blank_lines.
-       (static var option_tab) Add squeeze entry.
-       (ascii_option) Set squeeze_blank_lines.
-       (output_lines) Implement squeezing blank lines.
-
-Wed Dec 31 07:19:46 WST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * Removed redundant code from output.h
-
-Sat Dec 27 22:17:52 2003  Ben Pfaff  <blp@gnu.org>
-
-       Dictionary classes: each variable is "ordinary", "system", or
-       "scratch".
-
-       * var.h: (enum dict_class) New enum.
-
-       * vars-prs.c: (dict_class_from_id) New function.
-       (dict_class_to_name) New function.
-
-Sat Dec 27 22:16:06 2003  Ben Pfaff  <blp@gnu.org>
-
-       * var.h: (struct freq_tab_set) Removed (not used).
-
-Sat Dec 27 22:15:21 2003  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.c: (val_labs_destroy) vls needs to be freed too.
-
-Sat Dec 27 22:10:49 2003  Ben Pfaff  <blp@gnu.org>
-
-       * stats.c: (hypercube) Rename pow4().  All references updated.
-
-Sat Dec 27 22:05:49 2003  Ben Pfaff  <blp@gnu.org>
-
-       * rename-vars.c: (cmd_rename_variables) Rewritten.
-       (compare_name) Removed.
-
-Sat Dec 27 22:03:51 2003  Ben Pfaff  <blp@gnu.org>
-
-       var_set feature, and code taking advantage of it.
-       
-       * crosstabs.q: (static var var_dict) Removed.
-       (static var variables) New variable.
-       (static var variables_cnt) New variable.
-       (cmd_crosstabs) Free variables instead of var_dict.
-       (internal_cmd_crosstabs) Initialize and use variables,
-       variables_cnt instead of var_dict.
-       (free_var_dict) Removed.
-       (crs_custom_tables) Use var_set instead of a copied dictionary.
-       (crs_custom_variables) Set up variables, variables_cnt instead of
-       var_dict.
-       [DEBUGGING] (debug_print) Ditto.
-
-       * means.q: (mns_custom_tables) Use var_set instead of a copied
-       dictionary.
-
-       * vars-prs.c: (parse_vs_variable) New function.
-       (parse_dict_variable) Rewritten.
-       (parse_variable) Rewritten.
-       (parse_variables) Renamed parse_var_set_vars(), rewritten.
-       (parse_variables) New function in terms of parse_var_set_vars().
-       Now requires its first argument to be non-null.  All references
-       that passed a null pointer updated to pass default_dict instead.
-       (macro id_dict) Removed.
-       (parse_DATA_LIST_vars) Add assertions.
-       (parse_mixed_vars) Ditto.
-       (struct var_set) New structure.
-       (var_set_get_cnt) New function.
-       (var_set_get_var) New function.
-       (var_set_lookup_var) New function.
-       (var_set_destroy) New function.
-       (dict_var_set_get_cnt) New function.
-       (dict_var_set_get_var) New function.
-       (dict_var_set_lookup_var) New function.
-       (dict_var_set_destroy) New function.
-       (var_set_create_from_dict) New function.
-       (struct array_var_set) New structure.
-       (array_var_set_get_cnt) New function.
-       (array_var_set_get_var) New function.
-       (array_var_set_lookup_var) New function.
-       (array_var_set_destroy) New function.
-       (var_set_create_from_array) New function.
-
-       * q2c.c: (dump_parser) Use parse_variables(default_dict, ...)
-       instead of parse_variables(NULL, ...) in output code.
-
-Sat Dec 27 21:38:53 2003  Ben Pfaff  <blp@gnu.org>
-
-       Change inp_init from a 2-bit vector to an ordinary array.
-       Initialize it all in cmd_end_input_program() instead of in
-       create_variable().
-
-       * inpt-pgm.c: (enum value_init_type) New enum.
-       (global var inp_init) Change to `enum value_init_type *', make
-       static.
-       (inp_init_size) Removed.
-       (inp_nval) Change to `size_t', make static.
-       (cmd_input_program) Don't initialize inp_init or inp_init_size.
-       (cmd_end_input_program) Initialize inp_init, inp_nval.
-       (init_case) Rewrite.
-       (clear_case) Rewrite.
-
-       * inpt-pgm.h: Removed.
-
-Sat Dec 27 21:36:38 2003  Ben Pfaff  <blp@gnu.org>
-
-       * hash.c: (hsh_hash_bytes) Use Fowler-Noll-Vo hash instead of
-       Colin Plumb hash.  It is simpler and should better resist
-       collisions.
-       (hsh_hash_string) Ditto.
-
-Sat Dec 27 21:34:57 2003  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (export_write_case_func) Remove debug printing code.
-
-Sat Dec 27 21:11:09 2003  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_save_internal) Rename parameter.  Use &t->h instead
-       of cast.
-       (save_write_case_func) Use &trns->h instead of cast.
-       (cmd_export) Use &t->h instead of cast.
-
-Sat Dec 27 20:57:42 2003  Ben Pfaff  <blp@gnu.org>
-
-       Moved vectors into the dictionary.
-
-       * var.h: (struct vector) Moved here from vector.h.  `index' member
-       renamed `idx', `v' renamed `var', `nv' renamed `cnt'.  All
-       references updated.
-       
-       * vector.h: Removed.
-
-       * vector.c: (global var vec) Removed.
-       (global var nvec) Removed.
-       (cmd_vector) Rewritten.
-       (find_vector) Removed.
-
-       * dictionary.c: (dict_create_vector) New function.
-       (dict_get_vector) New function, replaces reading global vec[]
-       array.
-       (dict_get_vector_cnt) New function, replaces reading global nvec
-       variable.
-       (dict_lookup_vector) New function, replaces find_vector().
-       (dict_clear_vectors) New function.
-
-Sat Dec 27 20:54:01 2003  Ben Pfaff  <blp@gnu.org>
-
-       Start to move away from `struct variable' p `union' member to void
-       * aux member.
-
-       * var.h: (struct variable) Add `aux' member.
-
-Sat Dec 27 20:36:25 2003  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of struct variable `foo' member.
-
-       * frequencies.q: (internal_cmd_frequencies) Use p.frq.used instead
-       of foo.
-       (frq_custom_variables) Ditto.
-       (frq_custom_grouped) Ditto.
-
-       * get.c: (struct save_trns) Change `var' member from `int *' to
-       `struct variable **'.
-       (cmd_save_internal) Use aux instead of foo.
-       (save_trns_proc) Use revised `var' member.
-       (static var mtf_seq_no) Renamed mtf_seq_num.
-       (static var mtf_seq_nums) New static var.
-       (cmd_match_files) Initialize mtf_seq_nums.
-       (mtf_free) Free mtf_seq_nums.
-       (mtf_processing) Use mtf_seq_nums instead of foo.
-       (mtf_merge_dictionary) No need to initialize mv->foo.
-       (cmd_export) Use aux instead of foo.  Use revised `var' member.
-       (mns_custom_tables) Don't use foo to check for duplicates, that's
-       what PV_NO_DUPLICATE is for.
-
-       * var.h: (struct variable) Remove `foo' member.
-       (struct frequencies_proc) New member.
-       
-Sat Dec 27 19:46:13 2003  Ben Pfaff  <blp@gnu.org>
-
-       Clean up COMPUTE and IF.
-
-       * compute.c: More or less rewrite the darn thing.
-       (struct compute_trns) Rename and reorder and add and delete
-       members.
-       (cmd_compute) Rewrite.
-       (compute_num) Make conditional on test expression.  Now used for
-       both COMPUTE and IF.
-       (compute_num_vec) Ditto.
-       (compute_str) Ditto.
-       (compute_str_vec) Ditto.
-       (cmd_if) Rewrite.
-       (if_num) Removed.
-       (if_num_vec) Removed.
-       (if_str) Removed.
-       (if_str_vec) Removed.
-       (parse_target_expression) Renamed parse_rvalue_expression(),
-       rewritten.
-       (new_trns) Renamed compute_trns_create(), rewritten.
-       (delete_trns) Removed.
-       (free_trns) Renamed compute_trns_free(), rewritten.
-       (struct lvalue) New structure.
-       (parse_var_or_vec) Renamed lvalue_parse(), rewritten.
-       (lvalue_get_type) New function.
-       (lvalue_is_vector) New function.
-       (lvalue_finalize) New function.
-       (lvalue_destroy) New function.
-       
-Sat Dec 27 19:44:14 2003  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Disallow MODIFY VARS in input mode, so that
-       variables can't get dropped and confuse cmd_end_input_program()'s
-       attempt to fill inp_init[].
-       
-       * modify-vars.c: (static var forward_positional_ordering) New
-       variable.
-       (struct var_modification) Entirely changed.
-       (rearrange_dict) Interface changed, rewritten.
-       (cmd_modify_vars) Deal with modified struct var_modification, much
-       rewritten.
-       (struct var_renaming) New structure.
-       (compare_var_renaming_by_new_name) New function.
-       (validate_var_modification) New function.
-
-       * var.h: (struct modify_vars_proc) Removed.
-       (struct variable) Removed member p.mfv.
-
-Sat Dec 27 19:40:26 2003  Ben Pfaff  <blp@gnu.org>
-
-       Make EVALUATE a valid command whether we're debugging or not, so
-       that `make check' can succeed regardless of whether debugging is
-       turned on.
-       
-       * command.def: [GLOBAL_DEBUGGING] Drop the #if.
-
-       * compute.c: [GLOBAL_DEBUGGING] (cmd_evaluate) Drop the #if.
-
-Sat Dec 27 19:34:40 2003  Ben Pfaff  <blp@gnu.org>
-
-       * apply-dict.c: (cmd_apply_dictionary) Replace a ghastly switch
-       statement by a simple if test.
-
-       * dfm.c: (dfm_get_record) Add assertion.
-
-Sat Dec 27 17:51:26 2003  Ben Pfaff  <blp@gnu.org>
-
-       For each file x.c, move #include "x.h" to the very top of the
-       include list, to catch x.h failing to include the proper headers.
-
-Sat Dec 27 17:50:19 2003  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: (find) New function.
-       (remove_equal) New function.
-       (set_difference) New function.
-       (adjacent_find_equal) New function.
-       [TEST_UNIQUE] Removed test case.
-       (copy_if) Find end test.
-
-Sat Dec 27 17:42:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c: (dict_get_case_weight) New convenience function.
-
-       * aggregate.c: (accumulate_aggregate_info) Use
-       dict_get_case_weight().
-
-       * frequencies.q: (calc_general) Ditto.
-       (calc_integer) Ditto.
-       (calc) Ditto.
-
-       * t-test.q: (groups_calc) Ditto.
-       (z_calc) Ditto.
-
-Sat Dec 27 17:29:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * glob.c: (global var default_dict) Change from `struct
-       dictionary' to `struct dictionary *'.  All references changed.
-       (init_glob) Initialize default_dict with dict_create().
-
-Sat Dec 27 17:06:06 2003  Ben Pfaff  <blp@gnu.org>
-
-       struct dictionary now made opaque.  All related functions:
-
-       * get.c: (rename_variables) Removed.
-       (dict_delete_run) Removed.
-       
-       * temporary.c: (copy_variable) Removed.
-       (new_dictionary) Removed.
-       (save_dictionary) Removed.
-       (restore_dictionary) Removed.
-       (free_dictionary) Removed.
-
-       * vars-atr.c: (clear_default_dict) Removed.
-       (find_variable) Removed.
-       (find_dict_variable) Removed.
-       (create_variable) Removed.
-       (delete_variable) Removed.
-       (common_init_stuff) Removed.
-       (init_variable) Removed.  Updating of inp_init moved into
-       cmd_end_input_program().
-       (replace_variable) Removed.
-       (rename_variable) Removed.
-       (clear_variable) Removed.
-       (dup_variable) Removed.
-
-       * vars-prs.c: (is_varname) Removed.
-       (is_dict_varname) Removed.
-       (fill_all_vars) Removed.
-
-       * vector.c: (find_vector) Removed.
-
-       * weight.c: (stop_weighting) Removed.
-
-       * dictionary.c: New file.
-       (dict_create) New, replaces new_dictionary().
-       (dict_clone) New, replaces save_dictionary() and
-       restore_dictionary().
-       (dict_clear) New, replaces clear_default_dict().
-       (dict_destroy) New, replaces free_dictionary().
-       (dict_get_var_cnt) New function, replaces references to
-       dict->nvar.
-       (dict_get_var) New function, replaces references to dict->var[i].
-       (dict_get_vars) New function, replaces fill_all_vars().
-       (dict_create_var) New, replaces create_variable().  Interface
-       drops `type' parameter, using a zero `width' to designate numeric.
-       (dict_clone_var) New, replaces dup_variable().
-       (dict_rename_var) New, replaces rename_variable().
-       (dict_lookup_var) New, replaces find_variable(),
-       find_dict_variable(), is_varname().
-       (dict_contains_var) New function.
-       (compare_variable_dblptrs) New function.
-       (dict_delete_var) New function, replaces clear_variable().
-       (dict_delete_vars) New function, replaces dict_delete_run().
-       (dict_reorder_vars) New function.
-       (dict_rename_vars) New function, replaces rename_variables().
-       (dict_get_weight) New function, replaces reading dict->weight_var.
-       (dict_set_weight) New function, replaces writing dict->weight_var
-       or calling stop_weight(dict).
-       (dict_get_filter) New function, replaces reading dict->filter_var.
-       (dict_set_filter) New function, replaces writing dict->filter_var.
-       (dict_get_case_limit) New function, replaces reading dict->N.
-       (dict_set_case_limit) New function, replaces writing dict->N.
-       (dict_get_value_cnt) New function, replaces reading dict->nval.
-       (dict_compact_values) New function, replaces a loop that was
-       replicated in several places.
-       (dict_get_split_vars) New function, replaces reading dict->splits.
-       (dict_get_split_cnt) New function, replaces reading
-       dict->n_splits.
-       (dict_set_split_vars) New function, replaces writing dict->splits.
-       (dict_get_label) New function, replaces reading dict->label.
-       (dict_set_label) New function, replaces writing dict->label.
-       (dict_get_documents) New function, replaces reading
-       dict->documents.
-       (dict_set_documents) New function, replaces writing
-       dict->documents.
-       
-       All references to above functions updated.
-       
-       * aggregate.c: (cmd_aggregate) Copy file label and documents from
-       old dictionary to new by hand, because dict_create() can't do it
-       itself.  Use dict_set_documents(), dict_set_split_vars().
-
-       * temporary.c: (cancel_temporary) Also set temp_dict to NULL after
-       calling dict_destroy().
-
-       * data-list.c: (dls_var_spec) Remove `type' member, replace by
-       `width'.
-       (fixed_parse_compatible) Some slightly nontrivial changes for
-       dict_create_var().
-       (dump_fmt_list) Ditto.
-       (parse_free) Ditto.
-
-       * file-type.c: (create_col_var) Ditto.
-
-       * get.c: (cmd_get) Use dict_compact_values() instead of a loop.
-       (trim_dictionary) Use dict_delete_vars(), dict_reorder_vars().
-       (rename_variables) Use dict_rename_vars().
-       (mtf_merge_dictionary) Use dict_get_documents(),
-       dict_set_documents(), dict_compact_values().
-
-       * pfm-read.c: (read_variables) Deal with changes to weighting.
-
-       * q2c.c: (dump_parser) Use dict_lookup_var() instead of
-       is_varname() in output code.
-
-       * sfm-read.c: (read_header) Use dict_create(), dict_set_label(),
-       other dictionary functions.
-
-       * title.c: (add_document_line) Use dict_get_documents(),
-       dict_set_documents().
-
-       * vars-atr.c: (discard_variables) Use dict_clear(default_dict),
-       reset default_handle by hand.  dict_clear() will clear vectors so
-       there's no need for that by hand.
-
-       * vfm.c: (close_active_file) Move call to finish_compaction()
-       earlier, so that we can do the compaction as a single step using
-       dict_compact_values().  Use dict_clear_vectors().
-       (finish_compaction) Use dict_delete_var(), dict_compact_values().
-               
-       Some functions don't have replacements:
-
-       * vars-atr.c: (force_create_variable) Removed.  All references
-       updated to dict_create_var() followed by an assertion.
-       (force_dup_variable) Removed.  All references updated to
-       dict_clone_var() followed by an assertion.
-       
-       * weight.c: (update_weighting) Removed.  No longer necessary, so
-       all references removed.
-
-Sat Dec 27 16:43:01 2003  Ben Pfaff  <blp@gnu.org>
-
-       Clean up AGGREGATE.
-       
-       * aggregate.c: Eliminate separation of weighted and unweighted
-       case.  It made the code too obscure and I doubt it was actually
-       faster.  Instead, all code uses the "weighted" code, because
-       that's a generalization of the "unweighted" code.
-       (FWEIGHT) Removed.
-       (FOPTIONS) Ditto.
-       (parse_aggregate_functions) No need to set FWEIGHT.
-       (accumulate_aggregate_info) Get rid of FWEIGHT cases.
-       (dump_aggregate_info) Ditto.
-       (initialize_aggregate_info) No need for special plain_function
-       that gets rid of FWEIGHT option.
-
-       * aggregate.c: Get rid of approximations.
-       (accumulate_aggregate_info) Don't use approx_gt(), approx_lt(),
-       approx_in_range().
-       (aggregate_single_case) Don't use approx_ne().
-
-Sat Dec 27 16:19:36 2003  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c (ascii_line_width): Dead code, removed.
-
-       * postscript.c (ps_line_width): Ditto.
-
-       * q2c.c (xrealloc): Ditto.
-
-       * count.c (internal_cmd_count): Ditto.
-
-       * means.q (validate_dependent_endpoint): Ditto.
-
-       * set.q: (cmd_gset) Ditto.
-
-       * weight.c: [0] (weight_trns_proc) Ditto.
-
-Sat Dec 27 16:18:16 2003  Ben Pfaff  <blp@gnu.org>
-
-       Make the code -Wmissing-prototypes clean.
-
-       * Makefile.am (version.c): Add #include "version.h".
-       
-       * ascii.c: (ascii_open_global) Make static.
-       (ascii_close_page) Ditto.
-       (ascii_font_sizes) Ditto.
-       (ascii_postopen_driver) Ditto.
-       (ascii_close_driver) Ditto.
-       (ascii_option) Ditto.
-       (ascii_open_page) Ditto.
-       (ascii_line_horz) Ditto.
-       (ascii_line_vert) Ditto.
-       (ascii_line_intersection) Ditto.
-       (ascii_box) Ditto.
-       (ascii_polyline_begin) Ditto.
-       (ascii_polyline_point) Ditto.
-       (ascii_polyline_end) Ditto.
-       (ascii_text_set_font_by_name) Ditto.
-       (ascii_text_set_font_by_position) Ditto.
-       (ascii_text_set_font_by_family) Ditto.
-       (ascii_text_get_font_name) Ditto.
-       (ascii_text_get_font_family) Ditto.
-       (ascii_text_set_size) Ditto.
-       (ascii_text_get_size) Ditto.
-       (ascii_text_metrics) Ditto.
-       (ascii_text_draw) Ditto.
-       (ascii_close_page) Ditto.
-
-       * cmdline.h: New header for parse_command_line().  Used where
-       needed.
-
-       * command.c: Move prototypes for cmd_*() functions to command.h.
-
-       * command.h: Prototypes for cmd_*() functions moved here from
-       command.c.
-
-       * crosstabs.q: (gamma_int) Ditto.
-
-       * file-handle.h: Add fh_init_files() prototype.
-       
-       * getline.c: (welcome) Ditto.
-
-       * glob.h: New header for init_glob().  Used where appropriate.
-
-       * hash.c: (comparison_helper) Ditto.
-
-       * html.c: (html_open_global) Ditto.
-       (html_close_global) Ditto.
-       (html_preopen_driver) Ditto.
-       (html_postopen_driver) Ditto.
-       (html_close_driver) Ditto.
-       (html_option) Ditto.
-       (html_open_page) Ditto.
-       (html_close_page) Ditto.
-       (html_submit) Ditto.
-
-       * inpt-pgm.c: (input_program_source_read) Ditto.
-
-       * output.c: (find_defn_value) Ditto.
-       (destroy_list) Ditto.
-
-       * pfm-read.c: (read_int) Ditto.
-
-       * postscript.c: (ps_open_global) Ditto.
-       (ps_close_global) Ditto.
-       (ps_font_sizes) Ditto.
-       (ps_preopen_driver) Ditto.
-       (ps_postopen_driver) Ditto.
-       (ps_close_driver) Ditto.
-       (ps_option) Ditto.
-       (ps_open_page) Ditto.
-       (ps_close_page) Ditto.
-       (ps_line_horz) Ditto.
-       (ps_line_vert) Ditto.
-       (ps_line_intersection) Ditto.
-       (ps_box) Ditto.
-       (ps_polyline_begin) Ditto.
-       (ps_polyline_point) Ditto.
-       (ps_polyline_end) Ditto.
-       (ps_text_set_font_by_name) Ditto.
-       (ps_text_set_font_by_position) Ditto.
-       (ps_text_set_font_family) Ditto.
-       (ps_text_get_font_name) Ditto.
-       (ps_text_get_font_family) Ditto.
-       (ps_text_set_size) Ditto.
-       (ps_text_get_size) Ditto.
-       (ps_text_metrics) Ditto.
-       (ps_text_draw) Ditto.
-
-       * q2c.c: (finish_up) Ditto.
-       (xmalloc) Ditto.
-       (xstrdup) Ditto.
-       (get_buffer) Ditto.
-       (st_lower) Ditto.
-       (st_upper) Ditto.
-       (skip_ws) Ditto.
-       (get_line) Ditto.
-       (add_symbol) Ditto.
-       (find_symbol) Ditto.
-       (lex_get) Ditto.
-       (force_id) Ditto.
-       (force_string) Ditto.
-       (match_id) Ditto.
-       (match_token) Ditto.
-       (skip_token) Ditto.
-       (parse) Ditto.
-       (parse_setting) Ditto.
-       (parse_specifier) Ditto.
-       (parse_specifiers) Ditto.
-       (parse_subcommand) Ditto.
-       (dump_specifier_vars) Ditto.
-       (is_keyword) Ditto.
-       (make_identifier) Ditto.
-       (dump_declarations) Ditto.
-       (dump_specifier_init) Ditto.
-       (dump_vars_init) Ditto.
-       (make_match) Ditto.
-       (dump_specifier_parse) Ditto.
-       (dump_subcommand) Ditto.
-       (dump_parser) Ditto.
-       (dump_header) Ditto.
-       (dump_free) Ditto.
-       (recognize_directive) Ditto.
-
-       * recode.c: (string_to_long) Ditto.
-
-       * repeat.c: (find_DO_REPEAT_substitution) Ditto.
-
-       * repeat.h: New header for perform_DO_REPEAT_substitutions, used
-       where appropriate.
-
-       * sort.c: (sort_stream_read) Ditto.
-       (sort_stream_mode) Ditto.
-       
-Fri Dec 19 23:35:04 2003  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c (binary_search): Fix comparison.
-
-Fri Dec 19 23:27:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * algorithm.c: (binary_search) Fix assertion.
-
-Fri Dec 19 21:31:48 2003  Ben Pfaff  <blp@gnu.org>
-
-       * sysfile-info.c: (compare_vectors_by_name) Rewrite.
-
-Fri Dec 19 21:30:24 2003  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: (compare_case_lists) Rewrite.
-
-Fri Dec 19 16:44:22 2003  Ben Pfaff  <blp@gnu.org>
-
-       * quicksort.c: Removed (not used).
-
-       * quicksort.h: Removed (not used).
-
-       * sort.c: Removed blp_quicksort() prototype.
-
-Fri Dec 19 16:42:13 2003  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: (int_2_compare) Rewrite.
-       (compare_line) Rewrite.
-
-Fri Dec 19 16:38:35 2003  Ben Pfaff  <blp@gnu.org>
-
-       * matrix-data.c (compare_factors) Use lexicographical_compare()
-       algorithm.
-       (compare_doubles) New function.
-       
-       * algorithm.c: (lexicographical_compare) New algorithm.
-
-Fri Dec 19 16:23:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * matrix-data.c (compare_variables_by_mxd_vartype): Rewrite.
-
-Fri Dec 19 15:54:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * expr-prs.c: (cmp_func) Removed.
-       (parse_function) Use binary_search() algorithm.
-       (compare_functions) New function.
-       (init_func_tab) Use sort() algorithm.
-
-       * algorithm.c: (binary_search) New algorithm.
-
-Fri Dec 19 15:50:45 2003  Ben Pfaff  <blp@gnu.org>
-
-       * descript.q: (display) Use sort() algorithm instead of qsort().
-       (compare_func) Removed.
-       (descriptives_compare_variables) New function.
-
-Fri Dec 19 15:08:38 2003  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of AVL trees.  Hashes are more appropriate for everything
-       PSPP does.
-
-       * Makefile.am: (pspp_SOURCES) Remove avl.c, avl.h.
-       
-       * avl.c: Removed.
-
-       * avl.h: Removed.
-
-Fri Dec 19 14:33:31 2003  Ben Pfaff  <blp@gnu.org>
-
-       Much code can be clarified by using C++ STL-like algorithms.  Not
-       all uses of these algorithms are listed below, only the ones where
-       the change to an algorithm was the only change of interest.
-       
-       * Makefile.am: (pspp_SOURCES) Add algorithm.c, algorithm.h.
-       
-       * algorithm.c: New file.
-
-       * algorithm.h: New file.
-
-       * modify-vars.c: (static var forward) Removed.
-       (static var positional) Removed.
-       (compare_variables) Removed.
-       (struct ordering) New.
-       (cmd_modify_vars) Use sort() algorithm.
-       (compare_variables_given_ordering) New function.
-       (rearrange_dict) Use sort() algorithm.
-
-       * sysfile-info.c: (cmd_display) Use sort() algorithm.
-       (cmp_var_by_name) Removed.
-
-Fri Dec 19 14:26:17 2003  Ben Pfaff  <blp@gnu.org>
-
-       Make file handles use a hash table.
-       
-       * file-handle.q: (files) Change to hash table, make static.
-       (cmd_file_handle) Use hash table functions.
-       (fh_get_handle_by_filename) Ditto.
-       (fh_get_handle_by_name) Ditto.
-       (hash_file_handle) New function.
-       (cmp_file_handle) Rewrite.
-       (fh_init_files) Use hash table functions.
-
-Fri Dec 19 14:24:38 2003  Ben Pfaff  <blp@gnu.org>
-
-       Clean up FREQUENCIES.
-       
-       * Makefile.am: (pspp_SOURCES) Remove frequencies.g.
-
-       * frequencies.q: Remove a lot of old #if'd out code at the end.
-       (internal_cmd_frequencies) Use calc() instead of calc_no_weight()
-       or calc_weight().  Initialize percentile_values.
-       (calc) New function based on calc_weight() from frequencies.g.
-       (precalc) Use hash functions.
-       (static var comparison_func) Removed.
-       (static var comparison_param) Removed.
-       (comparison_helper) Removed.
-       (get_freq_comparator) New function.
-       (not_missing) New function.
-       (add_freq) Removed.
-       (postprocess_freq_tab) Use hash table functions, algorithms,
-       get_freq_comparator().  Rewrite.
-       (cleanup_freq_tab) Rephrase.
-       (add_percentile) Clean up spacing.
-       (hash_value_numeric) New function.
-       (hash_value_alpha) New function.
-       (compare_value_numeric_a) Rewrite.
-       (compare_value_alpha_a) Rewrite.
-       (compare_value_numeric_d) Rewrite.
-       (compare_value_alpha_d) Rewrite.
-       (compare_freq_numeric_a) Rewrite.
-       (compare_freq_alpha_a) Rewrite.
-       (compare_freq_numeric_d) Rewrite.
-       (compare_freq_alpha_d) Rewrite.
-       (calc_stats) Clean up mode, percentiles, max.
-       (dump_statistics) Clean up spacing.
-       
-       * frequencies.g: Removed.
-
-       * var.h: (struct freq_tab) Change `data' to hash table.
-
-Fri Dec 19 14:15:46 2003  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.h: Remove declaration of global variable `files',
-       which wasn't used anywhere.
-
-       * postscript.c: (add_encoding) Remove superfluous cast.
-       (line) Ditto.
-
-       * sfm-read.c: [linux] (bswap_int32) Drop ntohl() non-portable
-       version.
-
-       * temporary.c: [0] (display_tree) Removed.
-
-Fri Dec 19 14:13:04 2003  Ben Pfaff  <blp@gnu.org>
-
-       Implement a new random number generator based on the alleged RC4
-       algorithm.
-
-       * expr-evl.c: (expr_evaluate) Use rng_get_double_normal() instead
-       of rand_normal().
-
-       * random.c: [!HAVE_GOOD_RANDOM] (real_rand) Removed.
-       [!HAVE_GOOD_RANDOM] (real_srand) Removed.
-       (macro k) Removed.
-       (static var V[]) Removed.
-       (static var Y) Removed.
-       (static var X2) Removed.
-       (setup_randomize) Removed.
-       (shuffle) Removed.
-       (rand_uniform) Removed.
-       (rand_normal) Removed.
-       (struct rng) New structure.
-       (rng_create) New function.
-       (rng_destroy) New function.
-       (swap_byte) New static function.
-       (rng_seed) New function.
-       (rng_get_bytes) New function.
-       (rng_get_int) New function.
-       (rng_get_unsigned) New function.
-       (rng_get_double) New function.
-       (rng_get_double_normal) New function.
-       (pspp_rng) New function.
-
-       * random.h: Sync up to random.c.
-
-       * sample.c: (struct sample_trns) Make `frac' unsigned and a
-       fraction of UINT_MAX, not 65536.
-       (cmd_sample) Use rng_get_unsigned(), rng_get_double(), UINT_MAX
-       fraction.
-
-       * vfm.c: (open_active_file) No need to call setup_randomize() any
-       longer.
-
-Fri Dec 19 12:05:56 2003  Ben Pfaff  <blp@gnu.org>
-
-       Change dictionary name indexes to use hash tables instead of AVL
-       trees.
-
-       * crosstabs.q: (free_var_dict) Use hash tables.
-       (crs_custom_tables) Ditto.
-       (calc_general) Ditto.
-       (compare_table_entry) Rewrite.
-       (enum_var_values) Reorder parameters.  All references updated.
-       Rewrite.
-
-       * get.c: (rename_variable) Use hash tables.
-       (mtf_merge_dictionary) Ditto.
-
-       * glob.c: (init_glob) Use hash tables.
-       (cmp_variable) Removed.
-
-       * means.q: (mns_custom_tables) Use hash tables.
-
-       * modify-vars.c: (rearrange_dict) Use hash tables.
-
-       * rename-vars.c: (cmd_rename_variables) Use hash tables.
-
-       * sfm-read.c: (read_header) Use hash tables.
-       (read_variables) Ditto.
-
-       * temporary.c: (new_dictionary) Use hash tables.
-       (save_dictionary) Ditto.
-       (restore_dictionary) Ditto.
-
-       * var.h: (struct dictionary) Change AVL tree `var_by_name' into
-       hash table `name_tab'.
-
-       * vars-atr.c: [DEBUGGING] (dump_one_var_node) Removed.
-       [DEBUGGING] (dump_var_tree) Removed.
-       (find_variable) Use hash tables.
-       (find_dict_variable) Ditto.
-       (common_init_stuff) Ditto.
-       (rename_variable) Ditto.
-       (clear_variable) Ditto.  Also, remove debug code.
-       (dup_variable) Use hash tables.
-
-       * vars-prs.c: (fill_all_vars) Use hash tables.
-       (is_dict_varname) Ditto.
-       (parse_dict_variable) Ditto.
-       
-Fri Dec 19 11:46:23 2003  Ben Pfaff  <blp@gnu.org>
-
-       Change value labels to use hash tables instead of AVL trees, and
-       change value labels into an ADT.
-
-       * Makefile.am: (pspp_SOURCES) Add value-labels.c, value-labels.h.
-       
-       * value-labels.c: New file.
-
-       * value-labels.h: New file.
-
-       * apply-dict.c: (cmd_apply_dictionary) Use value label ADT.
-       Get rid of a stupid use of goto.
-
-       * autorecode.c: (compare_alpha_value) Rewrite.
-       (hash_alpha_value) Ditto.
-       (compare_numeric_value) Rewrite.
-       (hash_numeric_value) Ditto.
-
-       * frequencies.q: (dump_full) Use value label ADT.
-
-       * pfm-read.c: (read_value_label) Use value label ADT.
-
-       * pfm-write.c: (write_value_labels) Use value label ADT.
-
-       * sfm-read.c: (read_variables) Use value label ADT.
-       (read_value_labels) Rewrite.
-
-       * sfm-write.c: (write_value_labels) Rewrite.
-
-       * sysfile-info.c: (cmd_sysfile_info) Use value label ADT.
-       (display_variables) Ditto.
-       (describe_variable) Ditto.
-
-       * t-test.q: (print_t_groups) Use value label ADT.
-
-       * temporary.c: (copy_variable) Use value label ADT.
-       (free_dictionary) Ditto.
-
-       * val-labs.c: (verify_val_labs) Use value label ADT.
-       (get_label) Ditto.
-       (debug_print) Ditto.
-       (val_lab_cmp) Removed.
-       (inc_ref_count) Removed.
-       (copy_value_labels) Removed.
-
-       * var.h: (struct value_label) Removed.
-       (struct variable) Change AVL tree `val_lab' into hash table
-       `val_labs'.
-
-       * vars-atr.c: (init_variable) Use value label ADT.
-       (clear_variable) Ditto.
-       (free_value_label) Removed.
-       (free_val_lab) Removed.
-       (get_val_lab) Removed.
-       (compare_variables) New function.
-       (hash_variable) New function.
-
-       * vfm.c: (dump_splits) Use value label ADT.
-
-Fri Dec 19 11:18:11 2003  Ben Pfaff  <blp@gnu.org>
-
-       Add to the hash table interface.
-
-       * hash.c: (hsh_hash_bytes) Add assertion.
-       (hsh_hash_string) Ditto.
-       (hsh_clear) Ditto.
-       (hsh_rehash) Ditto.
-       (hsh_probe) Ditto.
-       (hsh_create) Ditto.  Also make minimum `size'.
-       (hsh_destroy) Rephrase.
-       (sort_nulls_last) Removed.
-       (not_null) New function.
-       (hsh_data) Ditto.
-       (comparison_helper) Ditto.
-       (hsh_sort) Rewritten.
-       (hsh_data_copy) New function.
-       (hsh_sort_copy) Ditto.
-       (hsh_insert) Ditto.
-       (hsh_replace) Ditto.
-       (hsh_hash_double) Ditto.
-       (hsh_delete) Fix stupid bug.
-       
-Thu Dec 18 12:27:03 WAST 2003 John Darrington <john@darrington.wattle.id.au>
-        * added a calculation of the mode to FREQUENCIES
-
-Wed Dec 17 12:53:01 WAST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * moved (un)defs of DEBUGGING to config.h
-
-Mon Dec 15 21:35:59 2003  Ben Pfaff  <blp@gnu.org>
-
-       * groff-font.c: (add_kern) Fix indentation.
-       (add_kern) Use & instead of % to take power-of-2 modulus.
-       (font_get_kern_adjust) Likewise.
-
-Fri Dec 12 23:54:37 2003  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.c: (recode) Replace stupid use of memcpy() by
-       memberwise copy.
-       (hash_alpha_value) Use hsh_hash_bytes().  Get rid of nasty casts.
-       (hash_numeric_value) Ditto.
-       (autorecode_proc_func) pool_strdup() was wrong here because the
-       source string was not null-terminated.  Use new pool_strndup()
-       instead.
-
-       * crosstabs.q: (enum_var_values) Remove superfluous and bizarre
-       use of hsh_iterator_init().
-
-       * data-in.c: (parse_N) Initialize i->v->f.
-
-       * flip.c: (cmd_flip) Use memmove(), not memcpy(), to copy
-       overlapping arrays.
-
-       * groff-font.c: Use power-of-2 hash table sizes, not prime.
-       (groff_read_font) Don't call hsh_next_prime().  Don't call
-       fclose(NULL).
-       (static var hash) Remove `size_p', `max_used' members.
-       (font_char_name_to_index) Don't call hsh_next_prime().  Use
-       hsh_hash_string() instead of hashpjw(), & instead of %.
-       (default_font) Don't call hsh_next_prime().
-
-       * pool.c: (pool_strndup) New function.
-       (pool_strdup) Reimplement in terms of pool_strndup.
-
-       * postscript.c: (hash_font_entry) Use hsh_hash_string().  Get rid
-       of nasty casts.
-       (hash_ps_encoding) Use hsh_hash_string().
-       (hash_ps_combo) Use hsh_hash_string(), hsh_hash_int().
-       (hash_filename2font) Use hsh_hash_string().
-
-       * som.c: Add #include <stdlib.h>.
-
-       * tab.c: (tab_destroy) Don't set t->container after freeing `t'
-       (by destroying its pool).
-       
-Fri Dec 12 23:18:59 2003  Ben Pfaff  <blp@gnu.org>
-
-       Miscellaneous hash table code cleanup:
-       
-       * hash.h: (struct hsh_table) Moved into hash.c.
-       (hsh_count) Ditto, and transformed into function.
-       (hsh_compare_func) New typedef, used for defining otherwise-long
-       function types here and in hash.c
-       (hsh_hash_func) Ditto.
-       (hsh_free_func) Ditto.
-       
-       * hash.c: (struct hsh_table) Renamed `n' to `used', `m' to `size',
-       `table' to `entries'.  Removed `mp'.  All references updated.
-       (hsh_clear) Don't shrink entries array; if the hash was this big
-       once, it probably will be again.
-       (hsh_rehash) Made static.
-       (force_hsh_insert) Renamed hsh_force_insert.
-       (force_hsh_find) Renamed hsh_force_find.
-
-       Made hash table sizes powers of 2, because that's fine with any
-       reasonable hash function and because taking a power-of-2 modulus
-       is faster than any other:
-       
-       (hsh_prime_tab) Removed;
-       (hsh_next_prime) Ditto.
-       (next_power_of_2) New function.
-       (hsh_create) Use next_power_of_2.
-       (hsh_rehash) Use & instead of %.
-
-       Cleaned up hsh_sort:
-       
-       (internal_comparison_fn) Removed.
-       (sort_nulls_last) New function.
-       (hsh_sort) Removed second parameter, switched to using the new
-       quicksort() function from quicksort.h to avoid using nasty need
-       for static variables with qsort().  All references updated.
-
-       Changed the hash functions offered, because there are better hash
-       functions than the ones we had, and cleaned up the names to boot:
-       
-       * hash.c: (hashpjw_d) Removed.
-       (hashpjw) Ditto.
-       (hsh_hash_bytes) New function.
-       (hsh_hash_string) New function.
-       (hsh_hash_int) New function.
-
-       Improved the hash table iteration interface:
-       
-       * hash.h: (hsh_iterator_init) Removed.
-       (struct hsh_iterator) Removed `init' member, change `next' to
-       size_t.
-
-       * hash.c: (hsh_foreach) Removed.  All references updated to use
-       hsh_first/hsh_next instead.
-       (hsh_first) New function.  Notably, unlike hsh_foreach() it does
-       not treat a null pointer as an empty hash table.
-       (hsh_next) New function.
-
-       Made deletion possible, though slow:
-
-       * hash.c: (locate_matching_entry) New function.
-       (hsh_find) Use locate_matching_entry().
-       (hsh_delete) New function also using locate_matching_entry().
-       (hsh_force_delete) New function.
-
-Fri Dec 12 23:16:10 2003  Ben Pfaff  <blp@gnu.org>
-
-       * quicksort.c: New file implementing a sort routine with a
-       interface better than qsort() because it passes a user-provided
-       parameter to the sort routine.
-
-       * Makefile.am: Add quicksort.c, quicksort.h.
-
-Fri Dec 12 13:31:58 2003  Ben Pfaff  <blp@gnu.org>
-
-       * All source files: Get rid of nasty special cases for Checker,
-       which is pretty obsolete now.
-
-Thu Dec 11 21:38:24 WST 2003 John Darrington <john@darrington.wattle.id.au>
-
-       * Fixed a bug apparent when using the FREQUENCIES command with the
-       html driver.  The html driver was incorrectly trying to display 
-       empty cells.
-
-Sun Jan  2 21:40:13 2000  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Reorganized.  Put locale dir in version.c instead
-       of passing it to each compile command.  Only put local gmp libs in
-       LD_ADD if not installed on system.  Remove `boast' target.
-
-       * All source files: struct and union typedefs eliminated.
-       `sizeof type' replaced by `sizeof object' where practical.  Moved
-       `unused' qualifiers from start to end of declarations for gcc
-       2.7.2 compatibility.  Change `while (1)' to `for (;;)'.  Made
-       assertions on pointers strictly compliant.  Removed _ prefixes on
-       some function parameter names.
-
-       * alloc.c: New source file, containing these external linkage
-       functions removed from common.c: xmalloc, xcalloc, xrealloc,
-       xstrdup.
-
-       * arena.c: Removed.
-       
-       * arena.h: Removed.
-
-       * ascii.c: Migrated from arenas to pools.
-       (struct ascii_driver_ext) ops[], box[], fonts[] changed from
-       c_string to len_string.  All references changed.
-       (ascii_option) Signature changed to comply to new output.c
-       interface.
-       (count_fancy_chars) Removed.
-       (delineate) Removed support for rich text.
-       (ascii_text_metrics) Ditto.
-       (text_draw) Ditto.
-       (output_shorts) Change `box', `off', `on' from c_string to
-       len_string.  Change `remaining' from int to size_t.
-       (ascii_close_page) Make page numbering less haphazard.
-
-       * autorecode.c: Migrate from arenas to pools.
-
-       * avl.c: Migrate from arenas to pools.  Synch from libavl 1.4.0.
-
-       * bitvector.h: New file containing these macros from misc.h:
-       SET_BIT, CLEAR_BIT, SET_BIT_TO, TEST_BIT, BIT_INDEX.
-
-       * command.c: (struct command) cmd1, cmd2, cmd3 members changed to
-       word[3].  ncmd removed.
-       (var empty_string) Removed.
-       (var cmd_table) Declaration updated.
-       (var cmdtab) Removed.
-       (cmp_command) Removed.
-       (split_words) Rewritten to use strtok_r().
-       (init_cmd_parser) Renamed cmd_init().  Rewritten.
-       (find_command) Removed.
-       (FILE_TYPE_okay) Rewritten.
-       (cmd_parse) Rewritten.  Semantics of the return value of command
-       handlers has changed: they must now return one of the new CMD_*
-       enumerals, rather than a magic value.  This meant that all
-       commands had to be modified, and they were.
-       (figure_out_command) New function.
-
-       * command.def: Add CORRELATIONS, PEARSON CORRELATIONS.  Add
-       #defines for INIT, INPU, etc.
-
-       * command.h: New CMD_* enum series.
-       (cur_proc) Make const char *, not char *.
-       (cmd_init) Prototype.
-       (cmd_parse) Ditto.
-
-       * common.c: Removed.
-
-       * common.h: Removed.
-
-       * correlations.q: New file.
-
-       * crosstabs.q: Migrate from arenas to pools.  Migrate to new-style
-       q2c.
-       (custom_tables) Renamed crs_custom_tables().
-       (custom_variables) Renamed crs_custom_variables().
-       (calc_integer) Add in some `const' qualifiers.
-       (table_value_missing) Change from a_string to len_string.
-       (float_M_suffix) Change from a_string to len_string.
-
-       * data-in.c: Rewritten.  All references to
-       parse_string_as_format() changed to data_in().
-
-       * data-in.h: New file.
-
-       * data-list.c: Change DLS_* from #define's to enums.  Move from
-       rpd_msg() to tmsg().
-       (RPD_ERR) New #define.
-       (do_reading) Change dfm_push_cust() to dfm_push(), pop_cust() to
-       dfm_pop().
-       (read_from_data_list_fixed) Change from old
-       parse_string_as_format() to new data_in().
-       (read_from_data_list_free) Ditto.
-       (read_from_data_list_list) Ditto.
-       (cmd_repeating_data) Modify approach to checking for end of
-       command.
-       (rpd_msg) Removed.
-       (rpd_parse_record) Change from old parse_string_as_format() to new
-       data_in().  Change from old convert_format_to_string() to new
-       data_out().
-       (read_one_set_of_repetitions) Change dfm_push_cust() to
-       dfm_push(), pop_cust() to dfm_pop().
-
-       * data-out.c: Rewritten.  All references to
-       convert_format_to_string() changed to data_out().
-
-       * descript.q: Migrate to new q2c.
-       (cmd_descriptives) Removed.
-       (internal_cmd_descriptives) Renamed cmd_descriptives ().
-       (custom_variables) Renamed dsc_custom_variables().
-
-       * dfm.c: (struct dfm_fhuser_ext) `ln' removed.  All references
-       removed.
-       (open_file_r) Initialize h->where.line_number.  Migrate to new
-       struct string.
-       (open_file_w) Initialize h->where.line_number.
-       (read_record) Change from ext->ln to h->where.line_number.
-       Migrate to struct string.
-       (dfm_put_record) Rephrased.
-       (dfm_push_cust) Renamed dfm_push(), rewritten.
-       (dfm_pop) New function.
-
-       * error.c: All references updated.
-       (glob var error_count) Renamed err_err_count.
-       (glob var warning_count) Renamed err_warning_count.
-       (glob var error_already_flagged) Renamed err_already_flagged.
-       (glob var verbosity) Renamed err_verbosity.
-       (glob var cust_fn) Removed.
-       (glob var cust_ln) Removed.
-       (static var file_loc) New.
-       (static var nfile_loc) New.
-       (static var mfile_loc) New.
-       (tmsg) New function.
-       (push_cust) Removed.
-       (pop_cust) Removed.
-       (msg) Rewritten.
-       (static var terminating) Removed.
-       (failure) Renamed err_failure().
-       (hcf) Renamed err_hcf().
-       (err_push_file_locator) New function.
-       (err_pop_file_locator) New function.
-       (err_location) New function.
-       (check_error_count) Renamed err_check_count().
-       (vmsg) Renamed err_vmsg().  Interface changed.
-       (verbose_msg) Removed.
-       (err_cond_fail) New function.
-       (error_break) Renamed err_break().
-
-       * error.h: All references updated.
-       (enum MSG_CLASS_COUNT) Renamed ERR_CLASS_COUNT.
-       (enum ERR_CLASS_MASK, ERR_VERBOSITY_SHIFT, ERR_VERBOSITY_MASK)
-       New.
-       (struct file_locator) New.
-       (struct error) New.
-       (macro verbose_msg) Removed.
-       (macro cond_fail) Removed.
-
-       * expr-opt.c: (evaluate_tree) sizeof(char) == 1.
-
-       * expr-prs.c: Reorganized.  All references updated.
-       (exprtypename) Renamed expr_type_name().
-       (typename) Renamed type_name().
-       (free_expression) Renamed expr_free().
-       (parse_expression) Renamed expr_parse().  Uses new type_check()
-       function.
-       (init_functab) Renamed init_func_tab().
-       (type_check) New function.
-       (parse_or) Rewritten to use new allocate_nonterminal() and
-       append_nonterminal_arg() functions.
-       (parse_and) Ditto.
-       (parse_not) Ditto.
-       (parse_rel) Ditto.  Also simplified logic.
-       (parse_add) Ditto.
-       (parse_mul) Ditto.
-       (parse_neg) Ditto.
-       (parse_exp) Ditto.
-       (SYSMIS_func) Ditto.
-       (VALUE_func) Rephrased.
-       (CONCAT_func) Fix memory leak by replacing free by free_node on
-       lossage.
-       (generic_str_func) Ditto.
-       (parse_function) Ditto.  Also rephrasings.  Uses bsearch() to find
-       function.
-       (allocate_nonterminal) New function.
-       (append_nonterminal_arg) New function.
-       (static func_tab[]) Now at file level.
-       (cmp_func) Moved.
-       (init_func_tab) Moved.  Now just uses qsort() to sort func_tab[].
-
-       * expr.h: (enum series OP_*) Moved to exprP.h.
-       (OP_* defines) Ditto.
-       (struct op_desc) Ditto.
-       (global ops[]) Ditto.
-       (struct num_con_node) Ditto.
-       (struct str_con_node) Ditto.
-       (struct var_node) Ditto.
-       (struct lag_node) Ditto.
-       (struct casenum_node) Ditto.
-       (struct nonterm_node) Ditto.
-       (union any_node) Members renamed.
-       (struct sys_node) Removed.
-       (struct val_node) Removed.
-       (operator typedef) Removed.
-       (typedef exprtype) Removed.
-       (enum series EX_*) Moved to exprP.h.
-       (struct expression) Ditto.  Also renamed a lot of the members.
-       (PXP_* defines) Changed to enums.
-       (free_node prototype) Moved to exprP.h.
-
-       * file-handle.h: (struct file_handle) New member `where'.
-
-       * file-handle.q: Migrated to new q2c format.
-       (prepend_current_directory) Removed (dead code).
-       (cmd_file_handle) Incorporated all of internal_cmd_file_handle().
-       (fh_get_handle_by_filename) Removed dead code.
-       Set new `where' member.
-
-       * file-type.c: (file_type_source_read) References to
-       parse_string_as_format() changed to data_in().
-       dfm_push_cust()/pop_cust() changed to dfm_push()/dfm_pop().
-
-       * filename.c: All references updated.
-       (init_filename) Renamed fn_init().
-       (expand_line) Removed.
-       (macro EXPAND_LINE) Removed.
-       (interp_vars) Renamed fn_interp_vars().  Now uses st_*() instead
-       of custom functions.
-       (gnu_getcwd) Renamed fn_get_cwd(), rewritten.
-       (tilde_expand) Renamed fn_tilde_expand(), uses ds_*().
-       (normalize_filename) Renamed fn_normalize().
-       (search_path) Renamed fn_search_path(), rewritten.
-       (prepend_dir) Renamed fn_prepend_dir().
-       (blp_getenv) Renamed fn_getenv().
-       (blp_dirname) Renamed fn_dirname().
-       (fn_basename) New function, not used.
-       (absolute_filename_p) Renamed fn_absolute_p().
-       (is_special_filename) Renamed fn_special_p().
-       (file_exists) Renamed fn_exists_p().
-       (readlink_malloc) Renamed fn_readlink().
-       (getenv_default) Renamed fn_getenv_default().
-       (open_file) Renamed fn_open().
-       (close_file) Renamed fn_close().
-       (open_file_ext) Renamed fn_open_ext().
-       (close_file_ext) Renamed fn_close_ext().
-
-       * font.h: Migrate from arenas to pools.
-
-       * format.c: (parse_format_specifier_name) Deal with ds_* strings.
-
-       * frequencies.g: Migrate from arenas to pools.
-
-       * frequencies.q: Migrate to new q2c version.  Migrate from arenas
-       to pools.
-
-       * getline.c: All references updated.
-       (global getl_buf) Changed from char * to struct string.
-       (static getl_include_path) Ditto.
-       (global getl_buf_len) Removed.
-       (global getl_buf_size) Removed.
-       (getl_include_path) Deal with new getl_buf, getl_include_path.
-       (getl_uninitialize) New function.
-       (getl_get_current_directory) Rewritten.
-       (getl_clear_include_path) Rewritten.
-       (getl_add_include_dir) Rewritten.
-       (getl_add_file) Assertion fixed.
-       (getl_add_virtual_file) Change initial value of `remaining_loops'
-       from 2 to 1.
-       (welcome) Rewritten.
-       (handle_line_buffer) Make static.  Change logic to make
-       getl_add_virtual_file() change sensible.  Use ds_*() strings.
-       (getl_read_line) Use ds_*() strings.  Implement SET ECHO.
-       (getl_close_file) Moved.
-       (getl_location) New function.
-
-       * getline.h: All references updated.
-       (macro curln) Removed.
-       (macro curfn) Removed.
-       (macro am_interactive) Renamed getl_am_interactive.
-       (macro am_reading_script) Renamed getl_reading_script.
-
-       * glob.c: (global fmt_parse_ignore_error) Removed.
-       (init_glob) Use locale_dir not LOCALEDIR.  Use feholdexcept() on
-       systems that support it (C99).  Turn off SET ECHO by default.  No
-       necessary julcal initialization anymore.
-
-       * groff-font.c: Migrate from arenas to pools.
-       (groff_read_font) Use err_push_file_locator().
-       (groff_read_DESC) Ditto.
-       (font_msg) Use tmsg().
-
-       * hash.c: (hsh_sort) Fix debug code.
-       [GLOBAL_DEBUGGING] Include stdio.h.
-
-       * hash.h: (macro force_hsh_insert) Rephrase.
-
-       * heap.c: Rewritten.
-       
-       * heap.h: Rewritten.
-
-       * html.c: (html_option) Change from outp_value to struct string.
-       (postopen) Change from curfn to getl_location().
-       (escape_string) Remove rich-text code.  Signature changed.
-       (output_tab_table) Switch from a_string to struct len_string.
-       Remove rich text support.
-
-       * lexer.c: All references updated.  Largely rewritten.  Major
-       changes listed below.  Removed tagged quote support.  Adapted to
-       struct string tokstr.
-       (global tokstr) Changed to struct string.
-       (global tokstr_size) Removed.
-       (global tokstr_len) Removed.
-       (global tokid) New.
-       (global tokint) Removed.
-       (global toklongstr) Removed.
-       (C* defines) Removed.
-       (static tbl[]) Removed.
-       (static id[]) Removed.
-       (static une[]) Removed.
-       (discard_line) Renamed lex_discard_line().
-       (get_entire_line) Renamed lex_entire_line().
-       (get_rest_of_line) Renamed lex_rest_of_line().
-       (get_dotted_rest_of_line) Merged into lex_rest_of_line().
-       (make_hexit) Removed.
-       (syntax_error) Renamed lex_error().  Return value removed.
-       (get_token_representation) Renamed lex_token_representation().
-       (putback) Renamed lex_put_back().
-       (putfwd) Renamed lex_put_forward().
-       (convert_negative_to_dash) Renamed lex_negative_to_dash().
-       (set_prog) Renamed lex_set_prog().
-       (init_lex) Renamed lex_init().
-       (reset_eof) Renamed lex_reset_eof().
-       (lookahead) Renamed lex_look_ahead().
-       (check_id) Rewritten.
-       (yylex) Renamed lex_get(), rewritten.
-       (lex_end_of_command) New function.  Many commands were rephrased
-       using this.
-       (lex_integer_p) New function.  Replaces compare of tokint against
-       NOT_LONG.
-       (lex_integer) New function.  Replaces tokint.
-       (match_tok) Renamed lex_match().
-       (match_id) Renamed lex_match_id().
-       (match_int) Renamed lex_match_int().
-       (force_match_id) Renamed lex_force_match_id(), added return value.
-       (force_match) Renamed lex_force_match(), added return value.
-       (force_string) Renamed lex_force_string(), added return value.
-       (force_int) Renamed lex_force_int(), added return value.
-       (lex_id_match_len) New function.
-       (id_match) Renamed lex_id_match(), rewritten.
-       (get_line) Renamed lex_get_line().
-       (preprocess_line) Renamed lex_preprocess_line().
-       (tokname) Renamed lex_token_name().
-       (bin_value_func) Removed.
-       (oct_value_func) Removed.
-       (hex_value_func) Removed.
-       (unexpected_eof) New function.
-       (convert_numeric_string_to_char_string) New function.
-       (parse_string) Rewritten, signature changed.
-       (add_tokstr_char) Removed.
-       (add_tokstr_unsigned) Removed.
-       (add_tokstr_string) Removed.
-       (parse_tagged_quote) Removed.
-       (skip_comment) Renamed lex_skip_comment().
-
-       * lexer.h: All references updated.
-       (macro is_id1) Renamed CHAR_IS_ID1.
-       (macro is_idn) Renamed CHAR_IS_IDN.
-       (token names ID, NUM, STRING, STOP, ... WITH, EXP) Renamed with
-       prefix T_: T_ID, T_NUM, T_STRING, T_STOP, ... T_WITH, T_EXP.
-       (macro get_token) Removed.
-       (macro id_match) Removed.
-       (macro force_match_id) Removed.
-       (macro force_match) Removed.
-       (macro force_string) Removed.
-       (macro force_int) Removed.
-       (macro force_num) Removed.
-       (macro force_id) Removed.
-
-       * lexerP.h: Removed.
-
-       * list.q: Migrated to new q2c format.
-       (write_line) Deal with struct len_string.
-       (write_varname) Ditto.
-       (write_fallback_headers) Ditto.
-
-       * magic.c: New file, incorporating the following global variables
-       previously in other files: endian, second_lowest_value.  And both
-       of those are conditional on #define's.
-
-       * magic.h: New file, incorporating the following global variable
-       declarations: endian, second_lowest_value, and the following macro
-       declarations: NOT_DOUBLE, NOT_LONG, NOT_INT.
-
-       * main.c: Added declarations of pgmname, finished, curdate,
-       start_interactive.
-       (main) Call new parse_script() function.
-       (parse_script) New function.
-       (execute_command) New function.
-       (dump_token) Removed.
-       (handle_error) New function.
-
-       * matrix.c: New file.
-
-       * matrix.h: New file.
-
-       * matrix-data.c: Migrated from arenas to pools.
-       (mget_token) Change from parse_string_as_format() to data_in().
-
-       * means.q: Migrate to new q2c.
-       (custom_tables) Renamed mns_custom_tables().
-       (custom_crossbreak) Renamed mns_custom_crossbreak().
-       (custom_variables) Renamed mns_custom_variables().
-
-       * mis-val.c: (static var width) Changed from `int' to `size_t'.
-       (parse_varnames) Prototype.
-       (parse_numeric) Rephrasings.
-       (parse_alpha) Adapt to new struct string tokstr.
-
-       * misc.c: (intlog10) Rewritten.
-       (spacing) Removed.
-       (ansi_rand) Renamed real_rand(), moved into random.c.
-       (ansi_srand) Renamed real_srand(), moved into random.c.
-       (setup_randomize) Moved to random.c.
-       (rand_uniform) Ditto.
-       (rand_normal) Ditto.
-       (rand_simple) Ditto.
-       (get_config_line) Removed.
-       (reverse) Removed (dead code).
-
-       * misc.h: (macro SET_BIT) Moved to bitvector.h.
-       (macro CLEAR_BIT) Ditto.
-       (macro TEST_BIT) Ditto.
-       (macro SET_BIT_TO) Ditto.
-       (macro BIT_INDEX) Ditto.
-
-       * output.c: (outp_read_devices) Move to err_push_file_locator()
-       from push_cust().  Use struct string.
-       (expand_op_tokstr) Removed.
-       (static var op_tokstr) Changed to struct string.
-       (static var op_tokstr_size) Removed.
-       (tokener) Rephrasings.  Use struct string.
-       (parse_options) Use struct string.
-       (destroy_driver) Fix assertion.
-       (outp_get_paper_size) Move to err_push_file_locator().
-       [0] Removed dead code.
-       (outp_string_width) Move to len_string.
-
-       * output.h: Comment fixes.
-       (TAG_* enum series) Removed.
-       (struct outp_value) Removed.
-       (enum OUTP_T_FANCY) Removed.
-       (struct outp_text) `s' changed from a_string to len_string.
-       (struct outp_class) `option' change arg 3 from outp_value to
-       struct string.
-
-       * pfm-read.c: (corrupt_msg) Rewritten.
-
-       * pfm-write.c: (bufwrite) Fix assertion.
-
-       * pool.c: New file, reference version.
-
-       * pool.h: New file, reference version.
-
-       * postscript.c: (ps_font_sizes) Fix assertion.
-       (ps_option) Change arg 3 from outp_value to struct string.
-       Adapt to struct string.
-       (macro output_line) Removed.
-       (macro add_string) Removed.
-       (output_encodings) Adapted to struct string.  Moved to
-       err_push_file_locator().
-       (find_encoding_file) Fix assertion.
-       (read_ps_encodings) Move to err_push_file_locator().
-       (postopen) Use getl_location() instead of curfn.
-       (out_text_plain) Move to len_string.
-       (text) Ditto.  Remove rich text support.
-
-       * print.c: (cmd_print) Remove now-unneeded resource cleanup code.
-       (cmd_print_eject) Ditto.
-       (cmd_write) Ditto.
-       (internal_cmd_print) Now cleans up after itself.  Uses
-       fh_parse_file_handle() now.
-       (cmd_print_space) Use PXP_NUMERIC to type-check.
-
-       * q2c.c: Overhauled.  Removed _("") i18n support.  All references
-       updated.  All output functions updated to handle structures rather
-       than local or static variables.  Adapt to new PSPP lex_*()
-       functions.
-       (macro _) Removed.
-       (macro N_) Removed.
-       (macro MAX_N_SBC) Removed.
-       (global bare) Removed.
-       (enum STRING) Renamed T_STRING.
-       (enum ID) Renamed T_ID.
-       (get_buffer) Buffer size increased.
-       (strlower) Renamed st_lower(), rephrased.
-       (strupper) Renamed st_upper(), rephrased.
-       (skip_ws) New function.
-       (get_line) Don't special-case any types of lines (like those
-       beginning with ! or $, for instance).
-       (get_token) Renamed lex_get().  Rephrased.
-       (static var `prefix') New.
-       (parse) New function.
-       (parse_setting) Minor rephrasing.
-       (dump_specifier_vars) Ditto.
-       (make_identifier) Put null terminator on identifier, duh.
-       (dump_vars) Renamed dump_declarations().  Never indent.  Never
-       static.  Output changed entirely.
-       (dump_specifier_init) Rephrase.
-       (dump_vars_init) No index variable needed.  Other modifications.
-       (dump_parser) Don't parse command name.  Do dump functions instead
-       of just code fragments.
-       (dump_free) Dump function instead of code fragment.
-       (recognize_directive) New function.
-       (main) Use recognize_directive().  Don't rely on magic $ line
-       beginning: instead, parse comments.  Update list of headers.
-
-       * random.c: New file, containing the following functions:
-       real_rand(), real_srand(), setup_randomize, shuffle, rand_uniform,
-       rand_normal, rand_simple.
-
-       * random.h: New file.
-
-       * recode.c: (cmd_recode) Merge internal_cmd_recode() into this
-       function.  `max_src_width', `max_dst_width' changed to size_t.
-       (internal_cmd_recode) Removed.
-       (parse_dest_spec) Merge similar cases.
-       (parse_src_spec) Add assertion.
-
-       * repeat.c: (recognize_keyword) New function.
-       (internal_cmd_do_repeat) Parse and handle PRINT keyword on END
-       REPEAT.  Improve recognition of END REPEAT (use
-       recognize_keyword()).  Move from curfn to getl_location().  Use
-       struct string.
-               
-       (perform_DO_REPEAT_substitutions) Adapt to struct string.
-
-       * set.q: Adapt to new q2c.
-       (cmd_set) Range-check some values better.
-       (custom_blanks) Renamed stc_custom_blanks().
-       (custom_length) Renamed stc_custom_length().
-       (custom_results) Renamed stc_custom_results().
-       (custom_seed) Renamed stc_custom_seed().
-       (custom_width) Renamed stc_custom_width().
-       (custom_format) Renamed stc_custom_format().
-       (custom_journal) Renamed stc_custom_journal().
-       (custom_color) Renamed stc_custom_color().
-       (custom_listing) Renamed stc_custom_listing().
-       (custom_disk) Renamed stc_custom_disk().
-       (custom_log) Renamed stc_custom_log().
-       (custom_rcolor) Renamed stc_custom_rcolor().
-       (custom_viewlength) Renamed stc_custom_viewlength().
-       (custom_workdev) Renamed stc_custom_workdev().
-
-       * settings.h: Not necessary to include format.h any longer.
-
-       * sfm-read.h: (macro bswap_int32) Moved here from sfmP.h.
-       (corrupt_msg) Rewritten.
-
-       * sort.c: Adapt to rewritten heap ADT.
-
-       * str.c: (aa_strcpy) Removed.
-       (ab_strcpy) Removed.
-       (ac_strcpy) Removed.
-       (ba_strcpy) Removed.
-       (bb_strcpy) Removed.
-       (ca_strcpy) Removed.
-       (aa_strdup) Removed.
-       (aa_strdupcpy) Removed.
-       (ba_strdup) Removed.
-       (sa_strdup) Removed.
-       (memrev) Renamed mm_reverse().
-       (memrmem) Renamed mm_find_reverse().
-       (cmp_str) Renamed st_compare_pad().
-       (strmaxcpy) Removed.
-       (strbarepadcpy) Renamed st_bare_pad_copy(), signature changed.
-       (strbarepadlencpy) Renamed st_bare_pad_len_copy(), signature
-       changed.
-       (strpadcpy) Renamed st_pad_copy(), signature changed.
-       (blpstrset) Removed.
-       (ds_create) New function.
-       (ds_init) New function.
-       (ds_replace) New function.
-       (ds_destroy) New function.
-       (ds_clear) New function.
-       (ds_extend) New function.
-       (ds_shrink) New function.
-       (ds_truncate) New function.
-       (ds_length) New function.
-       (ds_size) New function.
-       (ds_value) New function.
-       (ds_end) New function.
-       (ds_concat) New function.
-       (ds_concat_buffer) New function.
-       (ds_printf) New function.
-       (ds_putchar) New function.
-       (ds_getline) New function.
-       (ds_get_config_line) New function derived from the old
-       misc.c:get_config_line().
-       (ls_create) New function.
-       (ls_create_buffer) New function.
-       (ls_init) New function.
-       (ls_shallow_copy) New function.
-       (ls_destroy) New function.
-       (ls_null) New function.
-       (ls_null_p) New function.
-       (ls_empty_p) New function.
-       (ls_length) New function.
-       (ls_value) New function.
-       (ls_end) New function.
-
-       * str.h: Reformatted.
-       (struct a_string) Removed.
-       (struct b_string) Removed.
-       (struct c_string) Removed.
-       (struct len_string) New.
-       (struct string) New.
-       (macro as_streq) Removed.
-       (macro bs_streq) Removed.
-       (macro cs_streq) Removed.
-       (macro sa_streq) Removed.
-       (macro sb_streq) Removed.
-       [__GNUC__] (inline function ds_putchar) New function.
-       [__GNUC__] (inline function ds_length) New function.
-       [__GNUC__] (inline function ds_value) New function.
-       [__GNUC__] (inline function ds_end) New function.
-
-       * sysfile-info.c: (cmd_sysfile_info) Rephrased.
-       (display_vectors) Fix missing i18n.
-
-       * t-test.q: Migrate to new q2c.
-
-       * tab.c: Migrate from arenas to pools.
-       (tab_create) Use struct len_string.
-       (tab_realloc) Ditto.
-       (text_format) Ditto.
-       (tab_joint_text) Ditto.
-       (tab_natural_width) Remove rich text support.
-       (tab_natural_height) Ditto.
-       (tab_output_text) Handle TAT_FIX.
-       (tab_raw) Change arg from a_string to len_string.
-       (tabi_driver) Fix assertion.  Use struct len_string.
-       (render_strip) Use struct len_string.  Remove rich text support.
-       Add `const' qualifiers.
-
-       * tab.h: (enum TAB_RICH) Remove.
-       (enums TAB_COL_NONE, TAB_COL_DONE) New.  Where appropriate,
-       SOM_COL_* updated to read TAB_COL_*.
-       (struct tab_table) Change arena to pool.  Change a_string to
-       len_string.
-
-       * temporary.c: (restore_dictionary) Rewrite Checker code.
-
-       * var.h: (macros MAX_SHORT_STRING, MIN_LONG_STRING, SYSMIS,
-       LOWEST, HIGHEST) Moved here from common.h.
-       (typedef any_trns) Removed.  All references changed to `struct
-       trns_header'.
-
-       * vars-atr.c: (force_create_variable) Fix assertion.
-       (force_dup_variable) Fix assertion.
-       
-Thu Jun  3 18:40:42 1999  Ben Pfaff  <blp@gnu.org>
-
-       Using alphanumeric variables in functions under AGGREGATE
-       segfaulted.  Fixed.  Thanks to Dr. Dirk Melcher
-       <BZN-mdksh@t-online.de> for reporting this bug.
-       
-       * aggregate.c: (parse_aggregate_functions) When setting the
-       FSTRING bit, also allocate memory for the `string' member of
-       agr_next.
-       (free_aggregate_functions) Free iter->string.  Don't use the
-       non-function bits when indexing the array of functions.
-       [DEBUGGING] (debug_print) Don't use the non-function bits when
-       indexing the array of functions.        
-
-Sun May 30 00:00:54 1999  Ben Pfaff  <blp@gnu.org>
-
-       Under certain circumstances, the final case would be omitted from
-       the results of an AGGREGATE operation.  Fixed.  Thanks to Dr. Dirk
-       Melcher <BZN-mdksh@t-online.de> for reporting this bug.
-       
-       * aggregate.c (agr_00x_end_func): Increment number of cases in
-       sink before writing case.  For streams that keep track of how many
-       cases there are based on this value, this means that the last case
-       will be read in on the next stream read.
-
-Sat May 29 22:03:31 1999  Ben Pfaff  <blp@gnu.org>
-
-       Undefined behavior was invoked by referencing a freed pointer.
-       
-       * vfm.c (memory_stream_write): Free pointer *after* checking for
-       non-null status.
-
-Sat May 29 22:02:22 1999  Ben Pfaff  <blp@gnu.org>
-
-       A wrong record size was displayed when paging the active file to
-       disk.
-       
-       * vfm.c: (memory_stream_write) Fix off-by-one error.
-
-Sat May 29 21:50:26 1999  Ben Pfaff  <blp@gnu.org>
-
-       Not having enough temporary space for sorting caused a core dump.
-       Fixed.
-       
-       * sort.c: (allocate_cases) Initialize i.
-
-Sat May 29 21:40:54 1999  Ben Pfaff  <blp@gnu.org>
-
-       Syntax errors in function descriptions on AGGREGATE caused core
-       dumps.  Fixed.
-       
-       * aggregate.c (cmd_aggregate): Don't free agr_dict after calling
-       free_aggregate_functions(), since that function already frees
-       agr_dict.
-       
-Sat May 29 21:06:10 1999  Ben Pfaff  <blp@gnu.org>
-
-       A null pointer was dereferenced, causing a core dump, when
-       PERCENTILES was specified on FREQUENCIES.  This fixes the problem,
-       but PSPP still doesn't calculate percentiles.  Thanks to Regnor
-       Jernsletten <rjernsle@eunet.no> for reporting this problem.
-       
-       * arena.c: (arena_malloc) If the arena hasn't been initialized
-       already, initialize it.
-
-Sat May 29 20:47:29 1999  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.cygwin: New file supplied by Hankin <hankin@dunno.com>
-       for compilation with Cygnus Windows B20.  Not used by other
-       systems.
-
-Sat May 29 20:36:04 1999  Ben Pfaff  <blp@gnu.org>
-
-       SORT always sorted in ascending order.  Fixed.  Thanks to Dr. Dirk
-       Melcher <BZN-mdksh@t-online.de> for reporting this bug.
-
-       * sort.c: (compare_case_lists) Reverse sense of comparison if
-       sorting in descending order.
-       (compare_record) Ditto.
-
-Tue Mar  9 13:18:54 1999  Ben Pfaff  <blp@gnu.org>
-
-       SPLIT FILE with a string variable caused a core dump.  Fixed.
-
-       * vfm.c: If the variable is a string then make a temporary value
-       struct pointing to it.  The underlying problem is a lot bigger
-       than this (see TODO) but this is a stopgap for the simple case at
-       least.
-       
-Tue Mar  9 13:15:53 1999  Ben Pfaff  <blp@gnu.org>
-
-       Nested INCLUDEs didn't work.  Fixed.
-
-       * getline.c: (getl_include) Set first_line to NULL in allocated
-       structure.
-
-Tue Mar  9 13:13:46 1999  Ben Pfaff  <blp@gnu.org>
-
-       The MATCH FILES procedure set the values of variables not present
-       to 0.  It should have been SYSMIS.  This is now fixed.
-
-       * get.c: (mtf_delete_file_in_place) Replace 0.0 by SYSMIS.
-
-Tue Mar  9 12:52:23 1999  Ben Pfaff  <blp@gnu.org>
-
-       The REMARK command was too aggressive about skipping lines.  It
-       didn't like being the last command in a file.
-
-       * command.c: (cmd_remark) Call get_entire_line() instead of
-       get_line().
-
-Tue Mar  9 12:48:05 1999  Ben Pfaff  <blp@gnu.org>
-
-       Comment parsing wasn't consistent with the rest of the code in its
-       idea of where one command ends and another starts.  This meant
-       that sometimes commands would be mysteriously ignored.  Thanks to
-       Dr. Dirk Melcher <BZN-mdksh@t-online.de> for reporting this bug.
-        
-       * command.c: (parse_cmd) Hand off comment parsing to new function
-       skip_comment() in lexer.c.
-       * lexer.c: (skip_comment) New function.
-
-Wed Jan 20 20:22:07 1999  Ben Pfaff  <blp@gnu.org>
-
-       The TABLE subcommand on MATCH FILES worked only erratically at
-       best.  This fixes it.  Thanks to Dr. Dirk Melcher
-       <BZN-mdksh@t-online.de> for reporting this bug.
-
-       * get.c: (mtf_compare_BY_values) When comparing string values, a
-       difference of 1 is still a difference :-)
-       (mtf_processing) Inverted TABLE reading logic fixed.  Also don't
-       advance TABLE files automatically when matched.  Comment fixes.
-
-Tue Jan 19 22:32:31 1999  Ben Pfaff  <blp@gnu.org>
-
-       VARIABLE LABELS rejected a slash before the first variable
-       specification, contradicting the documentation.  Thanks to Walter
-       M. Gray <graywm@northernc.on.ca> for reporting this bug.
-
-       * var-labs.c: (cmd_variable_labels) Ignore a leading slash in
-       command specification.
-
-Tue Jan 19 22:29:54 1999  Ben Pfaff  <blp@gnu.org>
-
-       Because of an incorrect optimization in memory allocation,
-       CROSSTABS sometimes segfaulted when asked to output multiple
-       tables.  Thanks to Walter M. Gray <graywm@northernc.on.ca> for
-       reporting this bug.
-
-       * crosstabs.q: (postcalc) New variables maxcols, maxcells, which
-       are passed to output_pivot_table() for its use.
-       (output_pivot_table) Instead of assuming the number of columns is
-       constant, keep track with maxcols.  In general mode, use maxcells
-       to determine whether more matrix cells need to be allocated.    
-
-Tue Jan 19 22:27:46 1999  Ben Pfaff  <blp@gnu.org>
-
-       CROSSTABS didn't display value labels for column and row
-       variables.  Thanks to Walter M. Gray <graywm@northernc.on.ca> for
-       reporting this bug.
-
-       * crosstabs.q: (table_value_missing) If the specified value has a
-       value label for this variable, then show it instead of the raw
-       value.
-       (display_dimensions) Delegate display of value_labels to
-       table_value_missing.
-
-Mon Jan 18 20:04:06 1999  Ben Pfaff  <blp@gnu.org>
-
-       WRITE didn't write line ends.  Fixed.  Thanks to Dr. Dirk Melcher
-       <BZN-mdksh@t-online.de> for reporting this bug.
-
-       * print.c: (print_trns_proc) Write (CR/)LF if PRINT is used _or_
-       if the file isn't declared as binary.
-
-Mon Jan 18 19:56:45 1999  Ben Pfaff  <blp@gnu.org>
-
-       MATCH FILES corrupted memory and dumped core on some syntax
-       errors.  Fixed.
-
-       * get.c: (cmd_match_files) Set file->handle to NULL before
-       jumping to lossage.
-       (mtf_free_file) Don't free a null dictionary.   
-
-Mon Jan 18 19:27:57 1999  Ben Pfaff  <blp@gnu.org>
-
-       MATCH FILES should set numeric values not available to the
-       system-missing value, not to 0.  Thanks to Dr. Dirk Melcher
-       <BZN-mdksh@t-online.de> for reporting this bug.
-
-       * get.c: (mtf_processing) Set unused records to system-missing,
-       not 0.
-
-Mon Jan 18 15:06:46 1999  Ben Pfaff  <blp@gnu.org>
-
-       KEEP didn't work properly on the SAVE procedure.  Fixed.  Thanks
-       to Ralf Geschke <ralf@kuerbis.org> for reporting this bug.
-
-       * temporary.c: (save_dictionary) Initialize var_by_name AVL tree
-       in newly created dictionary, and add each copied variable to the
-       tree.
-Mon Jan 18 15:04:48 1999  Ben Pfaff  <blp@gnu.org>
-
-       Memory leak fix.
-       
-       * get.c: (trim_dictionary) Free variable list for KEEP after
-       finishing with it.
-
-Mon Jan 18 12:57:36 1999  Ben Pfaff  <blp@gnu.org>
-
-       Some systems didn't like the way open_file was coded.  Thanks to
-       Hankin <hankin@rogue.consultco.com> for pointing this out.
-
-       * filename.c: (open_file) Don't try to store stdin, stdout,
-       stderr as part of an array, because that doesn't always work.
-
-Mon Jan 18 12:53:27 1999  Ben Pfaff  <blp@gnu.org>
-
-       The SAVE procedure didn't save long string variables properly.
-       Fixed by this patch.  Thanks to Hankin
-       <hankin@rogue.consultco.com> for this patch.
-       
-       * sfm-write.c: (write_variable) Fix off-by-one error in writing
-       out variable pad records.
-
-Tue Jan  5 14:29:27 1999  Ben Pfaff  <blp@gnu.org>
-
-       Previously, if PRINT SPACE were given a negative argument, it
-       would report an error, then spin in an (almost) infinite loop.
-       This fixes that behavior.
-
-       * print.c: (print_space_trns_proc) After reporting a negative
-       argument, set number of lines to print to 1.
-
-Tue Jan  5 13:59:55 1999  Ben Pfaff  <blp@gnu.org>
-
-       SPSS 8.0 outputs some new record types in its system files, and it
-       allows longer value labels.  Accept these system files.
-
-       * sfm-read.c: (sfm_read_dictionary) Ignore record type 7 subtype
-       11 emitted by SPSS 8.0.
-       
-Tue Jan  5 13:55:50 1999  Ben Pfaff  <blp@gnu.org>
-
-       The LIST procedure was too conservative in allocating space for
-       buffers, which caused a bug that only showed up with very long
-       output variables.  Thanks to Hankin <hankin@dunno.com> for this
-       bug report.
-
-       * list.q: (determine_layout) Allocate 1022 bytes instead of 256.
-
-Tue Jan  5 13:34:34 1999  Ben Pfaff  <blp@gnu.org>
-
-       Typo meant string format specifiers weren't checked properly.  I
-       think that Hankin <hankin@dunno.com> sent me this report, but I'm
-       willing to be corrected on this point.
-       * format.c: (check_string_specifier) Fix obvious typo.  
-
-Tue Jan  5 12:50:42 1999  Ben Pfaff  <blp@gnu.org>
-
-       Using $CASENUM in an expression didn't work.  Here's a fix.
-       Thanks to Dirk Melcher <BZN-mdksh@t-online.de> for reporting this
-       bug.
-        
-       * expr-evl.c: (evaluate_expression) Add OP_CASENUM case.
-
-       * expr-opt.c: (dump_node) OP_CASENUM is acceptable.
-
-Tue Jan  5 12:47:48 1999  Ben Pfaff  <blp@gnu.org>
-
-       The changes in 0.2.1 to fix DATA LIST FREE parsing broke some
-       other behavior, *sigh*.  This patch hopefully fixes that.  This
-       time I've actually tested it.
-
-       Thanks to Hankin <hankin@dunno.com> for reporting this bug.
-
-       * data-list.c: (read_from_data_list_free,
-       read_from_data_list_list) Call parse_string_as_format() directly
-       without mucking around with the field width.
-
-Tue Jan  5 12:31:19 1999  Ben Pfaff  <blp@gnu.org>
-
-       Occasionally, you may encounter a script that wants to be
-       interpreted in interactive mode.  Make -i emulate this behavior to
-       allow such scripts to be executed with PSPP.
-
-       Thanks to Hankin <hankin@dunno.com> for reporting this behavior.
-
-       * cmdline.c: (pre_syntax_message[]) Update -i description.
-
-       * lexer.c: (preprocess_line) When getl_interactive is 2 (i.e.,
-       when -i is given on the command line) don't treat unindented lines
-       as starting a new command.
-
-Tue Jan  5 12:30:10 1999  Ben Pfaff  <blp@gnu.org>
-
-       In conjunction with egcs 1.1.1, Checker emits some bogus warnings,
-       mostly caused by local initialized aggregates.  After egcs is
-       fixed upstream these can be removed, but for now they're not a big
-       deal.
-       
-       * ascii.c: (ascii_postopen_driver) Checker chokes on local
-       initialized arrays.  Avoid this.
-
-       * sfm-write.c: (sfm_write_dictionary) Don't use a local
-       initialized struct.
-
-Tue Jan  5 12:07:24 1999  Ben Pfaff  <blp@gnu.org>
-
-       egcs 1.1.1 has some new warnings relative to gcc 2.8.1, which the
-       following changes avoid.  Currently I compile sources with egcs
-       1.1.1 and gcc 2.7.2.3 before sending them out.
-
-       * apply-dict.c: (apply_dict) Use new avl_traverser_init() macro.
-       
-       * ascii.c: (option_tab[]) Initialize all struct members.
-
-       * avl.h: (avl_traverser_init) New macro.
-       
-       * command.c: (DEFCMD, UNIMPL macros, cmd_table[]) Initialize all
-       struct members.
-
-       * crosstabs.q: (enum_var_values) Use new hsh_iterator_init()
-       macro.
-
-       * hash.c: Comment fix.
-
-       * hash.h: (hsh_iterator_init) New macro.
-
-       * html.c: (option_tab[]) Initialize all struct members.
-
-       * pfm-write.c: (write_value_labels) Use new avl_traverser_init()
-       macro.
-
-       * postscript.c: (option_tab[]) Initialize all struct members.
-       (output_encodings, preclose, dump_lines) Use new
-       hsh_iterator_init() macro.
-
-       * sfm-write.c: (write_value_labels) Use new avl_traverser_init()
-       macro.
-
-       * sysfile-info.c: (describe_variable) Use new avl_traverser_init()
-       macro.
-
-Thu Nov 19 12:32:45 1998  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: Examined each of the parsing functions to make sure
-       that they wouldn't dump core if they were passed a string of the
-       wrong length, since now the DATA LIST FREE/LIST routines don't
-       check for field width before passing it to the data parser.
-       (parse_RBHEX, parse_AHEX) Reject odd length input.
-       (parse_string_as_format) Reject input that's too short or too
-       long.
-
-       * data-list.c: Before, the DATA LIST FREE/LIST routines would pad
-       a field to its entire declared output width then pass it to the
-       data-in parsing routines.  This contradicted the documented
-       behavior.  This is fixed in these changes.  Thanks to Mark H. Wood
-       <mwood@IUPUI.Edu>.  In addition, this fixes a few more details of
-       free-format parsing that differed from SPSS.
-       (cut_field) Commas and spaces are treated identically.  Returns
-       the proper column instead of a fixed 1 value.
-       (parse_field) Removed.
-       (read_from_data_list_free, read_from_data_list_list) Call
-       parse_string_as_format directly instead of parse_field.
-
-       * heap.c: (heap_delete) Stylistic fixes.
-
-Sun Aug  9 11:12:13 1998  Ben Pfaff  <blp@gnu.org>
-
-       * loop.c: (loop_2_trns_proc) Formatting fix.
-
-       * sel-if.c: (cmd_filter) Set FILTER_before_TEMPORARY.
-
-       * var.h: (glob var FILTER_before_TEMPORARY) New global var.
-
-       * vfm.c: (macro FILTERED) New.
-       (static var filter_var) New.
-       (process_active_file_write_case) Use FILTERED.
-       (setup_filter) Set filter_var.
-       (close_active_file) Delete the filter if not
-       FILTER_before_TEMPORARY.
-       (procedure_write_case) Use FILTERED.
-
-Sat Aug  8 00:20:14 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: Changed /PIVOT={ON,OFF} to /FORMAT={PIVOT,NOPIVOT}.
-
-       * data-in.c: (parse_day_count) Message fix.
-       (parse_month) Style fix.
-
-       * data-list.c: (struct data_list_pgm) New member eof.
-       (cmd_data_list) Init eof to 0.
-       (do_reading) Implement the /END subcommand and read-past-eof
-       checking.
-
-       * do-if.c: Include stdio.h when debugging.
-       (cmd_else_if) Make sure the command is .-terminated.
-
-       * glob.c: (init_glob) Capitalize the command prompt.
-
-       * inpt-pgm.c: (end_case_trns_proc) Debugging message.
-       (end_file_trns_proc) Debugging message.
-
-       * loop.c: (internal_cmd_loop) Make it work when there's no loop
-       index!
-       (loop_2_trns_proc) Enable MXLOOPS (why was this disabled?)
-
-       * main.c: (dump_token) Make kwtab[] const.
-
-       * set.q: Spelling, comment fixes.
-
-       * sysfile-info.c: (cmd_display) DISPLAY VECTORS not DISPLAY
-       VECTOR.
-
-       * vars-prs.c: (fill_all_vars) Style fix.
-
-       * vfm.c: (index_to_varname) Return const.
-
-Tue Aug  4 23:49:23 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Changes in many source files for partial -ansi -pedantic and
-       no-debugging compliance: Remove trailing common in enum
-       declarations; add `unused' attributes; insert some appropriate
-       casts.
-
-       * cmdline.c: (parse_command_line) Add new --testing-mode flag.
-
-       * command.c: (shell) Make static.
-       (run_command) Make static.
-
-       * data-list.c: (dump_fixed_table) Remove use of local_strdup().
-
-       * dfm.c: (cmd_begin_data) I18n fix.
-
-       * error.c: (verbose_msg) Define if __STRICT_ANSI__.
-
-       * error.h: (macro verbose_msg) Define if __STRICT_ANSI__.
-
-       * expr-opt.c: (evaluate_tree) Don't initialize local arrays if
-       __STRICT_ANSI__.
-
-       * file-handle.q: Don't prepend the source file directory name to
-       the data file name.  (Ongoing issue.)
-       (prepend_current_directory) Comment out.
-       (internal_cmd_file_handle) Don't call prepend_current_directory().
-       (fh_get_handle_by_filename) Ditto.
-
-       * filename.c: Append zero byte to readlink() return value.
-
-       * getline.c: (getl_read_line) I18n fix.
-
-       * lexer.h: Don't use gcc features if __STRICT_ANSI__.
-
-       * misc.h: Don't use gcc features if __STRICT_ANSI__.
-
-       * pfm-write.c: (bufwrite) Don't try to increment a void * pointer
-       directly.
-
-       * postscript.c: (output_encodings) Don't use local_strdup().
-       (postopen) Ditto.
-
-       * print.c: Don't use gcc features if __STRICT_ANSI__.
-
-       * q2c.c: (dump_vars) Don't put a , at the end of the last enum.
-
-       * recode.c: (parse_src_spec) Fully brace nested if's.
-
-       * set.q: (global var set_testing_mode) New var.
-
-Wed Jul 29 22:01:44 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: Add some more `unused' attributes that only come into
-       play when NDEBUG is defined.
-       (ascii_close_page) Set s_len when reallocating s.
-       
-       * crosstabs.q: (delete_missing) New function.
-       (output_pivot_table) Call delete_missing() if /MISSING=REPORT.
-       (make_summary_table) Create summary table reallocable.
-
-       * postscript.c: Add more `unused' attributes as above.
-
-       * tab.c: (tab_create) [GLOBAL_DEBUGGING] Set reallocable member.
-       (tab_realloc) [GLOBAL_DEBUGGING] Assert that table is reallocable.
-        
-       * tab.h: (struct tab_table) [GLOBAL_DEBUGGING] New `reallocable'
-       member.
-
-       * var.h: (macro force_dup_variable) [!GLOBAL_DEBUGGING] Remove
-       gratuitous space between parameter definition.
-
-       * vars-atr.c: Changed some assert(0)'s to abort()'s to prevent
-       complaints about running off the end of functions with NDEBUG
-       enabled.
-
-Sun Jul  5 00:17:25 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Several source files: Removed some PORTME notes when reflection
-       revealed that ANSI forbids that sort of breakage.  Also, added
-       lots of `unused' qualifiers here and there.
-
-       * aggregate.c: (accumulate_aggregate_info) Remove local var
-       weighting that turned out not to be used.
-
-       * avl.c: Update to version 1.1.0.  Add unused specifier.
-       (avl_destroy) Initialize ab to 0.  Comment fixes.  Cast return
-       value to void *.
-       (avl_probe) Replace some instances of 1 with +1 where appropriate.
-       (avl_find) Cast return value to void *.
-       (avl_delete) q doesn't need to be initialized at the beginning of
-       the function.  Replace some instances of 1 with +1.
-       (force_avl_delete) Renamed avl_force_delete, all references changed.
-       (compare_ints) `param' marked unused.
-       (print_int) `param' marked unused.
-       (recurse_tree) Replace some instances of 1 with +1.
-
-       * avl.h: Update to version 1.1.0.  Only declares avl function
-       types if not already declared.
-       (AVL_MAX_HEIGHT) Only define if not already defined.
-       (struct avl_node) New unused member char pad[2].
-       [GLOBAL_DEBUGGING] Change conditionalization to NDEBUG instead.
-       (force_avl_insert) Renamed avl_force_insert.
-       (force_avl_delete) Renamed avl_force_delete.
-
-       * crosstabs.q: (struct table_entry) Put `freq' into a union with
-       new member `data'.
-       (struct crosstab) Add new member `ofs'.
-       (glob var int_tab) Removed.
-       (custom_tables) In integer mode, assign v[i] properly through the
-       indirect var_dict.
-       (custom_variables) Now p.crs.max == max + 1.
-       [DEBUGGING] (debug_print) p.crs.min and p.crs.max are now ints.
-       (precalc) Implement integer mode.
-       (calc_integer) Implement integer mode.
-       (compare_table_entry) Remove unused local variable `comparing'.
-       (make_summary_table) Implement integer mode.
-       (macro ns_rows) Implemented as static variable now.
-       (several variables) Made static, from global.
-       (output_pivot_table) Use table_value_missing() for column heads.
-       Remove several unused local variables.  Implement integer mode
-       table summing.  Count up ns_rows.
-       (crosstabs_dim) Make columns wider when /MISSING=REPORT requested.
-       (find_pivot_extent) Moved into find_pivot_extent_general; now just
-       calls that function or find_pivot_extent_integer.
-       (find_pivot_extent_integer) New function.
-       (enum_var_values) Implemented for integer mode.
-       (table_value_missing) New function.
-       (display_dimensions) Call table_value_missing() for heads.
-       (float_M_suffix) New function.
-       (display_crosstabulation) Call table_value_missing() for row
-       heads.  Handle missing values in /MISSING=REPORT mode.
-       (calc_fisher) Remove unused var N.
-       (calc_r) Remove unused var fact.
-
-       * data-list.c: (dump_fixed_table) Fix table dimensioning.
-       (read_one_set_of_repetitions) Remove unused vars var_spec, column.
-
-       * data-out.c: (insert_commas) Remove unused var cp.
-       (convert_CCx) Remove unused vars save_set_decimal,
-       save_set_grouping.
-
-       * descript.q: (dump_z_table) Fix table dimensioning.
-       (pre_calc) Remove unused var j.
-       (display) Remove unused vars title, s.  Fix table dimensioning.
-
-       * expr-evl.c: Comment fixes.
-
-       * frequencies.q: (full_dim) New function.
-       (dump_full) Fix table dimensioning.
-       (condensed_dim) New function.
-       (dump_condensed) Fix table dimensioning.
-
-       * get.c: (cmd_match_files) Remove unused var n_val.  Remove unused
-       label winnage.
-
-       * html.c: (html_close_drive) Remove unused var i.
-       (postopen) Remove unused vars title, curfn_len, cp.
-       (preclose) Remove unused vars this, x.
-
-       * lexer.c: Comment fixes.
-
-       * matrix-data.c: (cmd_matrix_data) Remove unused var index.
-
-       * means.q: (custom_tables) Remove unused var m_dim.
-
-       * mis-val.c: Format fix.
-
-       * modify-vars.c: (cmd_modify_vars) Remove unused var new_dict.
-
-       * output.c: (outp_get_paper_size) Remove unused var cp.
-
-       * pfm-read.c: (read_float) Remove unused var save, unused label
-       underflow.
-       (read_variables) Remove unused vars cp, j.
-       (read_value_label) Remove unused var j.
-
-       * pfm-write.c: (bufwrite) Remove unused var i.
-
-       * postscript.c: (ps_postopen_drive) Remove unused vars dev_info,
-       fn.
-       (output_encodings) Remove unused vars char_cp, n_output.
-       (read_ps_encodings) Remove unused var ep.
-       (postopen) Remove unused var title.
-       (preclose) Remove unused var fp.
-       (ps_open_page) Remove unused vars true, false, orientation,
-       mirror_horz, mirror_vert, width, length.
-       (ps_text_metrics) Remove unused var x.
-
-       * q2c.c: (find_symbol) Remove unused var y.
-       (parse_setting) Remove unused parameter sbc, all references
-       changed.
-       (dump_parser) Remove unused var cp.
-       (dump_free) Remove unused var i.
-
-       * set.q: (static vars args, n) Removed.
-       (internal_cmd_gset) Removed.
-
-       * sfm-read.c: (sfm_read_dictionary) Removed unused var i.
-       (read_machine_flt64_info) Removed unused var file_endian.
-       (read_documents) Removed unused var i.
-       (read_compressed_data) Removed unused parameter dict, all
-       references changed.
-
-       * sfm-write.c: (bufwrite) Removed unused var i.
-       (sfm_write_case) Removed unused var i.
-
-       * sort.c: (merge_once) Remove unused var t.
-       (write_separate) #if 0 out as dead code.
-
-       * split-file.c: (cmd_split_file) Remove unused var i.
-
-       * sysfile-info.c: (sysfile_info_dim) New function.
-       (cmd_sysfile_info) Fix table dimensioning.
-       (variables_dim) New function.
-       (display_variables) Fix table dimensioning.
-       (describe_variable) Remove unused var prev_r.
-
-       * t-test.q: (z_postcalc) Removed.
-       (pairs_calc) Remove unused var bad_weight.
-       (postcalc) Remove unused vars dfn, dfd.
-
-       * tab.c: (tab_create) Set t->dim to NULL.
-       (tab_dim) Make sure t->dim is NULL first.
-       (tab_natural_width) Remove parameter `clamp'.
-       (tab_value) Remove duplicate assertion for table.
-       (tab_raw) New function.
-       (nowrap_dim) New function.
-       (wrap_dim) New function.
-       (tab_output_text) Fix table dimensioning.
-
-       * tab.h: (tab_raw) New macro.
-
-       * val-labs.c: (get_label) Remove unused var type.
-       (copy_value_labels) Remove unused var trav.
-
-       * var.h: (struct crosstab_proc) Completely changed.
-
-       * vars-prs.c: (parse_dict_variable) Remove unused var v.
-
-       * vfm.c: (open_active_file) Remove unused vars i, lp.
-
-       * weight.c: (weight_trns_proc) #if 0 out as dead code.
-       
-Tue Jun  2 23:37:21 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add apply-dict.c, flip.c.
-
-       * apply-dict.c: New file.
-       
-       * command.c: (struct command) Make cmd[] larger for CLEAR
-       TRANSFORMATIONS command name.
-       (parse_cmd) Make sure we're in a valid state before using it as an
-       index.  Discard variables and reset state on invalid transitions.
-       (cmd_clear_transformations) New function.
-
-       * command.def: Add APPLY DICTIONARY, CLEAR TRANSFORMATIONS, FLIP.
-       Add unimplemented PRESERVE, RESTORE.
-
-       * file-handle.h: Include stddef.h.
-
-       * flip.c: New file.
-       
-       * pfm-read.c: (parse_value) Pad value label values with spaces,
-       not nulls.
-
-       * sfm-read.c: (struct sfm_fhuser_ext) Add reference count.
-       (sfm_close) Decrement reference count, make sure it's zero.
-       (sfm_maybe_close) New function.
-       (sfm_read_dictionary) Handle reference counts.
-
-       * vars-atr.c: (clear_default_dict) New function.
-       (discard_variables) Use clear_default_dict().
-
-Sun May 31 00:58:05 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add pfm-write.c.
-       (LDADD) Add the libgmp2 libraries.
-
-       * command.def: Define EXPORT.
-
-       * get.c: (cmd_export) New function.
-       (export_write_case_func) New function.
-
-       * pfm-read.c: (static spss2ascii[]) Make it const.
-
-       * pfm-write.c: New file.
-
-       * sfm-write.c: Formatting, comment fixes.
-
-       * var.h: Comment fix.
-
-Fri May 29 21:44:12 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add pfm.h, pfm-read.c.
-
-       * command.def: IMPORT is now implemented.
-
-       * format.c: (glob var translate_fmt[]) New var.
-
-       * get.c: (enum GTSV_NONE) Renamed GTSV_OPT_NONE.
-       (cmd_import) New function.
-       (import_source_read) New function.
-       (glob var import_source) New var.
-
-       * pfm-read.c: New file.
-
-       * pfm.h: New file.
-       
-       * sfm-read.c: (parse_format_spec) Local variable translate_fmt[]
-       moved in format.c.
-       (dump_dictionary) Disabled printing a couple of items.
-
-Mon May 25 12:42:37 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (postcalc) Call make_summary_table().
-       (make_summary_table) New function.
-       (insert_summary) New function.
-       (display_dimensions) Remove some unnecessary arguments, all
-       references changed.
-       (output_pivot_table) Fix lots of problems with the risk table
-       setup.
-       (submit) Don't display an empty table.
-       (display_risk) Fix order of arguments to calc_risk().
-
-       * glob.c: Always include assert.h and stdlib.h.
-
-       * output.h: (enum OUTP_T_JUST_FULL) Removed, all references
-       removed.
-
-       * tab.c: (tab_create) Cosmetic changes.
-
-       * tab.h: (enum TAB_JUSTIFY) Removed, all references removed.
-
-Sun May 24 22:39:23 1998  Ben Pfaff  <blp@gnu.org>
-
-       * tab.def: Removed.
-
-       * crosstabs.q: (output_pivot_table) Headers drawing and submission
-       code simplified, moved into new function submit().
-       (submit) New function.
-       (crosstabs_dim) New function.
-       (display_directional) Substitute variable names for %s where
-       appropriate.
-       (somers_d_v[], somers_d_ase[], somers_d_t[]) New static vars.
-       (calc_symmetric) Initialize parameters only if non-NULL.
-       Calculate Somers' d.
-       (calc_directional) Calculate Somers' d (or copy it, really).
-       Calculate eta.
-
-       * output.c: (outp_string_width) New function.
-
-       * postscript.c: (postopen) Calculate font widths based on the
-       width of the zero '0' character, not the width of the space
-       character.  Set paper-width and paper-length based on points, not
-       device units.
-       (ps_open_page) Fix page setup string for landscape mode.
-
-       * som.h: (struct som_dimension) Removed.
-       (struct som_table_class) height, width members take int * not
-       som_dimesion * now.
-
-       * tab.c: Many functions now have added parameter validation.
-       (tab_height, tab_width) These functions were removed and merged
-       into a single function tab_resize(), and all references changed.
-       (tab_dim) Rewritten since the interface changed; reduced from
-       hundreds of lines to two.  All callers were changed.  Currently
-       most of them just use tab_natural_dimensions as their callback and
-       await detailed translation of functionality.
-       (tab_natural_width) New function.
-       (tab_natural_height) New function.
-       (tab_natural_dimensions) New function.  This is a callback
-       function, not something that you'd want to call directly.
-       (tab_nat_dim) Removed.
-       (tabi_table) Allocates t->w and t->h.
-       (tabi_driver) Inlined sum_columns()'s functionality.  Calls the
-       dimensions callback.
-       (evaluate_dimensions) Removed.
-       (sum_columns) Removed.
-
-       * tab.h: (enum TAL_1THIN) Removed.
-       (enum series t_*) Removed.
-       (struct tab_table) Members trh, trv changed to unsigned char *
-       from int *.  Member dim changed to a function pointer from a
-       unsigned char *.  Member max_stack_height removed.  New members
-       hr_tot, vr_tot.
-       (macros tab_l, tab_r, tab_t, tab_b) New.
-
-Sat May 23 23:22:13 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (delineate) Assign last_space_nchars before skipping
-       spaces, to fix right justification.
-
-       * crosstabs.q: (static vars risk, direct) New vars.
-       (static var pearson_r) Removed.
-       (glob var chisq_fisher) Made static.
-       (static vars row_tot[], col_tot[]) Don't include grand total
-       anymore.
-       (static var grand_total) Renamed W, all references changed.
-       (output_pivot_table) Only make `table' if num_cells != 0.  Make
-       risk and directional tables.  Deal with grand total no longer part
-       of col_tot[].  Free rows and cols after we're done with them.
-       (display_risk) New function.
-       (display_directional) New function.
-       (clac_r) Rewritten so that it stores all its results into its
-       arguments, so it can be used for Spearman's correlation too.
-       (calc_symmetric) Added a t[] argument, all references changed.
-       Calculates ASEs for tau-b, tau-c, gamma.  Calculates Spearman's r,
-       Pearson's r, Cohen's kappa.
-       (calc_risk) New function.
-       (calc_directional) New function.
-
-       * som.c: (som_submit) Improved debugging code.
-
-       * stats.c: (hypercube) New function.
-       (cube) New function.
-       (sqr) New function.
-       (normal_sig) Went back to old implementation, which actually
-       worked.
-
-       * stats.h: (macros square, cube, hypercube) Removed.  The
-       equivalent functions in stats.c are inlined here; all references
-       to square changed to sqr.
-
-Fri May 22 00:03:41 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (N_SYMMETRIC) New define.
-       (postcalc) Disable debug printing.
-       (static vars chisq_fisher, pearson_r) New.
-       (output_pivot_table) Add support for symmetric measures.  Add
-       chi-square output of exact sigs.
-       (display_chisq) Rewritten.
-       (display_symmetric) New function.
-       (gamma_int) New function.
-       (Pr) New function.
-       (swap) New function.
-       (calc_fisher) New function.
-       (calc_chisq) Check boundary conditions better. Calculate Yates,
-       Fisher, Mantel-Haenszel tests.
-       (calc_r) New function.
-       (calc_symmetric) New function.
-
-       * stats.c: (normal_sig) Rewritten with new algorithm.  Renamed
-       from calc_normal.
-       (chisq_sig) Better boundary conditions.  Renamed from
-       calc_significance.
-
-       * tab.h: (struct tab_table) New member cf.
-
-       * tab.c: (tab_create) Set cf.
-       (tab_width) New function.
-       (tab_realloc) Handle cf.
-       (tab_vline) Handle cf.
-       (tab_hline) Handle cf.
-       (tab_box) Handle cf.
-       (tab_value) Handle cf.
-       (tab_float) Handle cf.
-       (tab_text) Handle cf.
-       (tab_joint_text) Handle cf.
-       (tab_offset) Handle cf.
-       (tab_next_row) Handle cf.
-       (evaluate_dimensions) Handle cf.
-       (render_strip) Handle cf.
-
-Wed May 20 00:03:59 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (postcalc) New vars row_tot, col_tot, pass them to
-       output_pivot_table().
-       (output_pivot_table) Moved lots of local variables outside and
-       made them static.  Add beginnings of chi-square statistic
-       support.  Now column and row totals aren't in the main matrix.
-       Always zero out any leftover rows & columns after we're done with
-       the table entries.  Move all output stuff into
-       display_dimensions(), display_crosstabs(), display_chisq().
-       (display_dimensions) New function.
-       (display_crosstabulation) New function.
-       (display_chisq) New function.
-       (calc_chisq) Implemented Pearson and likelihood-ratio chisquares.
-
-       * frequencies.q: (dump_full, dump_condensed) Remove tab_null()
-       references, simplify logic.
-
-       * postscript.c: Remove scale, translate-x, translate-y,
-       mirror-horz, mirror-vert, rotate-180 options.
-       (struct ps_driver_ext) Remove scale, translate_x, translate_y.
-       All references deleted.
-       (macro YT) New macro.
-       (array option_tab[]) Removed options.
-       (ps_option) Removed options.
-       (ps_open_page) Write page setup explicitly to output file, without
-       using now-deleted BP function.
-       (macro dump_line) Use YT().
-       (macro dump_thick_line) Use YT().
-       (draw_headers) Use YT().
-       (switch_font) Reorder arguments to SF function.
-       (write_text) Use YT().
-
-       * sfm-read.c: (sfm_read_case) Don't attempt to read variables that
-       have get.fv == -1.
-
-       * sysfile-info.c: (describe_variables) Don't use tab_nulls().
-
-       * tab.c: (tab_create) Initialize t->ct to zeros.  Remove
-       null-debugging code.
-       (tab_realloc) Remove null-debugging code.  Initialize new regions
-       of t->ct to zeros.
-       (tab_vline) Support offsets.
-       (tab_hline) Support offsets.
-       (tab_box) Support offsets.
-       (tab_null) Removed.
-       (tab_nulls) Removed.
-       (tab_row) Removed.
-       (tab_col) Removed.
-       (evaluate_dimensions) Remove null-debugging code.  Understand
-       TAB_EMPTY attribute.  Assert that text.s.s is always non-NULL if
-       TAB_EMPTY not present.
-
-       * tab.h: New cell attribute TAB_EMPTY.
-       (macros tab_nr, tab_nc, tab_row, tab_col) New.
-
-       * vars-atr.c: (init_variable) Set get.fv to -1 so that GET doesn't
-       try to read them from system files.
-
-       * vfm.c: (dump_splits) Don't call tab_null().   
-
-Sat May 16 19:36:55 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (struct crosstab) Added `missing' member.
-       (custom_tables) Init missing.
-       (calc_general) Handle missing values.
-       (calc_chisq) New function.
-       (output_pivot_table) Start work on chi-square output.  Update for
-       new tab offset support functions.  Shorten statistic names.
-
-       * Several files: add in more `const's to placate gcc's warnings.
-
-       * tab.h: (struct tab_table) Add col_ofs, row_ofs members.  Comment
-       fixes.
-
-       * tab.c: (tab_height, tab_realloc, tab_vline, tab_hline, tab_box,
-       tab_null, tab_nulls, tab_value, tab_float, tab_text,
-       tab_joint_text) Add col_ofs and row_ofs support.
-       (tab_offset) New function.
-       (tab_next_row) New function.
-       (tab_row) New function.
-       (tab_col) New function.
-       (tabi_table) Add col_ofs and row_ofs support.
-
-       * vars-atr.c: (is_system_missing) New function.
-
-Tue May 12 16:14:30 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: Expanded subcommand names RESID --> RESIDUAL, etc.
-       (static var no_cells) Removed.
-       (static var num_cells) New.
-       (static var expected) New.
-       (static var cells[]) New.
-       (internal_cmd_crosstabs) Deal with new variables.
-       (postcalc) Removed most of the meat and put it in new function
-       output_pivot_table().
-       (output_pivot_table) Calculates and outputs an entire pivot table.
-
-       * postscript.c: (postopen) Fix problems with free()ing addresses
-       not obtained from malloc().
-
-       * som.c: (som_submit) Add assertion.
-
-       * sysfile-info.c: (describe_variable) Use new tab_nulls()
-       function.
-
-       * tab.c: (static var tab_names[]) New.
-       (tab_realloc) -1 for nc or nr indicates no change.
-       (tab_nulls) New function.
-       (tab_dim) Use tab_names[].
-       (tabi_cumulate) Don't include bottom or right headers.  Furrfu.
-       (evaluate_dimensions) Don't terminate on uninited cells, just put
-       an X in them and emit a notice.  Use tab_names[].
-
-       * tab.h: Move bits into tab.def.
-
-       * tab.def: New.  Don't try to declare tab_table_class because then
-       som.h has to be included.       
-       
-Thu May  7 22:55:04 1998  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: New file, contains all the command definitions
-       previously included bodily in command.c.
-
-       * format.def: New file, contains all of the format definitions
-       previously split across format.h, format.c, and sfm-write.c.
-
-       * lexer.h: Renamed from tokens.h in order to match corresponding
-       .c file name.
-
-       * lexerP.h: Moved some rarely used functions exported by lexer.c
-       into here.
-
-       * Makefile.am: Commemorate renamed files.
-       (EXTRA_DIST) Add command.def, format.def.
-
-       * command.c: [0] (walk_cmdtable_func) Removed.
-
-       * crosstabs.q: (postcalc) Made it work and print out matrices
-       proving it.
-       (enum_column_values) Renamed enum_var_values, generalized for any
-       variable.
-
-       * format.h: (struct fmt_desc) New member `spss'.
-
-       * q2c.c: (main) Generated code includes lexer.h instead of
-       tokens.h.
-
-       * sfm-write.c: (write_format_spec) Use new spss member of fmt_spec
-       instead of an independent translation table.
-
-Tue May  5 13:19:03 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Lots of source files: Added const to declarations.
-
-       * aggregate.c: (parse_aggregate_function) Rename inner i to j.
-       
-       * arena.c: (arena_clear) Set prev pointer to null when done.
-
-       * ascii.c: (ascii_option) Rename index as indx.
-
-       * avl.c: This is now a separate library called libavl.
-       (xmalloc) Make static.
-       (avl_probe) Step A7 can use the cache instead of an explicit
-       compare.
-       (avl_delete) Don't maintain a q pointer because it's always
-       available in the pointer stack.  Comment fix.
-
-       * avl.h: This is now a separate library called libavl.
-
-       * command.c: (cmd_table[]) Remove spurious trailing "".
-
-       * common.h: Only include random() fix if this system needs it.
-
-       * crosstabs.q: Include alloca headers.
-       (n_sorted_tab) New global var.
-       (postcalc) Mostly rewritten.
-       (find_pivot_extent) Rewritten.
-       (enum_column_values) Rewritten.
-
-       * data-out.c: (convert_F) Rename inner n as n_spaces.
-
-       * error.c: (dump_message) Don't have an outer var i.
-
-       * file-handle.q: (static var f) Removed.  All references removed.
-       (internal_cmd_file_handle) Uses a local variable instead of f.
-
-       * get.c: (trim_dictionary) Change scope of i, i1, i2.
-       (cmd_match_files) Don't strcpy tokstr into sbc (why was this ever
-       done?)
-
-       * getline.h: Declare getl_history as extern.  Reported by
-       palme@uni-wuppertal.de (Hubert Palme).
-
-       * postscript.c: (postopen) Some large mods for constness.
-
-       * recode.c: Remove spurious copyrights since PSPP is owned by FSF
-       anyway.
-
-Fri Apr 24 12:52:47 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Rename BUILT_SOURCES to q_sources, all references
-       changed.  Add avl.c, avl.h to pspp_SOURCES.  Remove avllib from
-       LDADD.
-
-       * avl.c, avl.h: New files.  These form a clean-room
-       reimplementation of avllib.  Iterative algorithms are used in
-       place of recursive ones, so there is no resemblance in the code.
-
-       * Lots of headers: Don't include other headers by default.
-
-       * Lots of source files: Explicitly include all needed headers.
-
-       * arena.c: (arena_clear) New function.
-
-       * crosstabs.q: (ROW_VAR, COL_VAR) New enums.
-       (static var ar) Removed.
-       (staitc vars ar_tc, ar_col) New.
-       (cmd_crosstabs) Destroy the arenas.
-       (internal_cmd_crosstabs) Create the arenas.
-       (precalc) Don't need a free function for the hash.
-       (calc_general) Make sure to zero out the trailer on the key data
-       before inserting.
-       (print_table_entries) Updated.
-       (postcalc) Worked on actually implementing.
-       (find_pivot_extent) New function.
-       (compare_value) New function.
-       (enum_column_values) New function.
-
-       * data-in.c: (parse_month) Make local array `static const'.
-       
-       * data-out.c: (convert_date) Make local array `static const'.
-       (convert_WKDAY) Same.
-       (convert_MONTH) Same.
-
-       * frequencies.q: (postprocess_freq_tab) avl_walk_inorder() has
-       been renamed to avl_walk().
-       
-       * hash.c: Rewritten more efficiently.
-
-       * hash.h: Add attribute const to hsh_next_prime declaration.
-
-       * lexer.c: (id_match) Make arguments const.
-
-       * postscript.c: (ps_postopen_driver) Make default fonts the
-       Helvetica family.
-
-       * q2c.c: (main) Generated code needs stdlib.h.
-
-       * sfm-write.c: (write_value_labels) An avl_traverser needs to be
-       initialized to 0 now, not to NULL.  All other references to
-       avl_traverser were updated in the same way.
-
-       * tokens.h: Macro version of id_match updated to use const
-       properly.
-
-       * val-labs.c: (inc_ref_count) New function.
-       (copy_value_labels) Simply through use of new avl_copy() function.
-
-Wed Apr 15 13:01:58 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: Probably doesn't compile.  New PIVOT subcommand.
-       (postcalc) Worked on this.
-
-       * postscript.c: (OPO_DOUBLE_LINE) New enum.
-       (struct ps_driver_ext) New line_width_thick member.
-       (ps_preopen_drive) Init line_width_thick.
-       (option_tab[]) Add line-* options.
-       (ps_option) Parse line-* options.
-       (postopen) Add line_width_thick support.  Strip leading spaces on
-       prologue output lines.
-       (ps_open_page) Include line_width_thick in output.
-       (macro dump_thick_line) New.
-       (dump_fancy_line) Support thick lines as well as double lines.
-
-Tue Apr 14 00:50:08 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add crosstabs.c to BUILT_SOURCES.  Add crosstabs.q
-       to pspp_SOURCES.  Add crosstabs.q to EXTRA_DIST.
-
-       * Many source files: Rename `options' to `pv_opts' as appropriate.
-
-       * command.c: (static var cmd_table[]) Add CROSSTABS command.
-
-       * common.c: (xcalloc) New function.
-
-       * crosstabs.q: New file.  Not finished yet, though.
-               
-       * data-list.c: Comment fix.
-
-       * error.c: Remove some old Checker cruft.
-
-       * frequencies.q: (dump_full) Cumulate valid percent instead of
-       regular percent.
-
-       * getline.c: Comment fix.
-
-       * hash.c: Comment fixes.
-
-       * hash.h: (struct hsh_table) Make hash functions return unsigned
-       instead of int to avoid problems with taking the modulo of
-       negative return values.  All references changed.
-
-       * misc.c: (intlog10) Make its table static const instead of auto.
-
-       * sfm-read.c: (read_header) Make `prefix' static const instead of
-       auto.
-
-       * var.h: (union value) Add member `hash'.
-       (struct variable) Rename prv_index as `foo'--all references
-       changed.  Reorder.
-       (typedef pv_opts) Removed.  All references changed.
-
-       * vars-prs.c: (parse_variables) Message fixes.
-       
-Mon Mar  9 15:35:08 1998  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_match_files) Don't reverse the order of FILEs as
-       they are being inserted.  Don't check for BY variables of
-       different types.  Discard variables if the active file isn't
-       included in the merge.
-       (mtf_processing) Essentially rewritten.
-       (mtf_merge_dictionary) Check for master/slave variables of
-       different types/widths.
-
-       * vfm.c: (static var not_canceled) New var.
-       (process_active_file) Don't call vfm_source->read() if
-       there's no vfm-source.  Initialize not_canceled.
-       (process_active_file_write_case) Honor and update not_canceled.
-       (prepare_for_writing) Rollback changes from yesterday, they were
-       wrong.
-       (close_active_file) Don't destroy vfm_source unless it exists.
-       
-Mon Mar  9 00:56:16 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Lots of source files: Added { } around nested if/else constructs
-       to avoid new gcc 2.8 warnings.
-
-       * data-in.c: (parse_Z) Declare `int' type explicitly.
-       (convert_Z) Ditto.
-
-       * get.c: (struct mtf_file) Add prev, next_min, by, input members.
-       (cmd_match_files) Initialize mtf_by_values.  Manage by, input,
-       prev members.  Put TABLEs at the end of the chain and FILEs at the
-       beginning.  Don't allow the active file in STATE_INIT.  Use proper
-       `seen' value for the active file.  Fill out the by members and
-       make sure they're of consistent type.  Do the actual merge
-       operation.
-       (mtf_processing_finish) New function.
-       (var_type_description) New function.
-       (mtf_free_file) New function.
-       (mtf_free) Rewritten.
-       (mtf_delete_file_in_place) New function.
-       (mtf_read_nonactive_records) New function.
-       (mtf_compare_BY_values) New function.
-       (static var mtf_seq_no) New var.
-       (mtf_processing) New function.
-       (mtf_merge_dictionary) Assign nval members for the system file
-       dictionary.  Assign fv values for its variables.  Point each slave
-       variable to the corresponding master variable.
-
-       * hash.c: Include str.h.
-
-       * mis-val.c: (copy_missing_values) src arg is const.
-
-       * misc.c: (spacing) Make `max' var explicitly int.
-
-       * sfm-read.c: (dump_dictionary) Message reformatting.
-       (sfm_read_case) Add assertion.
-
-       * sort.c: Esthetic fixes.
-
-       * var.h: (struct match_files_proc) New struct.
-       (struct variable) Add private data match_files_proc.
-
-       * vars-atr.c: (delete_variable) Implement.  Add argument for the
-       dictionary that owning the variable.
-       (dup_variable) Add assertion.
-
-       * vfm.c: Comment fixes, hopefully the comments are correct now.
-       (process_active_file) New function.
-       (process_active_file_write_case) New function.
-       (process_active_file_output_case) New function.
-       (prepare_for_writing) Use temp_dict->nval for vfm_info, not
-       default_dict.nval.
-       (write_case) Renamed procedure_write_case().  Now write_case is a
-       pointer to a function.  Style fixes.
-       
-1998-03-05  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (q2c) Link with libmisc.
-       (version.c) Define default_config_path, include_path,
-       groff_font_path.
-
-       * ascii.c: (ascii_postopen_driver) When the default newline string
-       is requested, open file in text mode.  Suggested by
-       palme@uni-wuppertal.de (Hubert Palme).
-       (static vars line_buf, line_p) Change from char * to unsigned char
-       *.
-       (ascii_close_page) char * to unsigned char *.
-
-       * cmdline.c: (parse_command_line) Implement -r option by
-       prepending ~/.pspp/rc to the list of files to process.
-
-       * command.c: (cmd_remark) Reset getl_prompt to the standard prompt
-       before pulling in a final line.
-       (null_func, null_int_func) Removed (dead code).
-
-       * descript.q: (display) Calculate width of variable name column
-       properly.  Calculate number of valid cases properly.  Reported by
-       palme@uni-wuppertal.de (Hubert Palme).
-
-       * filename.c: (init_filename) Use default_config_path instead of
-       now obsolete CONFIG_PATH.
-
-       * getline.c: (getl_initialize) Use include_path instead of now
-       obsolete INCLUDE_PATH.
-       (getl_add_file) New argument `where'.  All references changed.
-
-       * groff.c: (find_font_file) Use groff_font_path instead of now
-       obsolete GROFF_FONT_PATH.
-       
-       * postscript.c: (find_ps_file) Use groff_font_path instead of now
-       obsolete GROFF_FONT_PATH.  Copy through temporary variable to
-       avoid problems with constness.
-
-       * str.h: (macro cs_streq) New macro.
-
-       * version.h: (glob var default_config_path, include_path,
-       groff_font_path) New vars.
-       
-1998-02-23  Ben Pfaff  <blp@gnu.org>
-
-       * Many source files: Change verbose_msg() priority levels and
-       messages.
-
-       * aggregate.c: Include debug-print.h.
-
-       * cmdline.c: (parse_command_line) Add --safer/-s and --command/-c
-       options.
-       (static var pre_syntax_message) Document --safer/-s and
-       --command/-c.
-
-       * command.c: (cmd_erase, cmd_host) Disable if set_safer is set.
-
-       * dfm.c: (open_inline_file) [__CHECKER__] Zero out ext->file,
-       because it's not used but it's still copied.
-       (open_file_r) Remove gratuitous debug message.
-
-       * filename.c: (safety_violation) New function.
-       (open_file) Remove gratuitous debug messages.  Don't allow pipe
-       files if set_safer is set.
-
-       * get.c: Turn off debugging.
-
-       * getline.c: (getl_add_virtual_file) New function.
-       (getl_read_line) Add verbose_msg() call for opening new syntax
-       file.
-       (getl_perform_delayed_reset) Add a return value describing whether
-       any action was taken.  Call reset_eof().
-
-       * getline.h: Comment fix.
-
-       * groff-font.c: (groff_read_font) Use `goto next_iteration' in
-       place of incorrect `continue'.  Use strtok_r() instead of
-       strtok().  Always check strtok_r() return value.
-       (groff_read_DESC) Use strtok_r() instead of strtok().
-
-       * lexer.c: (reset_eof) New function.
-
-       * main.c: (parse) Get a token after performing a delayed reset
-       action; allow empty syntax files.
-
-       * postscript.c: (output_encodings) Use strtok_r() instead of
-       strtok().
-
-       * q2c.c: (dump_parser) Use strtok_r() instead of strtok().
-
-       * set.q: Comment fixes.
-       (glob var set_safer) New var.
-       (internal_cmd_set) Support SAFER.
-
-       * str.h: [!HAVE_STRTOK_R] Declare strtok_r() prototype.
-
-       * temporary.c: (free_dictionary) Set d->splits to NULL after
-       freeing.
-
-       * vars-atr.c: (clear_variable) Decrement dict->n_splits if
-       variable deleted, not if it *isn't* deleted.
-
-1998-02-16  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (array cmd_table[]) Add MATCH FILES.
-
-       * common.c: Comment fixes.
-
-       * data-list.c, dfm.c, error.c, filename.c, list.q, matrix-data.c,
-       modify-vars.c, postscript.c, sfm-read.c, sfm-write.c, tab.c:
-       Include alloca.h.  Problem reported by palme@uni-wuppertal.de
-       (Hubert Palme).
-
-       * expr-opt.c: Include str.h.  Problem reported by
-       palme@uni-wuppertal.de (Hubert Palme).
-
-       * get.c: (cmd_get) [DEBUGGING] Update v->p.get to v->get.
-       (static var mtf_by) Change from char ** to variable **.
-       (static var mtf_master) New var.
-       (mtf_merge_dictionary) New function.
-       (cmd_match_files) Init mtf_master.  Parse mtf_by according to new
-       var type.  Reorder tests properly.  Initialize file->dict.  Detect
-       TABLE= without BY=.  Read file dictionaries and merge them.  Give
-       subcommand name with IN, LAST, FIRST error messages.  Create IN,
-       LAST, FIRST variables.  Comment fixes.
-       (mtf_free) Don't free default_dict.  Free mtf_master.
-
-       * getline.c: Define getl_mode.  Change getl_buf_size to size_t
-       from int.
-       (handle_line_buffer) Cast int to size_t in comparison to avoid
-       warning.
-
-       * getline.h: Declare getl_mode extern.
-
-       * groff-font.c: (groff_read_font) Type-fix calls to getline.
-       (groff_read_DESC) Make line_size a size_t.
-       (match_tok) Parenthesize name to avoid macro expansion.
-
-       * mis-val.c: (copy_missing_values) New function.
-
-       * postscript.c: (postopen) Make buf_size a size_t.
-
-       * sfm-read.c: (dump_dictionary) Make global from static.  Print
-       variable info in parts for easier debugging with Checker.
-
-       * temporary.c: (copy_variable) Use copy_value_labels().
-       (new_dictionary) New arg: whether to copy file label, documents.
-
-       * val-labs.c: (copy_value_labels) New function.
-
-       * var.h: (enums MISSING_*) Add MISSING_COUNT.
-
-       * vars-atr.c: [GLOBAL_DEBUGGING] (force_dup_variable) New
-       function.
-       (dup_variable) Set prv_index, get.fv, get.nv.
-
-Fri Feb 13 15:38:36 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pspp_SOURCE) Add htmlP.h.
-
-       * Many source files: For ANSI-compliance, add empty statement
-       after label.  Reported by palme@uni-wuppertal.de (Hubert Palme)
-       and Micah Altman <maltman@www-vdc.fas.harvard.edu>.
-
-       * data-in.c: (parse_numeric) Some header files break on
-       -DBL_MIN_10_EXP because they get a --; add () for safety.
-       Reported by palme@uni-wuppertal.de (Hubert Palme).
-
-       * dfm.c: Idea by Dr Eberhard W Lisse <el@linux.lisse.na>.
-       (struct dfm_fhuser_ext) Change `file' from FILE * to file_ext.
-       (dfm_close) Use close_file_ext.
-       (open_inline_file) Set file.file to NULL, not file.
-       (open_file_r, open_file_w) Initialize file.file; fill in file_ext
-       struct and use open_file_ext().
-       (read_record) Use file.file.
-
-       * file-handle.q: (prepend_current_directory) Pass through special
-       filenames.
-
-       * filename.c: Only include unistd.h if HAVE_UNISTD_H.
-       (normalize_filename) Pass through special filenames.
-       (open_file, close_file) Accept pipe| and |pipe syntaxes as
-       equivalent.
-       (dirname) Rename blp_dirname() because of name conflict on some
-       OS.  All references changed.  Reported by palme@uni-wuppertal.de
-       (Hubert Palme).
-       (is_special_filename) New function.
-
-       * get.c: (GTSV_OPT*) Add GTSV_OPT_MATCH_FILES.
-       (trim_dictionary) Conditionalize some of the options on whether
-       GTSV_OPT_MATCH_FILES is in *options.
-       (rename_variables) Don't allow variables to be renamed as scratch
-       variables.
-       (MTF_*) New enum series.
-       (struct mtf_file) New struct.
-       (static vars mtf_head, mtf_tail, mtf_by, mtf_n_by, mtf_free) New
-       vars.
-       (cmd_match_files, mtf_free) New functions.
-
-       * lexer.c: (match_int) Needed parentheses around name to escape
-       macro expansion.  Reported by Micah Altman
-       <maltman@www-vdc.fas.harvard.edu>.
-
-       * print.c: Needed to include alloca.h.  Reported by Micah Altman
-       <maltman@www-vdc.fas.harvard.edu>.
-
-       * recode.c: (convert_to_double) Parenthesize -DBL_MIN_10_EXP to
-       -(DBL_MIN_10_EXP).  Reported by palme@uni-wuppertal.de (Hubert
-       Palme).
-       
-       * str.h: Include stdarg.h.  Reported by palme@uni-wuppertal.de
-       (Hubert Palme) and Micah Altman <maltman@www-vdc.fas.harvard.edu>.
-
-Thu Feb  5 00:18:21 1998  Ben Pfaff  <blp@gnu.org>
-
-       * html.c: (struct html_driver_ext) Move into htmlP.h.
-       (html_preopen_driver) Initialize cp_x, cp_y.
-       (html_submit) Implement as call to output_tab_table().
-       (change_attributes) New function.
-       (escape_string) New function.
-       (output_tab_table) New function.
-
-       * list.q: (write_all_headers) Add code for writing headers for the
-       html driver.
-       (clean_up) Write out the html close-table tag.
-       (determine_layout) Ignore html driver.
-       (list_cases) Write html data.
-
-       * som.c: (som_submit) Move more of the code into output_table().
-
-       * tab.c: (static var hit) Make a global var and rename tab_hit.
-       (static var tab_table_class) Make a global var.
-
-       * htmlP.h: New file.
-
-Tue Feb  3 16:12:18 1998  Ben Pfaff  <blp@gnu.org>
-
-       * dump-sysfile.c: Removed.
-
-       * html.c: (preclose) Change comment in emitted code.
-
-       * matrix-data.c: Debugging off by default.  Comment fixes.
-       (static var container) New var.
-       (cmd_matrix_data) Create and destroy container.  Initialize
-       is_per_factor[] to 0s.  Move code into new function
-       string_to_content_type().  Require split values to be present in
-       the data when ROWTYPE_ is explicit.  Call specific function, not
-       general read_matrices().
-       (string_to_content_type) New function.
-       (context) Exclude all whitespace, not just spaces.
-       (mget_token) A dot is a number.  Add assertion.
-       (static var data) Renamed nr_data.
-       (static var factor_values) Renamed nr_factor_values.
-       (read_matrices) Renamed read_matrices_without_rowtype().  Handle
-       only specific case.  Close data_file before exit.
-       (fill_matrix) New function.
-       (read_data_lines) Renamed nr_read_data_lines().  Remove debug
-       printing.  Style fixes.  Message fixes.  Move code into
-       fill_matrix().
-       (read_matrices_without_rowtype) Rename
-       matrix_data_read_without_rowtype().  Fix off-by-one error on
-       loops.  Allocate nr_data[] memory from arena.
-       (read_matrices_with_rowtype) Removed.
-       (read_splits) Renamed nr_read_splits().  Style fixes.
-       (read_factors) Renamed nr_read_factors().
-       (dump_cell_content) Comment fixes.  Arguments changed.  Change
-       debug printing.  All references changed.
-       (output_data) Renamed nr_output_data().
-       (static var wr_content) New var.
-       (struct factor_data) New struct.
-       (static var wr_data) New var.
-       (static var wr_current) New var.
-       (matrix_data_source_destroy_source) Removed.
-       (read_matrices_with_rowtype) New function.
-       (matrix_data_read_with_rowtype) New function.
-       (wr_read_splits) New function.
-       (compare_factors) New function.
-       (wr_output_data) New function.
-       (wr_read_rowtype) New function.
-       (wr_read_factors) New function.
-       (wr_read_indeps) New function.
-       (glob var matrix_data_source) Make destroy_source member NULL as
-       well.
-
-Fri Jan 23 00:09:08 1998  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (syntax_error) Give better error message when at end of
-       file.
-
-       * matrix-data.c: (var content_names[]) Fix PROX spelling.  Change
-       N_SCALAR to output as plain N.
-       (mdump_token) Change output format.
-       (context) Fix message output interaction with spaces in input.
-       (another_token) New function.
-       (force_eol) Improved error message.
-       (static var max_cell_index) New var.
-       (read_matrices) Init `cells'.  factor_values is now per-cell.
-       Init max_cell_index.
-       (read_data_lines) Replace `compare' local with new `compare' arg.
-       Debugging messages changed.  Only read factors if per_factor.
-       Propagate error return from read_factors(), force_eol().
-       Copy N_SCALAR values across the N vector.
-       (read_matrices_without_rowtype) Don't init `cells'.  Don't need to
-       check parentheses manually since we now have is_per_factor[].
-       Call read_data_lines() with new args.  Check for end of data after
-       looping, using another_token().
-       (read_factors) Arguments changed.  Use max_cell_index to determine
-       whether to read or compare factors.  Message fixes.
-       (dump_cell_content) New function.
-       (output_data) Completely rewritten because content types were
-       supported to be nested inside factor values, not vice versa.
-       
-Thu Jan 22 00:26:38 1998  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (syntax_error) Support formatted varargs messages.
-
-       * matrix-data.c: Turn debugging on by default.
-       (static content_type[]) New array.
-       (static content_names[]) New array.
-       (static rowtype_, varname_) New vars.
-       (static is_per_factor[]) New array.
-       (static split_values) Moved declaration.
-       (static n_continuous, first_continuous) New var.
-       (cmd_matrix_data) Don't init split_values.  Assign ROWTYPE_ to
-       rowtype_.  Simplify SPLIT code.  Init is_per_factor[].  Assign
-       VARNAME_ to varname_.  Initialize first_continuous, n_continuous.
-       Check for continuous variables.
-       [DEBUGGING] (debug_print) Remove content_names[].
-       (mdump_token) New macro.
-       (mget_token_dump) New function.
-       (mdump_token) New function.
-       (context) New function.
-       (mget_token) Fix messages.
-       (static var data, split_values, factor_values) New vars.
-       (read_matrices) Manage split_values, factor_values.
-       (read_data_lines) New function.
-       (read_matrices_without_rowtype) Implemented.
-       (read_splits) Message fixes.  Uses `just_read'.
-       (read_factors) New function.
-       (output_data) New function.
-       (matrix_data_source_destroy_source) Close the file handle.
-       (glob var matrix_source) Change name from "DATA LIST" to "MATRIX
-       DATA".
-
-       * str.c: (strpadcmp) Removed.
-
-       * vfm.c: (dump_splits) Initialize i; fix test for end of splits.
-
-Sun Jan 18 00:30:59 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Lots of source files: Add cast to unsigned character to calls to
-       tolower() and toupper().
-
-       * aggregate.c: Set default_dict.splits to NULL.
-
-       * command.c: (static variable tab[]) Add MATRIX DATA.
-
-       * data-in.c: Add debugging defines.  Formatting fixes.
-
-       * expr-opt.c: Formatting fixes.
-
-       * lexer.c: (syntax_error) Message fixes.
-
-       * matrix-data.c: New enum series.
-       (static vars fmt, section, diag, explicit_rowtype, signle_split,
-       split_values, n_factors, factors, cells, pop_n, contents,
-       n_contents) New vars.
-       (cmd_matrix_data) Finished implementation.
-       (compare_variables_by_mxd_vartype) New function.
-       [DEBUGGING] (debug_print) New function.
-       (static vars mtoken, mtokstr, mtoklen, mtokval) New vars.
-       (read_matrices) New function.
-       (read_matrices_without_rowtype) New function.
-       (read_matrices_with_rowtype) New function.
-       (read_splits) New function.
-       (mget_token) New function.
-       (force_eol) New function.
-       [0] (test_tokenizer) New function.
-       (matrix_data_source_destroy_source) New function.
-       (glob var matrix_data_source) New var.
-
-       * misc.h: Include ieeefp.h if present.
-
-       * split-file.h: (cmd_split_file) Changes corresponding to struct
-       dictionary changes.
-
-       * str.h: Fix memmem prototype.
-
-       * temporary.c: (save_dictionary, restore_dictionary,
-       free_dictionary) Changes corresponding to struct dictionary
-       changes.
-
-       * var.h: (MXD_* enums) New enum series.
-       (struct matrix_data_proc) New struct.
-       (struct split) Removed.
-       (struct dictionary) Changed `splits' member from `split *' to
-       `variable **'.
-       (macro force_create_variable) New macro.  Replaced lots of
-       create_variable()/assert() calls with calls to this macro.
-
-       * vars-atr.c: (discard_variables) Changed assertion.
-       [GLOBAL_DEBUGGING] (force_create_variable) New function
-       called by the macro of the same name.
-       (clear_variable) Changes to delete splits from the dictionary
-       corresponding to struct dictionary changes.
-
-       * vars-prs.c: (parse_variables) [GLOBAL_DEBUGGING] Check for
-       corrupted variable `index' values in the dictionary passed in
-       every time this function is called.
-
-       * vfm.c: (dump_splits, SPLIT_FILE_procfunc) Changes corresponding
-       to struct dictionary changes.
-
-Tue Jan 13 23:45:02 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pspp_SOURCES) Add matrix-data.c.
-
-       * command.c: New includes.
-       (static array cmd_table[]) Add ERASE, HOST, NEW FILE.
-       (cmd_erase) New function.
-       [unix] (shell) New function.
-       (run_command) New function.
-       (cmd_host) New function.
-       (cmd_new_file) New function.
-
-       * expr-prs.c: (parse_primary) Message fix.
-
-       * inpt-pgm.c: Formatting fix.
-       (cmd_reread) Implement the FILE subcommand.
-
-       * matrix-data.c: New file.
-
-       * q2c.c: (dump_header) Change output commenting style.
-
-       * weight.c: Comment fix.
-
-Tue Jan 13 00:53:39 1998  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (buf64_10x) Renamed buf64_1xx, all references
-       changed.
-       (buf_10x) Renamed buf_1xx, all references changed.
-       (cmd_aggregate) Implemented cases 010, 011, 110, and 111 (all
-       cases now implemented).
-       (create_sysfile) New function.
-       (agr_11x_func) New function.
-
-       * data-in.c: (parse_numeric) Work properly if there's an
-       explicitly coded decimal point in the data and decimal places are
-       specified on DATA LIST.  Bug reported by Dr Eberhard W Lisse
-       <el@linux.lisse.na>.
-
-       * get.c: (cmd_get, cmd_save_internal) Allow extraneous slash
-       before file specification on GET, SAVE, XSAVE.  Bug reported by Dr
-       Eberhard W Lisse <el@linux.lisse.na>.
-
-       * q2c.c: [!HAVE_STRERROR] Include misc/strerror.c, not
-       strerror.c.  Bug reported by Alexandre Oliva
-       <oliva@dcc.unicamp.br>.
-
-       * sort.c: Include sort.h.  Comment fixes.  A few esthetic fixes.
-       (static var separate_case_tab) New var.
-       (cmd_sort_cases) Cancel temporary transformations here.  Free
-       v_sort before return.
-       (sort_cases) Run an EXECUTE procedure if SEPARATE is nonzero and
-       we're reading from a sort stream.  Don't cancel temporary
-       transformations.  Offload internal sorting to do_internal_sort().
-       (do_internal_sort) New function.  Handles internal sorting even
-       when SEPARATE is nonzero.  Doesn't free v_sort.
-       (do_external_sort) Take new arg SEPARATE.  Only destroy `x' if
-       it's non-NULL.
-       (write_initial_runs) Take new arg SEPARATE.  Only destroy the old
-       sink if SEPARATE is zero.
-       (read_output_cases) Renamed read_sort_output(), all references
-       changed.  Now uses separate_case_tab when it exists.
-       (write_separate) New function.
-
-       * vfm.c: (page_to_disk) Destroy memory_source_cases, not
-       memory_sink_cases.  Don't redundantly call
-       vfm_source->destroy_source().
-       (memory_stream_mode) After switching over, set memory_sink_cases
-       to NULL.
-
-Sat Jan 10 23:35:51 1998  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: (struct agr_var) Expand dbl[] array from 2 to 3
-       elements.
-       (static var prev_case) New, moved out of aggregate_single_case()
-       local scope.
-       (static var buf64_10x, buf_10x) New.
-       (cmd_aggregate) Initialize prev_case.  Comment fixes.  Implement
-       the 000, 001, 100, and 101 cases.  Free prev_case.
-       (parse_aggregate_functions) Disallow scratch variables.
-       (free_aggregate_functions) Only free agr_dict if non-null.  Use
-       iter->function to determine numeric/string type, not
-       iter->src->type.
-       (aggregate_single_case) Don't manage prev_case.  Initialize
-       aggregate info after dumping it.
-       (accumulate_aggregate_info) Fix sum, weighted sum, mean, weighted
-       mean, stddev, weighted stddev definitions.
-       (dump_aggregate_info) Implemented.
-       (initialize_aggregate_info) Renamed from
-       initialize_aggregate_functions().  Initializes dbl[2].
-       (agr_00x_trns_proc, agr_00x_end_func, write_case_to_sfm,
-       agr_10x_trns_proc, agr_10x_trns_free, agr_10x_end_func) New.
-
-       * cases.c: (alloc_val) Removed.
-
-       * get.c: (cmd_save_internal) Initialize new `dict' member.
-
-       * sfm-write.c: (sfm_write_dictionary, write_header,
-       write_variable, write_value_labels, write_documents) Reorganize,
-       simplify for new parameter structure.
-       (write_variable) Only one variable * argument now.
-
-       * sfm.h: (struct sfm_write_info) Removed `pri', `sec', and
-       replaced by new `dict' member.
-
-       * temporary.c: (new_dictionary) Initialize n_documents.
-
-       * vars-atr.c: (dup_variable) Allocate `value's from dict into
-       v->fv manually.
-       (init_variable, replace_variable) Eliminate usage of alloc_val().
-
-       * vars-prs.c: (parse_DATA_LIST_vars) Accept PV_NO_SCRATCH option.
-
-       * vfm.c: (arrange_compaction) Allow `temporary' value of 2 to
-       signal that AGGREGATE is to be used for forming final cases.
-       (close_active_file) Call end_func before stopping lagging.  Cancel
-       temporary after finishing compaction.
-       (write_case) Comment fixes.  Cleaned up.
-       (compact_case) Let AGGREGATE handle compaction when `temporary' is
-       2.
-
-Sat Jan 10 02:10:47 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (BUILT_SOURCES) Add means.c.
-       (pspp_SOURCES) Add means.c.
-       (EXTRA_DIST) Add means.q.
-
-       * command.c: (array cmd_table[]) Add MEANS.
-
-       * common.h: Esthetic fixes.  Comment fixes.  Test for
-       MAX_SHORT_STRING greater than 8.
-       (macros LOWEST, HIGHEST) New.
-
-       * data-in.c, data-list.c, recode.c: Comment fixes.
-
-       * means.q: New file, base version.
-
-       * mis-val.c: (parse_num_or_range, parse_numeric) Replace -DBL_MAX
-       with LOWEST, DBL_MAX with HIGHEST.
-
-       * q2c.c: (dump_vars) Add an enum to array types giving the number
-       of values for the enum.
-
-       * sfm-read.c: (sfm_read_dictionary, read_machine_flt64_info)
-       Replace second_lowest_value with second_lowest_flt64.
-
-       * sfm-write.c: (write_variable, write_rec_7_34) Replace
-       second_lowest_value with second_lowest_flt64.
-
-       * t-test.q: Comment fix.
-
-       * temporary.c: (restore_dictionary) Esthetic fix.
-
-       * tokens.h: (force_match_id, force_match, force_string, force_int,
-       force_num, force_id) Replace msg() with syntax_error().
-
-       * var.h: (struct means_proc) New.
-       (struct variable) Add mns member to `p' union.
-
-       * vars-prs.c: (parse_variable, parse_dict_variable,
-       parse_variables, parse_DATA_LIST_vars) Replace msg() with
-       syntax_error().
-
-Thu Jan  8 22:28:41 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pspp_SOURCES) Add tab.h.
-
-       * Most source files: Added a cast to unsigned char in usages of
-       the ctype is*() functions.  Replaced `end of command expected'
-       calls to msg() with calls to syntax_error().
-
-       * frequencies.q: (dump_condensed) Fix tab_dim() column reference.
-
-       * lexer.c: (hex_val) Removed (was dead code).
-       (idmatch) Parenthesize function name to avoid macro expansion.
-
-       * postscript.c: Comment fixes.
-       (ps_preopen_driver) Change default font size to 10pt.
-
-       * sfm-read.c: (read_variables) Byteswap sv.print, sv.write as
-       int32s.
-       (parse_format_spec) Change system-file format spec argument type
-       to int32.  Parse the format spec with bitwise operators.
-
-       * sfmP.h: (struct sysfile_format) Removed.
-       (struct sysfile_variable) Changed print, write members from
-       sysfile_format to int32.
-
-       * tokens.h: Esthetic fixes.
-       [__GNUC__] (macro id_match) New macro to hopefully speed up
-       identifier matching.
-       (macros match_id, match_tok, match_int) Implemented in
-       compiler-independent manner; no longer GNU C only.
-
-       * vfm.h: Include time.h.
-
-Mon Jan  5 11:06:15 1998  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c: (dump_fixed_table) Change tab_dim().
-
-       * dump-sysfile.c: (open_sysfile) Fix mmap() call.
-
-       * error.c: Include command.h.
-
-       * frequencies.g: Formatting fixes.
-
-       * frequencies.q: Add tab_dim() calls.  Make the total cell a
-       joined cell.
-
-       * glob.c: Include command.h.
-
-       * sfm-read.c: (struct sfm_fhuser_ext) New members sysmis, highest,
-       lowest.
-       (sfm_read_dictionary) Initialize sysmis, highest, lowest.
-       (sfm_read_machine_flt64_info) Update sysmis, highest, lowest.
-       (read_variables) Byteswap sv.type; byteswap sv.print, sv.write as
-       the other elements (is this right?).
-       (read_variables) Use lowest, highest members.
-       (parse_format_spec) New arg `vv' for more stringent checking.
-       (dump_dictionary) Byteswaps nonexplicit data.
-       (sfm_read_case) Byteswap numeric data.
-
-       * som.c: Initialize table_num to 1.
-       (render_segments) Remember to increment y_index after each table
-       segment.
-
-       * sysfile-info.c: (cmd_sysfile_info) Change tab_dim().  Don't call
-       avl_count() on a NULL tree.  No title for the second table.
-       (cmd_display) Handle DISPLAY VECTORS by calling display_vectors().
-       Handle AS_SCRATCH as AS_NAMES.  Warn if no variables.  Re-enable;
-       fix call to display_variables().
-       (display_variables) Default to 4 columns, not 3.  Set up headers.
-       Column title is Variable, not Name.  Fix index column.
-       Add joint text.  Add tab_dim().  Handle value labels properly.
-       Handle DISPLAY LABELS properly.  Draw boxes correctly.
-       (describe_variable) Value labels don't need titles.  Don't clear
-       nonexistent index column.
-       (compare_vectors_by_name) New function.
-       (display_vectors) New function.
-
-       * tab.c: (tab_height) Add assertion.
-       (tab_null) Add debug code.
-       (evaluate_dimensions) Add debug code.
-
-       * var.h: (struct variable) get_proc data is sometimes used
-       simultaneously with other per-procedure info, therefore it was
-       removed from the union.  All references changed.        
-
-Sun Jan  4 18:13:33 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_close_page) Put title on second line of headers
-       if there is no subtitle.
-
-       * command.c: (glob var cur_proc) Move definition here, from
-       common.c.
-       (cmd_remark) Emit blank line before remarks.
-
-       * command.h: (glob var cur_proc) Move declaration here, from
-       common.h.
-
-       * data-list.c: (dump_fixed_table) Fix messages.
-       (dump_free_table) Call tab_nat_dim().
-
-       * descript.q: (dump_z_table) Modify tab_dim() call.
-
-       * frequencies.q: (dump_condensed, dump_statistics) Add tab_dim()
-       call.
-       (dump_statistics) Don't output header.
-
-       * groff-font.c: Minor format fix.
-
-       * html.c: Comment fix.
-
-       * list.q: (write_varname) Indent after advancing page.
-
-       * output.h: Minor reordering.
-
-       * postscript.c: Comment fixes.  Many places, '\n' was replaced by
-       a reference to eol[].
-       (struct ps_driver_ext) New member eol[].
-       (ps_preopen_driver) Initialize eol[].
-       (ps_postopen_driver) Fix sense of text for text_opt, line_opt
-       defaults.  Handle headers.  Fix test for minimum page length.
-       (static var option_tab[]) Add `line-ends'.
-       (ps_option) Handle line-ends to change eol[].
-       (postopen) Scale prop_em_width and fixed_width properly.  Set the
-       prologue title to outp_title if applicable.  Replace the prologue
-       line ends with eol[].  Call draw_headers() if headers are enabled.
-       (text_width) New function.
-       (out_text_plain) New function.
-       (draw_headers) New function.
-
-       * print.c: (dump_table) Call tab_nat_dim().
-
-       * som.c: (som_blank_line) Only advance a line if not at the top of
-       a page.
-       (som_submit) Move several informational table calls here.
-       Increment subtable_num if SOMF_NO_TITLE not set.
-       (output_table) Advance a line if SOMF_NO_SPACING not set.
-       (render_columns, render_segments, render_simple) Handle spacing
-       between tables.  Handle table titles.  Remove debug output.
-
-       * som.h: (SOMF_*) New enum series.
-       (struct som_table_class) New member `flags'.
-
-       * sysfile-info.c: (cmd_sysfile_info) Calls tab_nat_dim().  No
-       headers or spacing.
-       (display_variables) Calls tab_nat_dim().
-       (describe_variable) Remove restriction on number of value labels.
-       Make value labels separated by thin lines.
-
-       * tab.c: (tab_create) Default `flags' to none.
-       (tab_float) New arg `w'.  All references changed.
-       (tab_nat_dim) New function.
-       (tab_output_text) No title or spacing.
-       (tab_flags) New function.
-       (tabi_flags) New function.
-       (tabi_title) New function.
-       (strip_height) Removed.
-       (tabi_render) Skip title when necessary.
-       (static var tab_tab_class) Add tabi_flags, tabi_title.
-       (evaluate_dimensions) Disable display of column, row size.
-       (sum_columns) Add title height to top header.
-       (render_strip) Moved within file.
-
-       * tab.h: (struct tab_table) New member `flags'.
-
-       * vfm.c: (dump_splits) Calls tab_nat_dim().  No title.
-
-Sat Jan  3 16:55:44 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Most source files: Add `const' attribute in all appropriate
-       places.
-       
-       * sysfile-info.c: (cmd_sysfile_info) Add tab_dim() call, add a
-       column to the variables table for use by describe_variable().
-       (cmd_display) Disable for the present.
-       (display_documents) Don't wrap documents.
-       (display_variables) Table has four columns now.
-       (describe_variable) Table has four columns now.  Don't use a
-       subtable, use joined cells instead.
-
-       * tab.c: (tab_create) Don't set `join'.
-       (tab_realloc) ct array is not made up of a_string's.
-       Reallocate trh, hrh, h arrays, initialize trh array.  Initialize
-       cell contents on GLOBAL_DEBUGGING, not DEBUGGING.
-       (text_format) New function.
-       (tab_title) Rewritten, uses text_format().
-       (tab_text) Rewritten, uses text_format().
-       (tab_joint_text) New function.
-       (tab_join) Removed.
-       (static var hit) New variable.
-       (render_strip) New args r1, r2.  Implement joined cells that fit
-       on a single page.
-       (tabi_render) Increment hit.  Pass new args to render_strip().
-       (evaluate_dimensions) [GLOBAL_DEBUGGING] Check for uninitialized
-       cells.  For t_naw and t_nah, ignore joined cells and null cells in
-       calculations.
-       
-       * tab.h: (struct tab_join_rect) Removed.
-       (struct tab_table) Removed `join'.
-       (TAB_JOIN_MAIN) Removed.
-       (struct tab_joined_cell) New struct.
-       (TAT_NOWRAP) New enum.
-
-Fri Jan  2 01:39:58 1998  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_postopen) Replace ASCII_* macros with their
-       expansions.
-       (ascii_postopen_driver) Fix initialization of *_spacing so that
-       the TAL_0 bit doesn't count.
-
-       * data-list.c: (dump_fixed_table) Use natural width for Format
-       column.
-
-       * glob.c: (rerange) Removed.
-       (get_date) Formatting fixes.  Internationalization fix.
-
-       * html.c: (html_postopen_driver) Replace HTML_DEFAULT_OUTPUT_FILE
-       with "pspp.html".
-
-       * postscript.c: (ps_postopen_driver) Replace
-       PS_DEFAULT_OUTPUT_FILE with "pspp.ps".
-
-       * som.c: (som_submit) Don't eject page before every table.
-       (output_table) Fix order of arguments on call to area().
-       (render_columns) Fix calculation of max_len.
-       
-       * tab.c: (tabi_cumulate) Minor change to increase elegance.
-       (render_strip) New function.
-       (strip_height) New function.
-       (tabi_render) Rewrite as calls to render_strip().
-
-       * tab.h: (TAT_* enums) Removed TAT_RICH, all references removed.
-       Renumbered TAT_PRINTF, TAT_TITLE, TAT_FIX to correspond better
-       with the TAB_* and OUTP_T_* constants.
-       
-Thu Jan  1 11:53:52 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Formatting fixes.
-
-       * ascii.c: (ascii_postopen_driver) Initialize *_line_spacing[],
-       *_line_width[].
-
-       * data-list.c: (dump_fixed_table) Add tab_dim() call.
-
-       * descript.q: (dump_z_table, display) Add tab_dim() calls.
-
-       * dump-sysfile.c: (glob var length) Make type off_t.
-       (usage) Fix arguments.
-       (main) Return 0.
-
-       * output.h: (OUTP_T_*) Change constants' value to match tab.h.
-       Now right-justification is the default so many references had to
-       change.
-       (struct outp_class) Removed line_width, all references changed.
-       (OUTP_DEV_*) Add OUTP_DEV_DISABLED.
-       (struct outp_driver) Add elements horiz_line_width,
-       vert_line_width, horiz_line_spacing, vert_line_spacing.  Remove
-       som element.
-
-       * postscript.c: (outp_encodings) Formatting fixes.  Fix garbage
-       collection.
-       (postopen) Initialize all the informational members of
-       outp_driver.
-
-       * som.c: (som_blank_line) New function, renamed from blank_line(),
-       all references changed.
-       (som_submit) Disables drivers whose pages can't be opened.
-       (render_columns, render_simple, render_segments) Add debug output.
-       (render_columns) Fix loop range.
-       (render_simple) Don't try to render the headers, they're taken
-       care of automatically.  Advance cp_y past the table when done.
-       (render_segments) Fix loop ranges.
-
-       * tab.c: Initialize new members of tab_table.
-       (tab_vline) Handle trv[]; don't set style for spacing-only lines.
-       (tab_hline) Handle trh[]; don't set style for spacing-only lines.
-       (tab_box) Handle trh[], trv[]; don't set style for spacing-only
-       lines.
-       (set_expr) Removed.
-       (tab_dim) New function.
-       (tab_col_width) Removed.
-       (tab_row_height) Removed.
-       (tab_output_text) Call tab_dim().
-       (tabi_driver) Call evaluate_dimensions(), sum_columns().
-       (tabi_area) Implemented.
-       (tabi_cumulate) Implemented.
-       (tabi_render) Partially implemented, but broken.
-       (var tab_table_class) Made static.
-       (evaluate_dimensions) New function.
-       (sum_columns) New function.
-
-       * tab.h: (enum t_*) Now start at t_end.  New: t_ptw, t_nr, t_nc,
-       t_nah, t_naw, t_neg, t_xch, t_dup, t_lbl, t_jnz, t_sac, t_sar,
-       t_scr, t_srr, t_sentinel.  Removed: t_nat.
-       (struct tab_table) New: wl, wr, ht, hb, trh, hrh, trv, wrv, dim,
-       max_stack_height, w, h.  Removed: ce, re.
-       (macro blank_line) Removed.
-       (glob var zero_length) Removed.
-
-Fri Dec 26 15:44:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Most source files: include some of the new include files broken
-       out of var.h.
-       
-       * Makefile.am: (pspp_SOURCES) Add all the new source files to the
-       list.
-
-       * aggregate.c: (glob var outfile) Make static.
-
-       * command.c: (glob var pgm_state) Move here.
-
-       * common.c: (glob vars endian, second_lowest_value, pgmname,
-       finished, curdate, cur_proc, start_interactive, history_file) Move
-       here.
-
-       * descript.q: (structs dsc_z_score, descriptives_trns) Move here.
-
-       * file-handle.q: (glob vars files, inline_file) Move here.
-
-       * glob.c: Lost lots of glob vars, detailed in individual file
-       entries.
-       (init_glob) set_printer, set_screen were obsolete, deleted.
-       set_cprompt has fewer spaces because pspp has fewer letters than
-       fiasco.
-
-       * inpt-pgm.c: (glob vars inp_init, inp_init_size) Move here.
-       (inp_nval) Made static.
-
-       * lexer.c: (glob vars token, tokval, tokstr, tokstr_size,
-       tokstr_len, toklongstr, tokint) Move here.
-
-       * misc.c: Lost several vars and functions.
-
-       * set.q: (all the set_* variables) Move here.
-
-       * str.c: (strmaxcpy, strbarepadcpy, strbarepadlencpy, strpadcpy,
-       blpstrset, strpadcmp, memrev, memrmem, cmp_str) Move here from
-       misc.c.
-
-       * tab.c: (set_expr, tab_col_width, tab_row_height) New functions.
-
-       * tab.h: (enum series t_*) New enums.
-       (struct tab_table) Use arena struct tag.  New members ce, re.
-
-       * tokens.h: Comment fixes.
-
-       * var.h: Move lots of enums and variables and functions and
-       structures to other files.  Use and declare a lot more union and
-       struct tags.  Comment fixes.  
-
-       * vector.c: (glob vars vec, nvec) Move here.
-
-       * vfm.c: (glob vars reinit_sysmis, reinit_blanks, init_zero,
-       init_blanks, last_vfm_invocation) Move here.
-
-       * cases.h: New file.
-       (struct long_vec) Move here.
-       (vec_init, vec_clear, vec_insert, vec_delete, devector, envector)
-       Move here.
-
-       * command.h: New file.
-       (STATE_* enums) Move here.
-       (glob var pgm_state) Move here.
-
-       * format.c: New file.
-       (glob var formats) Move here.
-       (parse_format_specifier_name, fmt_to_string,
-       check_input_specifier, check_output_specifier,
-       check_string_specifier, convert_fmt_ItoO, parse_format_specifier)
-       Move here.
-
-       * format.h: New file.  Move functions now in format.c here.
-       (FMT_* enums) Move here.
-       (struct fmt_desc) Move here.
-       (FCAT_* enums) Move here.
-       (struct fmt_spec) Move here.
-       (glob vars formats, fmt_parse_ignore_error) Move here.
-
-       * inpt-pgm.h: New file.
-       (INP_* enums) Move here, make #defines into enums.
-       (glob vars inp_init, inp_init_size) Move here.
-
-       * sort.h: New file.
-       (glob vars v_sort, nv_sort) Move here.
-       (sort_cases, read_sort_output) Move here.
-
-       * vector.h: New file.
-       (struct vector) Move here, add struct tag.
-       (glob vars vec, nvec) Move here.
-       (find_vector) Move here.
-
-       * New file.
-       (glob vars last_vfm_invocation, temp_case, reinit_sysmis,
-       reinit_blanks, init_zero, init_blanks) Move here.
-       (struct case_stream) Move here.
-       (glob vars vfm_source, vfm_sink, vfm_memory_stream,
-       vfm_disk_stream, sort_stream, data_list_source,
-       input_program_source, file_type_source, get_source, n_lag) Move
-       here.
-       (procedure, write_case, lagged_case, compact_case, page_to_disk)
-       Move here.
-               
-Wed Dec 24 22:40:42 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (pspp_SOURCES) Added html.c, som.c, som.h.
-       (LDADD) Add libdcdflib.
-
-       * ascii.c: Comment and formatting fixes.  Almost every external
-       function had an assert added, checking driver_open and page_open.
-       (ascii_init_driver) Broken into ascii_preopen_driver,
-       ascii_postopen_driver, ascii_close_driver.  Manages driver_open.
-       (ascii_open_page) Sets page_open.
-       (ascii_close_page) Clears page_open.
-
-       * html.c: Comment and formatting fixes.  Almost every external
-       function had an assert added, checking driver_open and page_open.
-       (html_init_driver) Broken into html_preopen_driver,
-       html_postopen_driver, html_close_driver.  Manages driver_open.
-       (html_open_page) Sets page_open.
-       (html_close_page) Clears page_open.
-       (html_submit) Disabled.
-
-       * lexer.c: (parse_string) Remove debugging printf.
-
-       * list.q: (determine_layout) Open a page if one is not yet open.
-
-       * output.c: Comment fixes.
-       (add_class) Set the class member of the new list element.
-       (parse_options) Don't handle device type.
-       (colon_tokenize) New function.
-       (configure_driver) New four-field format with a field for device
-       type.  Now initialize driver_open, page_open, next, and prev
-       fields.  Use new colon_tokenize() function.  Don't do a memory
-       copy to replace a driver, it doesn't work; instead delete the old
-       driver and insert a new one.
-       (destroy_driver) Don't call som_destroy_driver().  Close the page
-       if it's open.  Find the class in the list of classes and decrement
-       that reference count.  Remove the driver from the global driver
-       list.
-       (outp_iterate_enabled_drivers) Renamed outp_drivers().  All
-       references changed.  Rewritten.  Don't return a driver that's not
-       enabled.
-       (outp_eject_page) All references to som_internal_eject_page()
-       changed to use this.  Sets cp_x to 0 as well as cp_y.
-
-       * output.h: (OUTP_I_* enums) Removed.
-       (struct som_submission_form) Removed.
-       (struct outp_class) init_driver broken into preopen_driver,
-       postopen_driver, and close_driver.  submit changed to take a
-       som_table argument.
-
-       * postscript.c: Comment and formatting fixes.  Almost every
-       external function had an assert added, checking driver_open and
-       page_open.
-       (ps_init_driver) Broken into ps_preopen_driver,
-       ps_postopen_driver, ps_close_driver.  Manages driver_open.
-       (ps_open_page) Sets page_open.
-       (ps_close_page) Clears page_open.
-
-       * som.c: New file, base implementation.
-       
-       * som.h: (struct som_table) Add struct tag.
-       (enum SOM_COL_ACROSS) Removed.
-       (SOM_ROWS, SOM_COLUMNS) New enums.
-       (struct som_table_class) Add member `cumulate'.  Remove `segment';
-       change `render' arguments.
-       (struct som_point, struct som_rect) Removed.
-       (som_submit_table) Fixed typo, should have been som_submit.
-
-       * sysfile-info: (describe_variable) Don't try to insert a
-       subtable; just destroy it for now.
-
-       * t-test.q: Include dcdflib/cdflib.h instead of cdflib.h.  Fix
-       references to value labels.
-
-       * tab.c: (tab_destroy) New function.
-       (tab_columns) Change argument.
-       [0] (tab_submit) Remove dead code.
-       (tab_title) Allocate string from the table's arena.
-       (tab_output_text) Only free the buffer if we allocated it.
-       (tab_submit) New function.
-       (static vars t, d) New static vars.
-       (tabi_table, tabi_driver, tabi_count, tabi_area, tabi_columns,
-       tabi_headers, tabi_cumulate, tabi_render) New functions.
-       (glob var tab_table_class) New global var.
-
-       * tab.h: (struct tab_join_rect) Don't use a som_rect; directly
-       encapsulate the rectangle.  All references changed.
-       
-Sun Dec 21 16:18:58 1997  Ben Pfaff  <blp@gnu.org>
-
-       * All header files updated to use struct tags in addition to
-       typedefs for all structures.  Don't use word `struct' in struct
-       tags.
-       
-       * Makefile.am: (pspp_SOURCES) Remove html.c.
-       (INCLUDES) Replace the lib/* includes with a single lib/ include;
-       all references updated.
-
-       * command.c: (parse_cmd) Remove call to som_check_workspace.
-       (output_line) Update to new som.
-
-       * data-in.c: (parse_numeric) A single dot is not an error; it is
-       the system-missing value.
-
-       * data-list.c: (dump_fixed_table, dump_free_table) Update to new
-       som.
-
-       * data-out.c: Added `const' as appropriate to many prototypes.
-       (convert_E, convert_F, convert_CCx) Take double argument instead
-       of value * argument.
-       (convert_format_to_string) Call changed functions appropriately.
-       Instead of modifying the caller's value for FCAT_SHIFT_DECIMAL,
-       make a local copy of the value.
-
-       * descript.q: Remove custom_variables() prototype now provided by
-       q2c.  
-       (custom_variables) Don't increment sbc_variables, the caller does
-       this.
-       (dump_z_table, display) Update to new som.
-
-       * error.c: (vmsg) Add const to prototype.  Remove code to handle
-       `too many errors' condition.
-       (check_error_count) New function.
-       (msg) Add const to prototype.
-
-       * filename.c: (open_file) Rewrite for elegance.
-
-       * frequencies.q: Remove custom_*() prototypes now provided by q2c.
-       (dump_full, dump_condensed, dump_statistics) Update for new som.
-
-       * list.q: Don't include somP.h.  Change all references to
-       som_driver_ext to refer to the new members of som_driver.  Change
-       som_internal_eject_page() references to outp_eject_page().
-
-       * main.c: (parse) Rewrite for elegance.  Add call to
-       check_error_count().
-
-       * output.c: (add_class, outp_list_classes, outp_configure_driver)
-       Rewrite or revise for new outp_driver_class_list structure.
-       (outp_iterate_enabled_drivers) Fix comparison between disabled
-       devices and current device type.
-       (outp_eject_page) New function.
-
-       * output.h: Comment fixes.
-       (struct outp_driver) New members driver_open, page_open, cp_x,
-       cp_y, font_height, prop_em_width, fixed_width.  Deleted members
-       ref_count, next.
-       (struct outp_driver_class_list) New struct.
-       (outp_class_list) Changed to type outp_driver_class_list; all
-       references updated.
-
-       * print.c: (dump_table, print_trns_proc) Updated for new som.
-
-       * q2c.c: (dump_vars) Simplify array subcommand code.  Declare
-       prototypes for custom subcommands.
-       (dump_subcommand) Always include the `else'.
-       (dump_parser) Fix comments in output code.
-
-       * set.q: Reordered functions.
-
-       * som-frnt.c, som-high.c, som-low.c, somP.h: Removed.
-       
-       * som.h: Rewritten from scratch.
-
-       * str.h: Remove dead code.
-
-       * tab.c, tab.h: New files, base implementation.
-
-       * sysfile-info.c: (cmd_sysfile_info, describe_variable) Update to
-       new som.
-
-       * t-test.q: New code from John Williams
-       <johnr.williams@stonebow.otago.ac.nz>.  Include math.h, cdflib.h.
-       Many many new static vars and defines.
-       (precalc, postcalc, g_postcalc, z_postcalc, t_pairs, t_groups,
-       groups_calc, pairs_calc, z_dev_calc, z_calc) New functions.
-       (struct value_list) New struct.
-       (variance, covariance, pooled_variance, oneway, pearson_r, f_sig,
-       t_crt, t_sig, print_t_groups) New functions.
-       (cmd_t_test) Implemented.
-
-       * temporary.c: (cancel_temporary) Only free the temp_dict if it's
-       non-NULL.
-
-       * vfm.c: (dump_splits) Update to new som.
-
-Thu Dec  4 23:02:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (fiasco_SOURCES) Add html.c.
-
-       * aggregate.c: Base source.
-
-       * ascii.c: (postopen, preclose) Reformat.
-
-       * data-out.c, expr-evl.c: Comment fixes.
-       
-       * filename.c: (open_file) When opening a file for writing, use
-       line buffering instead of full buffering for better interactive
-       performance.  Suggested by Valerio Aimale
-       <valerio@svpop.com.dist.unige.it>.  Also, recognize special file
-       names `stdin', `stdout', `stderr'.
-
-       * groff-font.c: Comment fixes.
-
-       * html.c: New file; base version.
-
-       * list.q: (write_all_headers, clean_up, determine_layout,
-       list_cases) Ignore `special' devices for now.  Needs to be fixed
-       later.
-
-       * output.c: (outp_init) Add html driver to list; reverse list
-       order.
-
-       * output.h: (struct outp_class_struct) New members `special',
-       `submit'; comment fixes.  All references changed.
-
-       * postscript.c: (ps_init_driver) Make defaults for text_opt,
-       line_opt depend on whether the OUTP_DEV_SCREEN bit is set on the
-       device.
-       (postopen) Comment fix.
-       (preclose) Comment fixes, formatting fixes.  Change x->file.file
-       references to more proper f->file.
-
-       * som-high.c: (som_submit_table) Special classes use their own
-       renderers.
-
-       * som.h: Comment fixes.
-
-       * temporary.c: (new_dictionary) Don't try to xstrdup() a NULL
-       string.
-       
-Tue Dec  2 14:36:07 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (fiasco_SOURCES) Add aggregate.c back in.
-
-       * aggregate.c: Still working on this.
-
-       * command.c: (cmd_table[]) Add AGGREGATE back in.
-       (split_words) Make '-' a legal word separator as well as ' '.
-
-       * main.c: Comment fixes.
-
-       * q2c.c: (dump_parser) Don't require the procedure's full name to
-       be present, in the generated source.
-
-       * t-test.q: Change name to `t-test' from `t test'.  Let PAIRS be
-       multiply specified and let it be default; let MISSING, CRITERIA,
-       FORMAT be multiply specified.
-       (cmd_t_test) Parse command name.  [DEBUGGING] Call debug_print().
-       (custom_groups) Fix defaults.
-       (custom_pairs) Check whether this is a PAIRS subcommand before
-       attempting to parse.  Better garbage collection.  Proper storage
-       allocation.
-       [DEBUGGING] (debug_print) New function.
-
-       * temporary.c: Comment fixes.
-       (copy_variable) Don't copy variable name and index.
-       (save_dictionary) Copy variable name and index by hand.
-
-       * vars-atr.c: Comment fixes.
-       (create_variable) New dictionary argument.  All references
-       changed.
-       (common_init_stuff) New dictionary argument.  All references
-       changed.
-       (init_variable) New dictionary argument.  All references changed.
-       (dup_variable) New function.
-
-       * vars-prs.c: (parse_variables) If there are any errors, we always
-       return 0.  Previously, it was possible for some types of errors to
-       be ignored.
-       
-Sat Nov 22 01:20:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (fiasco_SOURCES) For 0.1.5 release, remove
-       aggregate.c.
-
-       * command.c: (cmd_table[]) Comment out AGGREGATE; add T TEST.
-
-       * list.q, t-test.q: Remove ALL option from VARLIST declaration in
-       grammar rules.
-
-       * q2c.c: Comment fixes.
-       (SBC_* enums) Remove SBC_VARLIST_ALL; all references removed.
-       
-       * t-test.q: (cmd_list) Rename cmd_t_test.
-
-       * temporary.c: (new_dictionary) Don't declare as static.
-       
-Fri Nov 21 00:03:06 1997  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: Changes, still not finished.
-
-       * file-handle.q, frequencies.q, list.q, set.q: Comment fixes.
-
-       * q2c.c: Comment fixes.  Now its output is internationalized.
-       (get_token) Fix parsing of escapes within literal strings.
-       (main) Fix bad #line directives in output.
-
-       * t-test.q: Base implementation.
-
-       * temporary.c: (new_dictionary) New function.
-       (restore_dictionary) [__CHECKER__] Change fill character to *
-       (from @).
-       
-Sun Nov 16 01:29:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (BUILT_SOURCES, fiasco_SOURCES) Add t-test.c
-
-       * aggregate.c: Changes, still not finished.
-
-       * descript.q, list.q: Comment fixes.
-
-       * q2c.c: Almost completely rewritten.
-
-       * t-test.q: New file, not complete.
-
-Fri Nov 14 00:14:48 1997  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.c: Changes, still not finished.
-
-       * sort.c: (sort_cases) Call cancel_temporary() instead of doing it
-       by hand.
-
-       * temporary.c: (cancel_temporary) New function.
-
-       * vars-atr.c: (discard_variables) Call cancel_temporary() instead
-       of doing it by hand.
-
-       * vfm.c: (close_active_file) After restoring a TEMPORARY
-       dictionary, set temp_dict to NULL.  Cancel TEMPORARY through
-       cancel_temporary().
-       (SPLIT_FILE_procfunc) Comment fix.
-
-Tue Oct 28 16:08:45 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (fiasco_SOURCES) Add aggregate.c.
-
-       * aggregate.c: New file, not finished yet.
-
-       * command.c: (cmd_table) Add AGGREGATE.
-
-       * common.h: (pgm_state) Move declaration to var.h.
-
-       * lexer.c: (bin_value_func, oct_value_func, hex_value_func) i18n
-       fixes.
-       (parse_string) Message fix.
-
-       * recode.c: Comment fix.
-
-       * sfm-read.c: (read_variables) Code esthetic fixes.
-       (write_header) Default date is `Jan', not `JAN'.
-
-       * sfmP.h: (bswap_int32) [!__linux__] Fix off-by-one errors.
-
-       * sort.c: (cmd_sort_cases) Farm the work out to new function
-       parse_sort_variables().
-       (parse_sort_variables) New function.
-       (sort_cases) New function.  Cancels temporary transformations,
-       which sorting didn't do previously.
-       (cmd_sort_cases) Better garbage collection on error.  Uses
-       do_external_sort().
-       (write_initial_runs, merge_once) Improved code esthetics.
-       (sort_stream_read) Reduced to one call to read_output_cases().
-       (read_output_cases) New function.
-
-       * var-labs.c: (cmd_variable_labels) Re-enabled truncation of
-       variable labels to 120 characters.
-
-       * var.h: Comment fixes.
-       (glob var pgm_state) From common.h.
-
-       * vars-atr.c: (discard_variables) Set pgm_state to STATE_INIT.
-
-       * vars-prs.c: (parse_DATA_LIST_vars) Support PV_SINGLE in
-       options.  Set *names to NULL on error.
-
-       * vfm.c: (memory_stream_init) Assert compaction_nval != 0.
-
-Thu Oct  9 09:59:49 1997  Ben Pfaff  <blp@gnu.org>
-
-       * sfm-write.c, vfm.c: [HAVE_UNISTD] #include <unistd.h>, needed by
-       SunOS4.  From Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-Wed Oct  8 18:55:24 1997  Ben Pfaff  <blp@gnu.org>
-
-       * vfm.c: (page_to_disk) Added missing local variables.
-
-Tue Oct  7 20:23:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Comment fix.
-
-       * sort.c: (cmd_sort_cases) Attempt to perform internal sort if the
-       source is anything other than a disk stream, not just if it's in a
-       memory stream.  Call page_to_disk() before external sort.
-       (allocate_cases) Message fix.
-
-       * vfm.c: (prepare_for_writing) Warn user when paging workspace to
-       disk.
-       (page_to_disk) New function.
-
-Sun Oct  5 15:56:14 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (INCLUDES) Include .. instead of $(top_srcdir).
-
-       * common.h: (macro strerror) Remove.  From Alexandre Oliva
-       <oliva@dcc.unicamp.br>.
-
-       * get.c: (dict_delete_run) The number of variables to delete is
-       not necessarily the number of variables that need to be shifted
-       up.
-       (trim_dictionary) Don't set *options to 0.  Fix bug that caused
-       too many variables to be deleted.
-
-       * postscript.c: Comment fix.
-
-       * q2c.c: Include strerror.c.  From Alexandre Oliva
-       <oliva@dcc.unicamp.br>.
-
-       * set.q: #undef ON and OFF.  From Alexandre Oliva
-       <oliva@dcc.unicamp.br>.
-
-       * sfm-read.c: (sfm_read_dictionary) Don't set the file class too
-       early, otherwise errors cause a bad free().
-
-       * str.h: (macro nvsprintf) s/FORMATS/FORMAT/ typo.  From Alexandre
-       Oliva <oliva@dcc.unicamp.br>.
-
-       * temporary.c: (save_dictionary) Don't allocate memory if
-       n_documents is 0.
-
-       * vfm.c: (memory_stream_write) Message fix.
-
-Sat Oct  4 16:20:43 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (static var cmd_table[]) Define REPEATING DATA
-       command.
-
-       * common.h: Added support for broken systems that are missing
-       EXIT_SUCCESS, EXIT_FAILURE, RAND_MAX, and/or strerror().
-
-       * Many source files: Replace syntax error messages via msg() with
-       call to syntax_error().
-
-       * data-list.c: (dump_fixed_table) Add support for dumping table
-       for REPEATING DATA as well as DATA LIST FIXED.
-       (cmd_repeating_data) Allows and requires `/' between subcommands.
-       Does proper thing with allowing rpd.starts_end to stay 0.  Allows
-       CONTINUED specifications to be omitted.  Forces CONTINUED to be
-       specified if ID is.  Calculates starts_end, cont_end from logical
-       record length as reported by fhp.  Calls dump_fixed_table() if
-       requested.  Fixed length of record copied by memcpy.
-       (parse_num_or_var) Sets `num' to 0, not NOT_INT, for variables.
-       Message fix.
-       (realize_value) Returns sensible value for out-of-range variable
-       values.
-       (rpd_parse_record) New argument `ofs'.  Fixed confusion between
-       length of occurrences and length of line.  Added warning for
-       fields that exceed the line length.  Fixed infinite loop.
-       (read_one_set_of_repetitions) Numerous minor changes for more
-       complete SPSS compliance.  Message fixes.
-
-       * dfm.c: (dfm_close) If the file being closed is the inline file,
-       read all the remaining data before closing it.
-       (dfm_get_record) Don't close the file on lossage, as either it
-       has been closed already or it doesn't belong to us.
-
-       * error.c: (puts_stdout) New function.
-       (vmsg) Use puts_stdout instead of puts.
-
-       * file-handle.q: (fh_record_width) New function.
-
-       * inpt-pgm.c: (init_case) Fixed buffer overrun when inp_nval % 4
-       == 0.
-       (clear_case) Ditto.
-       (input_program_source_read) Made an old kluge an approved method.
-
-       * lexer.c: (syntax_error) New function.
-
-       * misc.c: [BROKEN_RAND] (ansi_rand, ansi_srand; static var next)
-       New.
-
-       * output.c: (oupt_get_paper_size) Message fix.
-
-       * q2c.c: Numerous fixes to formatting of generated code made to
-       conform to GNU coding standards.  Uses syntax_error() in generated
-       code.  Other miscellaneous generated message fixes.  Added support
-       for broken systems that are missing EXIT_SUCCESS, EXIT_FAILURE,
-       RAND_MAX, and/or strerror().
-
-Sat Oct  4 02:09:56 1997  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: Comment fixes.
-
-       * data-list.c: (struct repeating_data_trns) New member `id_spec'.
-       (find_variable_input_spec) New function.
-       (cmd_repeating_data) Initializes id_spec.
-       (rpd_parse_record) Implemented.
-       (read_one_set_of_repetitions) Returns -3 by default in order to
-       kluge out some potential bugs.
-
-       * data-out.c: Comment fixes.
-
-       * file-type.c: (internal_cmd_record_type) Message fix.
-
-       * inpt-pgm.c: (input_program_source_read) Special temporary kluge
-       for handling -3 return value.
-
-Sat Sep 20 23:58:15 1997  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c: Comment fixes.
-       (struct dls_var_spec) Reordered members.
-       (read_from_data_list_fixed) Restructured.
-       (struct repeating_data_trns) Reordered members.  Renamed `starts'
-       as `starts_beg', `ends' as `starts_end'.
-       (cmd_repeating_data) Calculates length of repeated data if
-       necessary and possible.
-       (parse_num_or_var) Don't allow string variables.
-       (realize_value) New function.
-       (rpd_msg) New function.
-       (rpd_parse_record) New function.  Currently stubbed out.
-       (read_one_set_of_repetitions) Implemented.
-
-       * inpt-pgm.c: (input_program_source_read) Comment fix.
-
-Thu Sep 18 21:34:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (cmd_end_repeat_p) Removed.
-       (init_cmd_parser) Doesn't set cmd_end_repeat_p.
-       (parse_cmd_name) Removed.
-
-       * data-list.c: Comment fixes.
-       (data_list_pgm) Removed `eof' member.
-       (static var first) New var.
-       (cmd_data_list) Sets `first'.  Ensures that DATA LIST uses the
-       FILE TYPE file inside FILE TYPE structures.
-       (append_var_spec) Appends to *first, not dls.spec.
-       (parse_fixed) Message fixes.
-       (struct rpd_num_or_var) New.
-       (struct repeating_data_trns) New.
-       (static var rpd) New.
-       (cmd_repeating_data) New function.
-       (parse_num_or_var) New function.
-       (parse_repeating_data) New function.
-       (read_one_set_of_repetitions) New function.
-
-       * file-type.c: (cmd_file_type) Message fixes.  Always
-       default_handle to FILE TYPE file handle.
-       (internal_cmd_record_type) Message fixes.
-
-Wed Aug 20 14:22:03 1997  Ben Pfaff  <blp@gnu.org>
-
-       * repeat.c: Comment fix.  Disable debugging.
-
-       * temporary.c: (restore_dictionary) Sets splits to NULL and
-       n_splits to 0 before destroying the variables because now doing
-       this tries to remove split variables.
-
-       * vars-atr.c: (discard_variables) Asserts that n_splits is 0 after
-       destroying the dictionary.
-       (clear_variable) Removes a variable from splits after destroying
-       it.
-
-Mon Aug 18 18:06:55 1997  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: (set_compat) Removed.
-       (pick_compat) Removed.
-       (parse_command_line) Removed -c option.
-       (pre_syntax_message) Removed -c option.
-       (usage) Remove compatibility code.
-
-       * common.h: (macros VER_PC, VER_WND, VER_X) Removed.
-       (glob var compat) Removed.
-
-       * compute.c: (type_check) Fixed messages about type mismatches.
-
-       * data-list.c: (cmd_data_list) Removed compatibility code.
-       (fixed_parse_compatible) Calls convert_negative_to_dash().
-       Fixed bug where it only set the variable in fx.spec if it created
-       the variable itself.
-       (dump_fmt_list) Spelling fix.
-       (cut_field) Removed compatibility code.
-
-       * dfm.c: (cmd_begin_data) Don't require a command terminator on
-       BEGIN DATA command.
-
-       * expr-evl.c: (evaluate_expression) Implement LAG.
-
-       * expr-prs.c: (parse_add) Calls convert_negative_to_dash().
-       (parse_neg) Calls convert_negative_to_dash().
-       (LAG_func) Increases n_lag to the lag requested.  Fixed assignment
-       bug.
-
-       * expr.h: (struct expression_struct) Removed member max_lag.
-
-       * file-type.c: (parse_col_spec) Calls convert_negative_to_dash().
-       (internal_cmd_record_type) Removed special handling to produce
-       negative numbers from dash tokens.
-
-       * getline.c: (static var DO_REPEAT_level) New var.
-       (getl_add_DO_REPEAT_file) Increments DO_REPEAT_level.
-       (handle_line_buffer) Copies the line into getl_buf; doesn't call
-       copy_with_DO_REPEAT_substitutions().
-       (getl_read_line) Maintains value of getl_mode.  Calls
-       perform_DO_REPEAT_substitutions() whenever DO_REPEAT_level is
-       positive.
-       (getl_close_file) Decrements DO_REPEAT_level when appropriate.
-
-       * getline.h: (getl_mode) New glob var.
-
-       * glob.c: Comment fixes.
-       (init_glob) Restructured.  Sets set_seed.
-       (init_compat_dependent) Removed.  All references removed.
-       (get_date) Format changed from MM/DD/YY to DD MMM YYYY.
-       (__htonl, __htons) Removed.  (What were these for?)
-
-       * lexer.c: (static var tbl) Dash set to class CNUM.
-       (make_hexit) New function from data-out.c.
-       (get_token_representation) Rewritten.
-       (convert_negative_to_dash) New function.
-       (lex_init_compat_dependent) Removed.
-       (yylex) A dash is parsed as part of a number if it is followed by
-       a digit.  The ASCII representation of a number is copied to
-       tokstr.  String parsing farmed out to parse_string().  Comment
-       fixes.
-       (bin_value_func, oct_value_func, hex_value_func, parse_string) New
-       functions.
-       (preprocess_line) Line processing depends on interactive/batch
-       mode, not on compatibility mode.  Removed PC+ compatibility code.
-
-       * loop.c: (loop_3_trns_proc) Comment fix.
-
-       * main.c: Remove dead code.
-       (main) Remove call to init_compat_dependent().
-
-       * misc.c: (convert_fmt_ItoO) Make E format conversion more
-       conformant.
-
-       * print.c: (parse_string_argument) Calls
-       convert_negative_to_dash().
-       (fixed_parse_compatible) Calls convert_negative_to_dash().
-
-       * repeat.c: (RPT_* defines) Removed.
-       (struct rpt_numeric) Removed.
-       (struct repeat_entry) New member type, changed `replacement' from
-       char * to char **.
-       (clean_up) Deallocation adapted to new repeat_entry.
-       (internal_cmd_do_repeat) `type' defaults to 0.  Remove lookahead()
-       usage.  Creates vars for `type' of 1.
-       (parse_ids) Sets type of 1.  Adapted to new repeat_entry.
-       (store_numeric) Rewritten, new interface.
-       (parse_numbers) Rewritten.
-       (parse_strings) Rewritten.
-       (find_DO_REPEAT_substitution) New function.
-       (perform_DO_REPEAT_substitutions) New function.
-       (copy_with_DO_REPEAT_substitutions) Removed.
-       (debug_print) Rewritten.
-
-       * set.q: Comment fix.
-       (custom_results) Removed compatibility code.
-       (internal_cmd_set) Removed SET EMULATION subcommand.  Removed
-       compatibility code.
-
-       * sysfile-info.c: (cmd_display) Removed compatibility code.
-
-       * tokens.h: Comment fixes.
-       (token types enum) Removed `toktype' typedef name for this int
-       type.  Removed SUBST.  Restructured.
-
-       * vars-atr.c: (discard_variables) Sets n_lag to 0.
-
-       * vars-prs.c: Comment fix.
-
-       * vfm.c: Comment fixes.
-       (glob var n_lag) New var.
-       (static vars lag_count, lag_head, lag_queue) New vars.
-       (procedure) Removed argument nlag.
-       (setup_lag) New function.
-       (close_active_file) Discards lagging state.
-       (lag_case) New function.
-       (lagged_case) New function.
-       (write_case) Lags a case if lagging.
-
-       * weight.c: (cmd_weight) Removed compatibility code.
-       
-Sun Aug 17 22:34:40 1997  Ben Pfaff  <blp@gnu.org>
-
-       * getline.h: (struct getl_script) New members loop_index, macros.
-
-       * getline.c: (getl_add_file) Sets first_line field to NULL.
-       (getl_add_DO_REPEAT_file) New function.
-       (handle_line_buffer) When the current line's length is negative,
-       set the filename and line number.  Increment line number after
-       reading line.  Pass the line to
-       copy_with_DO_REPEAT_substitutions() for processing.
-       (getl_close_file) Free DO REPEAT lines before freeing the
-       filename, and just set the filename to NULL when doing this,
-       because otherwise the filename gets freed twice.
-
-       * glob.c: (glob var queuing) Removed.  All references removed.
-
-       * lexer.c: Comment fixes.
-       (get_token_representation) New function.
-
-       * repeat.c: Comment fixes.
-       (struct repeat_entry) Replaced type and v union members with a
-       simple string.
-       (append_record) New function.
-       (internal_cmd_do_repeat) Started reforming it for the new
-       repeat_entry struct.  Properly records filename changes in the
-       getl_line_buf.  Fixed improper use of = for ==.  Fixed sense of
-       strncasecmp() result usage.  Uses append_record() to simplify.
-       Properly discards END REPEAT line.  Calls getl_add_DO_REPEAT_file
-       to add in the file.
-
-       (copy_with_DO_REPEAT_substitutions) Started coding.
-
-       [DEBUGGING] (debug_print_lines) New function.
-
-       * set.q: (custom_results, internal_cmd_set) s/VER_PCP40/VER_PC/;
-
-       * tokens.h: (macro is_id1, is_idn) New macros.
-
-Sat Aug 16 10:57:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: (static var pre_syntax_message) Changed `win'
-       compatibility mode to `wnd'.
-
-       * data-list.c: (fixed_parse_spss) Renamed
-       fixed_parse_compatible().
-
-       * glob.c: (init_glob) Excise unused code for
-       program_invocation_short_name.
-
-       * lexer.c: (preprocess_line) Leading indentors are ignored in Wnd
-       as well as in X.
-
-       * print.c: (fixed_parse_spss) Renamed fixed_parse_compatible().
-
-       * set.q: `win' compatibility renamed `wnd'.
-
-Thu Aug 14 22:11:12 1997  Ben Pfaff  <blp@gnu.org>
-
-       * filename.c: [__WIN32__] Change the included Windows header files
-       (again).
-       (absolute_filename_p) [__MSDOS__] A filename with a colon as the
-       second character is absolute.
-       (dirname) Fix logic error.  Don't printf() the results.
-       (prepend_dir) Don't printf() the results.
-
-       * getline.c: (handle_line_buffer) New function.
-       (getl_read_line) Reads line with handle_line_buffer() when
-       appropriate.
-       (getl_close_file) Discard line buffer data.
-
-       * getline.h: Comment fixes.
-       (struct getl_line_list) New struct.
-       (getl_script_struct) Added line buffer members.  These are hooks
-       for use by DO REPEAT to allow it to insert virtual source code
-       into the program.
-
-       * glob.c: (init_glob) [__DJGPP__ || (__WIN32__ && __BORLANDC__)]
-       Override Borland C++ stupidity that claims Windows has a console
-       window size of 0x3.
-
-       * repeat.c: This is in the process of being restructured from
-       using a token-buffering approach to the DO REPEAT facility to
-       using the more flexible approach of a line-buffering approach in
-       conjunction with the getline module.  Comment fixes.
-       (struct tok_struct) Removed.
-       (static vars queue_index, queue_head, queue) Removed.
-       (static vars line_buf_head, line_buf_tail) New vars.
-       (internal_cmd_do_repeat) Instead of queuing tokens, queue lines.
-       Not complete.
-       (pull_queue, destroy_queue) Removed.
-       [DEBUGGING] (debug_print_tokens) Removed.
-
-Tue Aug  5 13:57:58 1997  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.q: (prepend_current_directory) New function.
-       (internal_cmd_file_handle, fh_get_handle_by_filename) Prepends
-       current directory before normalizing filename.
-
-       * filename.c: (gnu_getcwd) New function.
-       (absolute_filename_p) New function.
-       (search_path) New argument, PREPEND.  All references changed to
-       pass NULL except those explicitly mentioned.  Uses
-       absolute_filename_p().  Prepends PREPEND before trying the
-       filename.
-       (dirname, prepend_dir) New functions.
-
-       * getline.c: (getl_get_current_directory) New function.
-       (getl_include) Passes getl_get_current_directory() as PREPEND arg
-       to search_path().
-               
-Sun Aug  3 11:42:36 1997  Ben Pfaff  <blp@gnu.org>
-
-       * In several source files, the term `script' was replaced with
-       `syntax file' inside error messages.  Usage of the term `script'
-       in the sense of a syntax file is now deprecated.
-
-       * cmdline.c: (static vars pre_syntax_message, post_syntax_message)
-       Updated messages.
-
-       * dump-sysfile.c: (usage) Update message.
-
-       * getline.c: (getl_read_line) Ignore lines beginning with `#!'.
-
-       * getline.h: (glob var getl_include_path) Declare extern.
-
-       * list.q: Define EXTERN as extern before #including somP.h.
-
-       * var.h: Remove declaration of `disptype' variable.
-
-       * vfm.c: (close_active_file) After switching the data sink to a
-       data source, set vfm_sink to NULL, because it doesn't exist any
-       more.
-
-Thu Jul 17 21:41:44 1997  Ben Pfaff  <blp@gnu.org>
-
-       * glob.c: [__BORLANDC__] Include math.h.  Define _matherr() and
-       _matherrl() to ignore all math errors.
-
-       * sfm-read.c: (read_value_labels) When reading the labels from
-       disk, read the little parts separately instead of as a struct;
-       this avoids alignment problems.
-
-       * sfm-write.c: (struct sfm_fhuser_ext) New member `elem_type'.
-       (sfm_write_dictionary) Sets elem_type and frees it on lossage.
-       (write_header) Allocates and initializes elem_type.
-       (sfm_write_case) Uses elem_type to determine how to handle each
-       flt64 element.
-       (sfm_close) Frees elem_type.
-
-       * sfmP.h: Comment fix.
-       [__BORLANDC__] Uses #pragma -a to adjust structure member
-       alignment.
-       
-Thu Jul 17 01:55:12 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (fiasco_SOURCES) Remove display.c.
-
-       * common.c: Fix typo.
-
-       * dfm.c: (read_record) Remove strncasecmp() emulation and fix the
-       sense of the condition.
-
-       * expr-evl.c: (macro ALLOC_STRING_SPACE) [!PAGED_STACK] Add
-       line-continuation backslash.
-
-       * filename.c: [__WIN32__] Include <windef.h> before <winbase.h>.
-
-       * frequencies.q: (custom_grouped, add_percentile) Don't use a
-       non-constant expression as an argument to sizeof.
-
-       * glob.c: [__WIN32__ && __BORLANDC__] When including <conio.h>,
-       undefine gettext macro because that's a conio function.
-
-       * hash.h: (hsh_prime_tab declaration) Remove.
-
-       * list.q: (write_fallback_headers) Move `leader' allocation out of
-       main loop.  Change to local_alloc() allocation.
-
-       * output.h: Formatting fixes.  Put __attribute__ in right place on
-       function prototypes.
-
-       * sfm-read.c: (read_machine_flt64_info, read_variables) Change
-       incorrect `SECOND_LOWEST_VALUE' references to proper
-       `second_lowest_value'.
-
-       * som-frnt.c: (EXTERN macro) Define as `extern' instead of null
-       value.  This way 2 out of 3 of the som files define the vars
-       extern, the correct way, that actually works under BC++.
-       (som_set_float) Don't use nonconstant initializers for a struct.
-
-       * som-high.c: Add the standard alloca() header.
-       (replicate_table) Add prototype.
-
-       Merged DISPLAY routine.
-       * sysfile-info.c: (AS_*) New enum series.
-       (cmd_sysfile_info) Gutted.  Calls describe_variable() to do the
-       dirty work.
-       (cmd_display, display_macros, display_documents,
-       display_variables) Stolen from defunct display.c.
-       (describe_variable) New function.
-
-       * temporary.c: [0] (display_tree) New debug function.
-       (copy_variable) Performs shallow copy of value labels instead of
-       deep copy; i.e., just copys the AVL tree and increments the
-       reference counts.
-
-       * val-labs.c: Comment fixes.
-       (do_value_labels) Optionally skip leading forward slash.
-       (get_label) Creates only a single value label instead of many
-       copies of one, and sets the reference count.
-
-       * display.c: Removed.
-
-       * dump-sysfile.c: New file, not yet complete.
-
-Fri Jul 11 23:02:18 1997  Ben Pfaff  <blp@gnu.org>
-
-       For lots of source files I added more verbose_msg's.  These aren't
-       listed below as they have tested as being benign.  In some cases
-       these replaced debug_printf() calls.
-
-       * output.c: (outp_read_devices) Message fix.
-
-       * postscript.c: (output_encodings) Message fix.  Reports errors on
-       fclose().
-       (postopen) Message fix.
-       
-Fri Jul 11 14:09:40 1997  Ben Pfaff  <blp@gnu.org>
-
-       * dfm.c: (dfm_close) Don't call fclose() for a NULL FILE.
-
-       * filename.c: (close_file_ext) Set f->file to NULL *after* closing
-       it.
-
-       * main.c: Remove <malloc.h> #include.
-
-       * mis-val.c: (parse_numeric) Set .f member for each missing[]
-       instead of trying to just set the missing[] itself, which is a
-       gcc-specific idiom.
-
-       * sfm-read.c: (read_variables) Same.
-
-       * str.h: Add memmem() prototype.
-
-       * val-labs.c, var-labs.c: Replace <malloc.h> with <stdlib.h>.
-
-Thu Jul 10 22:13:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (q2c) Don't include any libraries in the link.
-
-       * dfm.c: (force_line_buffer_extension) New macro.
-       (count_tabs) New function.
-       (tabs_To_spaces) New function.
-       (read_record) Calls tabs_to_spaces() on the line being processed.
-
-       * q2c.c: Disabled i18n for this proglet so that libintl.a doesn't
-       have to be compiled twice (once for CC, once for LOCAL_CC).
-Sun Jul  6 19:14:33 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (INCLUDES) Add intl directory; fix directories.
-       (LDADD) Add @INTLLIBS@.
-       (q2c) Add LIBS, @INTLLIBS@ to link step.
-
-       * inpt-pgm.c: Turn off debugging.
-
-       * postscript.c: (postopen) Format fix.  local_free() blocks
-       returned by local_alloc(); don't free() them.
-
-Sat Jul  5 23:44:51 1997  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: (parse_string_as_format) Comment fix.  Fix check for
-       string length.
-
-       * data-list.c: (read_from_data_list_fixed) Pass proper value for
-       LEN arg, not simply the full string length.
-
-       * sort.c: (allocate_file_handles) Check SPSS compatible temp file
-       directories before generic temp file directories.
-
-       * vfm.c: Disable debugging.
-
-Fri Jul  4 13:26:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Comment fix.
-       (cmd_save_internal) Always passes GTSV_OPT_SAVE option.
-
-Wed Jun 25 22:52:28 1997  Ben Pfaff  <blp@gnu.org>
-
-       * expr-prs.c: (debug_print_postfix) Conditionally included on
-       GLOBAL_DEBUGGING.  Removed out_header() reference.
-
-       * exprP.h: Removed #undef GLOBAL_DEBUGGING.
-
-Sun Jun 22 22:00:28 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: Removed obsolete ascii_close_page() prototype.
-
-       * command.c: (output_line) Comment fix.
-
-       * data-in.c: Formatting fix.
-       (parse_string_as_format) Now the `fc' argument is used only for
-       the purpose of error messages; it is not an index into the string
-       passed.  All references changed.
-
-       * data-list.c: Comment fix.
-       (cut_field) Comment fix.  Now returns the column number of the
-       position of the field cut out on success.
-       (parse_field) Added `column' argument.  Puts the column numbers in
-       the error message.
-       (read_from_data_list_free, read_from_data_list_list) Record the
-       column number returned by cut_field(), pass it to parse_field().
-
-       * dfm.c: Comment fix.
-
-       * do-ifP.h: Comment fix.
-
-       * expr-prs.c: (SYSMIS_func) Implemented string-type arguments for
-       the SYSMIS function.
-
-       * expr.h, exprP.h: Comment fix.
-
-       * glob.c: (init_glob) Only calls setlocale() and family if
-       ENABLE_NLS set.
-
-       * hash.h: Comment fix.
-
-       * include.c: Comment fix.
-
-       * output.c: Comment fix.
-
-       * postscript.c: (ps_line_intersection) Simplified assertion.
-
-       * repeat.c: Comment fix.
-
-       * vars-atr.c: Comment fix.
-
-       * vars-prs.c: Comment fix.
-
-       * vfm.c: (vector_initialization) [DEBUGGING] Fixed undefined
-       behavior with usage of postincrement.
-       (memory_stream_read) Discards cases as it goes. 
-
-Sun Jun 15 16:45:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Cleans q2c, not just distcleans it.  Distcleans
-       foo.
-
-       * Most source files: Includes debug-print.h, related comment
-       fixes.
-
-       * cases.c: (alloc_val) Removed complex allocation code.  Merely
-       increments default_dict.nval and returns the former value.
-       (envector, devector) Removed references to lv member of struct
-       variable.
-
-       * common.h: (macro VME) Replaced complex definition with simple
-       one.
-
-       * data-list.c: (cmd_data_list) Sets vfm_source instead of
-       read_active_file and cancel_input_pgm.
-       (read_from_data_list, cancel_data_list) Removed.
-       (data_list_source_read, data_list_source_destroy_source) New
-       functions.
-       (glob var data_list_source) New var.
-
-       * dfm.c: (open_file_r, open_file_w) Simplified debug output.
-       (cmd_begin_data) Improved criteria for an input program accessing
-       the inline file.  Still not perfect.
-
-       * do-if.c: (do_if_trns_proc) Simplified debug output.
-
-       * expr-prs.c: Comment fixes.
-       [DEBUGGING] (debug_print_postfix) Simplified debug output.
-
-       * file-handle.q: (fh_close_handle) Simplified debug output.
-
-       * file-type.c: Comment fixes.
-       (cmd_file_type) Sets vfm_source instead of read_active_file and
-       cancel_input_pgm.
-       (cmd_end_file_type) On failure, discards variables in place of
-       just canceling the input program.
-       (read_from_file_type) Renamed file_type_source_read.
-       (cancel_file_type) Renamed file_type_source_destroy_source.
-       (glob var file_type_source) New var.
-
-       * get.c: (GTSV_* enum series) New enums GTSV_OPT_SAVE, GTSV_NONE.
-       (cmd_get) Initializes options to GTSV_NONE before passing to
-       trim_dictionary().  Removed `lv' reference.  Sets vfm_source
-       instead of read_active_file and cancel_input_pgm.
-       (cmd_save_internal) Initializes options before passing to
-       trim_dictionary().  Local var `nval' removed.
-       (dict_delete_run) Comment fixes.
-       (trim_dictionary) Comment fixes.  Disallows scratch variables if
-       GTSV_OPT_SAVE set in options.
-       (read_from_get) Renamed get_source_read.
-       (cancel_get) Renamed get_source_destroy_source.
-       (glob var get_source) New var.
-
-       * inpt-pgm.c: (cmd_input_program) Sets vfm_source instead of
-       read_active_file and cancel_input_pgm.
-       (read_from_input_program) Renamed input_program_source_read.
-       Simplified debug output.
-       (cancel_input_program) Renamed
-       input_program_source_destroy_source.
-       (glob var input_program_source) New var.
-
-       * loop.c: (loop_1_trns_proc) Simplified debug output.
-
-       * main.c: (dump_token) Made eof output more explicit.
-
-       * sfm-read.c: (read_variables, dump_dictionary) Removed `lv'
-       references.
-
-       * sort.c: (cmd_sort_cases) Disallows scratch variables.  Removed
-       code for always-memory or always-disk cases.  malloc's case-list
-       based on vfm_source_info.ncases.  Explicit support for
-       memory_stream via memory_source_cases.
-       (do_external_sort) Sets vfm_source instead of read_active_file and
-       cancel_input_pgm.
-       (allocate_file_handles) The temporary directory permissions are
-       set to 0700 instead of 0777.
-       (allocate_cases) Formatting fixes.  Simplified debug output.
-       (output_record) Compacts the case if necessary before writing it
-       out.
-       (close_handle, open_handle_w) Simplified debug output.
-       (write_initial_runs) Destroys vfm_sink, then sets it to
-       sort_stream.  Writes records to memory based on
-       vfm_sink_info.case_size.
-       (write_to_sort_cases) Renamed sort_stream_write().
-       (merge) Simplified error handling.  Simplified debug output.
-       Formatting fixes.
-       (read_from_external_sort) Renamed sort_stream_read().
-       Reads records based on vfm_source_info.case_size.
-       (sort_stream_write) Writes records to memory based on
-       vfm_sink_info.case_size.
-       (sort_stream_mode) New function.
-       (glob var sort_stream) New variable.
-
-       * temporary.c: (cmd_temporary) Simplified debug output.
-       (copy_variable) Removed references to `lv'.
-
-       * title.c: (get_title) Simplified debug output.
-
-       * var.h: Comment fixes.
-       (struct get_proc) Removed member `lv'.
-       (struct variable) Removed member `lv'.  Comment fixes.
-       (glob vars read_active_file, write_active_file, cancel_input_pgm)
-       Removed.
-       (struct case_stream) New.
-
-       * vars-atr.c: (discard_variables) Changed cancel_input_pgm,
-       read_active_file references to use vfm_source.
-       (init_variable, replace_variable) Removed references to `lv'.
-
-       * vfm.c: Comment fixes.
-       (glob var vfm_source, vfm_sink, vfm_source_info, vfm_sink_info)
-       New variables.
-       (static var queue, qh, qt, n_lag) Removed.  All references
-       removed.
-       (glob var compaction_necessary, compaction_nval, compaction_case,
-       paging) New variables.
-       (record_case) Removed.
-       (procedure) Comment fixes.  Calls vfm_source->read() instead of
-       read_active_file().
-       (lag) Removed.
-       (prepare_for_writing, arrange_compaction, make_temp_case,
-       vector_initialization, setup_filter) New function.
-       (open_active_file) Most of the code moved into the abovementioned
-       new functions.  Now sets temp_dict to &default_dict if there is no
-       temporary dictionary, for convenience.  New debug output.
-       (close_active_file) Deals with changing the sink to the source.
-       Calls finish_compaction().  Frees compaction_case.  Mostly
-       rewritten.
-       (glob vars disk_source_file, disk_sink_file) New vars.
-       (destroy_active_file, read_from_memory) Removed.
-       (disk_stream_init, disk_stream_read, disk_stream_write,
-       disk_stream_mode, disk_stream_destroy_source,
-       disk_stream_destroy_sink) New functions.
-       (glob var vfm_disk_stream) New var.
-       (glob vars memory_source_cases, memory_sink_cases,
-       memory_sink_iter, memory_sink_max_cases) New vars.
-       (memory_stream_init, memory_stream_read, memory_stream_write,
-       memory_stream_mode, memory_stream_destroy_source,
-       memory_stream_destroy_sink) New functions.
-       (glob var vfm_memory_stream) New var.
-       (write_case) Local var `i' renamed `cur_trns'; local var `retval'
-       named `more_cases'.  Simplified debug output.  Otherwise mostly
-       rewritten.
-       (record_case) Moved into the stream drivers.  Removed.
-       (transform) Removed (was dead code).
-       (SPLIT_FILE_procfunc) s/vfm_replacement/vfm_sink_info/.  In the
-       common case that the splits don't change, we don't need to copy
-       the case into prev_case again--pointless.
-       (compact_case) New function.
-       (finish_compaction) New function.
-
-       * vfmP.h: Comment fixes.
-       (DEV_* enum series) Removed. 
-       (struct storage) Renamed `stream_info'.  Removed variant record.
-       Removed `device' member.
-
-       * debug-print.h: New file.
-       
-Sun Jun  8 01:12:38 1997  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.c: Turned off debugging.
-
-       * data-list.c: (destroy_dls) Closes the associated file handle.
-
-       * descript.q: (custom_variables) Added PV_NO_SCRATCH to
-       parse_variables() options.
-
-       * dfm.c: (open_file_r) Removed gratuituous argument to msg() call.
-
-       * display.c: (display_variables) Really fixed null cell bug.
-
-       * file-handle.q: (fh_close_handle) Changed debugging message.
-
-       * frequencies.q: (custom_variables) Added PV_NO_SCRATCH to
-       parse_variables() options.
-
-       * list.q: Added PV_NO_SCRATCH in q2c varlist options.
-       (cmd_list) Fails if no variables specified.
-       (determine_layout) Writes blank lines manually.
-
-       * loop.c: (loop_1_trns_proc) Made debugging code only print
-       messages if debugging.
-
-       * q2c.c: (dump_subcommand) Appends sbc->message to SBC_VARLIST
-       parse_variables() arguments.
-       (main) Parses optional parenthesized options to varlist
-       subcommands into sbc->message.
-
-       * sfm-read.c: Format fix.
-
-       * var.h: (FV_*) New enum series.
-       (PV_*) New enum PV_NO_SCRATCH.
-
-       * vars-prs.c: (find_var) Removed.
-       (fill_all_vars) Takes FV_* enum instead of boolean third
-       argument.  Rewritten to deal with scratch as well as system
-       variables.
-       (parse_variables) Error message on scratch variable if
-       PV_NO_SCRATCH set.
-
-       * vfm.c: (static var virt_begin_func) New var.
-       (procedure) Sets up virt_begin_func.
-       (SPLIT_FILE_procfunc) For the first case, calls virt_begin_func()
-       after dump_splits().  For succeeding groups changes, calls
-       virt_begin_func() instead of begin_func().      
-
-Fri Jun  6 22:42:23 1997  Ben Pfaff  <blp@gnu.org>
-
-       * count.c, data-out.c, file-handle.q, list.q, loop.c: Turned off
-       debugging.
-
-       * dfm.c: Added some debugging messages, disabled by default.
-       (open_file_r) Fixed error message.
-       (read_record) On eof on inline_file, instead of calling
-       fh_close_handle(), simply jump to eof label like a normal file.
-       Message fixes.
-
-       * display.c: Thin lines between rows for certain kinds of
-       listing.  Fixed `null cell' bug.
-
-       * error.c: (failure) Flush stdout, stderr before failing.
-
-       * file-handle.q: (fh_close_handle) Added debugging message.
-
-       * frequencies.q: (dump_full) Bottom line extends across entire
-       table width.  Changed title formatting.
-       (dump_condensed) Changed title formatting.
-       (dump_statistics) Fixed title formatting.
-
-       * glob.c: (init_glob) Moved initialization of cur_proc out of #if.
-       Sets default value of set_format.
-
-       * list.q: (cmd_list) Calls blank_line() before determine_layout().
-       Passes write_all_headers() to procedure() as pre-group func.
-       (write_all_headers) New function.
-       (determine_layout) Removed calls to write_header().
-       Calls blank_line() before and after write_fallback_headers().
-
-       * recode.c: (recode_trns_free) Only attempts to free head->map if
-       non-NULL.
-
-       * sfm-read.c: (read_variables) Allows `#' at beginning of system
-       file variable names but gives a warning.  Sets `left' based on
-       first character being/not being `#'.  On lossage frees dict->var.
-
-       * som-high.c: (som_draw_title) Simplified title formatting.
-
-       * vfm.c: (dump_splits) Fixed and changed splits formatting.
-
-Thu Jun  5 22:51:15 1997  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.c: (cmd_autorecode) Sets h_trans to NULL at
-       beginning.  Frees v_src, v_dest on successful exit.  Frees
-       h_trans[*], h_trans on lossage.
-       (recode) Frees h_trans[*], h_trans.
-
-       * dfm.c: (dfm_close) Formatting change.
-       (open_inline_file) Now passed a dfm_fhuser_ext to initialize; no
-       longer allocates its own in inline_file.
-       (open_file_r) Passes the local dfm_fhuser_ext to
-       open_inline_file().
-       (open_file_w) Message fix. 
-       (read_record) Buffer reallocation strategy changed.  Frees
-       ext->line even in inline_file to prevent leaks.
-       (dfm_put_record) Fixed bug where `ext' was cached before the file
-       was opened and thus it would be NULL when the file really was
-       open.
-       (cmd_begin_data) Sets up inline_file basics itself, then calls
-       open_inline_file() for the dfm_fhuser_ext.  Formatting fix.
-
-       * list.q: (write_line) Formatting fix.
-       (clean_up) Minor strategy change.  Sets proportional font after
-       finishing cleanup.
-       (determine_layout) Sets fixed font before writing regular headers,
-       or after writing fallback headers.
-
-       * modify-vars.c: (cmd_modify_vars) Frees variable lists for DROP
-       and KEEP vars after using them.
-
-       * postscript.c: (ps_init_driver) Frees x->family.
-       (postopen) When loading fonts, free the temporary font name buffer
-       after using it.
-       (ps_text_set_font_by_position) Free temporary font name buffer
-       after using it.
-       (text) Fixed code that calculated `lig' so that `lig' always gets
-       initialized.  Formatting fix.
-
-       * som-low.c: (get_cell_size, som_get_table_size) `prop_height' ->
-       `font_height'.
-       [GLOBAL_DEBUGGIGN] (check_table) Use arena_alloc() to allocate
-       cells, not xmalloc(), so that the cells will get destroyed
-       automatically.
-
-       * sysfile-info.c: (cmd_sysfile_info) Frees the dictionary after
-       using it.
-
-Tue Jun  3 23:33:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_text_draw) Always sets metrics for strings that
-       are drawn.
-
-       * dfm.c: Comment fix.
-
-       * list.q: Comment fixes.  Include somP.h.  Removed static vars
-       table, n_columns, n_rows, part.  New struct list_ext.  New static
-       var line_buf.
-       (n_lines_remaining, n_chars_width, write_line) New functions.
-       (cmd_list, list_cases) Rewritten.
-       (begin_row, end_row, flush_table) Removed.
-       (write_header, clean_up, write_varname, write_fallback_headers,
-       determine_layout) New functions.
-
-       * output.c: (outp_iterate_enabled_drivers) Minor reformat.
-
-       * output.h: Comment fix.
-
-       * postscript.c: Comment fix.
-       (struct ps_driver_ext) Removed prop_size, fixed_size members;
-       added font_size.  All references changed.
-       (ps_init_driver) Initializes font_size.  Simplified space checking
-       code.
-       (static var option_tab[]) Removed prop-size, fixed-size; added
-       font-size.
-       (ps_option) Handles font_size.
-
-       * som-high.c: Moved prototypes into somP.h.
-       (som_init_driver) New function.
-       (som_submit_table) Moved some code into new function
-       som_init_driver().
-       (build_target) Moved some code into new function
-       som_internal_eject_page().
-       (som_eject_page) Uses som_internal_eject_page().
-       (som_internal_eject_page) New function.
-
-       * som-low.c: Moved prototypes into somP.h.
-
-       * som.h: Formatting fixes.
-
-       * somP.h: (struct som_driver_ext) Removed em_width;
-       added prop_em_width, fixed_width.
-
-Mon Jun  2 14:25:25 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added `localedir' definition.  Added
-       -DLOCALEDIR="..." to DEFS.  Added -I. to INCLUDES.
-
-       * ascii.c: (macro draw_line) Fixed capitalization.
-
-       * ascii.c, autorecode.c, cases.c, cmdline.c, command.c, common.c,
-       compute.c, count.c, data-in.c, data-list.c, data-out.c,
-       descript.q, dfm.c, display.c, do-if.c, error.c, expr-evl.c,
-       expr-opt.c, expr-prs.c, file-handle.q, file-type.c, filename.c,
-       formats.c, frequencies.q, get.c, getline.c, glob.c, groff-font.c,
-       hash.c, heap.c, include.c, inpt-pgm.c, lexer.c, list.q, loop.c,
-       main.c, mis-val.c, misc.c, modify-vars.c, numeric.c, output.c,
-       postscript.c, print.c, q2c.c, recode.c, rename-vars.c, repeat.c,
-       sample.c, sel-if.c, sfm-read.c, sfm-write.c, sfmP.h, som-frnt.c,
-       som-high.c, som-low.c, sort.c, split-file.c, sysfile-info.c,
-       temporary.c, title.c, tokens.h, val-labs.c, var-labs.c,
-       vars-atr.c, vars-prs.c, vector.c, vfm.c, weight.c: Marked strings
-       for internationlization.
-
-       * glob.c: [HAVE_LOCALE_H] Includes locale.h.
-
-Sun Jun  1 23:31:18 1997  Ben Pfaff  <blp@gnu.org>
-
-       * do-if.c, sort.c, val-labs.c: Comment fixes.
-
-       * glob.c: (init_glob) Uncommented, updated i18n support.
-       
-       * arena.c, ascii.c, data-in.c, descript.q, error.c, expr-evl.c,
-       expr-opt.c, expr-prs.c, filename.c, frequencies.q, groff-font.c,
-       output.c, postscript.c, sfm-read.c, som-high.c, vars-prs.c: Made
-       the declarations of macros taking arguments a lot nicer.
-
-Sun Jun  1 17:22:04 1997  Ben Pfaff  <blp@gnu.org>
-
-       * error.h: Removed CE, CW aliases for SE, SW.
-
-       * q2c.c: Removed explicit streq() definition since it's duplicated
-       in str.h.
-       
-       * approx.h, error.h, font.h, hash.h, misc.h, output.h, somP.h,
-       stats.h, str.h, tokens.h: Made the declarations of macros taking
-       arguments a lot nicer-looking of <pinard@iro.umontreal.ca>.
-       Comment fixes.
-
-Sun Jun  1 12:02:06 1997  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: Comment fixes.
-       (pick_compat) Changed return type to int.  Now, instead of setting
-       glob var `compat' to the emulation, returns the emulation.  All
-       references changed.
-       (parse_command_line) Added terminating null to end of
-       `long_options' array definition.
-       (pre_syntax_message) Fixes.
-       (usage) Shows the default emulation in the syntax message by
-       calling pick_compat().
-
-       * getline.c: (getl_add_include_dir) Separates paths with
-       PATH_DELIMITER, not DIR_SEPARATOR.
-
-       * glob.c: (init_glob) Fixed references to DEFAULT_VER_PCP40,
-       DEFAULT_VER_WIN61, DEFAULT_VER_X40.
-
-       * output.c: (outp_configure_macro) Make earlier definitions for a
-       particular key override later ones for the same key.
-       
-Fri May 30 19:40:49 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: Comment fixes.
-
-       * output.c: (outp_get_paper_size)
-       s/STAT_OUTPUT_INIT_FILE/STAT_OUTPUT_PAPERSIZE_FILE/.
-       
-Sun May 25 22:34:07 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c, postscript.c, sfm-read.c, sfm-write.c, sort.c: Include
-       <errno.h>.  GNU libc 2 enforces this!
-
-       * command.c: (parse_cmd) Fixed problem with `else' clause being
-       paired with wrong `if'.  Comment fix.
-
-Fri May  9 16:53:52 1997  Ben Pfaff  <blp@gnu.org>
-
-       * getline.c: [!HAVE_LIBREADLINE] (read_console) Changed
-       blp_getline() to getline().
-
-       * output.c: (outp_eval_dimension) Changed the fix from last time;
-       there was no variable `a'.
-
-       * q2c.c: (get_line) Fixed boundary condition overrun bug.
-
-Mon May  5 21:58:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * output.c: (outp_evaluate_dimension) Fixed handling of negative
-       numbers having fractional parts.  Added case of a fraction without
-       a whole-number part.
-
-Fri May  2 22:08:05 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_text_get_font_position) Removed.
-
-       * expr.h, exprP.h: Disabled debugging.
-
-       * groff-font.c, postscript.c: Changed `groff' to `Groff' in
-       several places.
-
-       * output.h: (struct outp_class_struct) Removed
-       text_get_font_position method.  All references deleted.
-
-       * postscript.c: Big change here.  Fontmaps were completely
-       eliminated because of a change in philosophy.  Comment fixes.
-       (struct ps_fontmap, ps2dit_map, font_family, dit2family_map)
-       Removed.
-       (struct ps_driver_ext) `position', `fontmap', `prop_name',
-       `fixed_name' members removed.  New members `prop_family',
-       `fixed_family'.  `family' member changed to type char *.
-       (static var ps_fontmaps) Removed.
-       () Removed.
-       (ps_init_driver) Removed obsolete references, updated.
-       Initializes `translate_x', `translate_y', `scale'.  Doesn't read
-       fontmap, of course.  Refers to font names through internal_name
-       rather than subversive means.  Frees proper items.
-       (static var option_tab[]) Removed `fontmap-file' option; renamed
-       `fixed-font', `prop-font'.
-       (ps_option) Corresponds to option_tab[].
-       (read_fontmap, release_fontmap, ps_to_dit, compare_ps2dit,
-       hash_ps2dit, compare_dit2family, hash_dit2family, compare_family,
-       hash_family) Removed.
-       (postopen) Generates font names from family names.  Gets
-       PostScript font name properly.  New prologue file comment `!!!'
-       style.
-       (ps_open_page) Adds translate_x, translate_y to BP prologue
-       function; gives SF argument floating-point format.
-       (ps_text_set_font_by_name) Doesn't try to map PostScript->Groff
-       font name.  Doesn't change font family.
-       (ps_text_set_font_by_position) Generates Groff font name from font
-       family name instead of through table lookup.
-       (ps_text_set_font_by_family) Renamed `ps_text_set_font_family',
-       all references changed.  Reduced to simple string assignment.
-       (ps_get_font_name) Removed.
-       (ps_get_font_family) Reduced to string return.
-       (text) Doesn't save `position' since it no longer exists.  Ugly
-       kluge to save font family--fix soon?
-       (load_font) Removed PostScript name argument.
-       
-Thu May  1 14:58:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: Comment fix.
-       (ps_open_page) Puts scale factor in PostScript output.
-       
-Sat Apr 26 11:49:32 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Distcleans q2c.
-
-Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (delineate) Sets text size even if width is zero.
-
-       * command.c: Comment fix.
-       (static var cmd_table[]) Re-enabled EVALUATE command.
-       (parse_cmd) Lotsa comment fixes.  Fixed infinite loop in parsing
-       of comments in script files.  Now more liberal on criteria for
-       performing a state transition--if *anything* happened correctly,
-       not just if *everything* happened correctly.
-
-       * data-out.c: (convert_F) Comment fix.  Why in the fsck does
-       Checker segfault on formatting large numbers and why in the fsck
-       hadn't I noticed this before?
-
-       * expr.h, exprP.h: No longer turn off GLOBAL_DEBUGGING.
-
-       * list.q: (cmd_list) Commented out the actual output routine
-       because of various problems.  Probably will abandon the idea of
-       using the general `crushed tables' for the LIST procedure.
-
-       * temporary.c: (restore_dictionary) Sets var_by_name to NULL after
-       clearing it.  Allocates a new var_by_name dictionary before trying
-       to add members to it.
-
-       * vars-atr.c: [DEBUGGING] (dump_one_var_node) Removed argument
-       `sib'.  Changed type of `node' argument.
-       [DEBUGGING] (dump_var_tree) Replaced avlwalk() with
-       avl_walk_inorder().
-       (clear_variable) Only dumps the var tree if var_by_name non-NULL.
-       [DEBUGGING] Only deletes the variable from var_by_name if that var
-       non-NULL.
-
-Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added include files to SOURCES.  Added
-       frequencies.q to EXTRA_DIST.  Removed include/ from INCLUDES.  Now
-       includes rules for q2c.  Added `boast' target.
-
-Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Maintainer-clean Makefile.in.
-       
-       * Makefile.am: Fixed redundant EXTRA_DIST line.
-
-       * ascii.c: Comment fixes.
-       (ascii_line_vert) Fixed overly aggressive range check.
-
-       * display.c: Removed dead code.
-
-       * list.q: Turn debugging on.
-       (flush_table) New debug code.
-
-       * sfm-read.c: (read_value_labels) malloc's the structure before
-       trying to assign to its members.
-
-       * sfm-write.c: Comment fix.
-
-       * som-high.c: (som_submit_table) Sets som.t and som.d on each call
-       to output_table().
-       (output_table) No arguments anymore--gets them through `som'
-       global.  New debug code.  In crushed tables, now sets `htv' as
-       well as `hv' to avoid bad confusion later.
-       (dump_crush_page) New debug code.
-
-       * som-low.c: (som_dump_crush_page) New debug code.
-
-Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
-
-       All source files: Broke long lines into multiple lines.
-       
-       * ascii.c: (ascii_close_page) Uses host_system var in place of
-       HOST_SYSTEM constant.
-
-       * cmdline.c: (var syntax_message[]) Broke into
-       pre_syntax_message[] and post_syntax_message[].
-       (usage) Outputs both parts, separated by driver list.
-
-       * error.h: Fixed broken formatting.
-
-       * expr-opt.c: (str_search, str_rsearch) New functions.
-
-       * misc.c: (blp_getdelim) Removed.  All references changed to
-       `getdelim'.
-       (str_search, str_rsearch) Removed.
-       (memrmem) New function.
-
-       * misc.h: (blp_getline) Removed.  All reference changed to
-       `getline'.
-
-       * stat.h: New file.
-
-       * filename.c: Includes "stat.h", not <sys/stat.h>.
-       (blp_getenv) Uses host_system var instead of HOST_SYSTEM constant.
-
-       * output.c: (outp_list_classes) Changed output formatting.
-
-       * sfm-write.c: (write_header) Uses host_system var instead of
-       HOST_SYSTEM constant.
-       (write_rec_7_34) Extracts version numbers from the version string.
-       Untested.
-
-       * sort.c: Includes "stat.h", not <sys/stat.h>.
-
-       * str.c: (strcasecmp) Removed.
-
-       * title.c: (cmd_document) Uses host_system var instead of
-       HOST_SYSTEM constant.
-
-       * version.c: Generated on-the-fly by the Makefile instead of being
-       static.
-
-       * str.h: Comment fixes.  Doesn't substitute for missing memmove or
-       memcpy.
-       [!HAVE_STRNCASECMP] Declares strncasecmp().
-
-       * version.h: Removed stray character.  Comment fixes.
-       (vars host_system, build_system) New vars.
-
-Mon Mar 24 21:47:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Most source files: Changed formatting of copyright notice; fixed
-       FSF address; reformatted to better conform to GNU standards;
-       comment fixes.  Added markups to prevent GNU indent from messing
-       up my beautiful formatting :-).
-       
-       * q2c.c: (get_line) Ignores lines that begin with `/* *INDENT' so
-       that GNU indent markups can be passed through without problems.
-
-Wed Feb 19 21:30:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Turned off debugging.
-
-       * glob.c: (init_glob) Turned on save-file compression by default.
-
-       * sfm-write.c: (sfm_write_case) Fixed bug which resulted in less
-       compression than was possible in save files.
-
-Sun Feb 16 20:57:20 1997  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c: (convert_F) Comment fixes.  Debug message fixes.
-
-       * frequencies.q: Removed Fiasco extensions.  Updated calculation
-       algorithms.  Polished output format. 
-       (struct frq_info_struct) Removed members `max_degree', `min_n',
-       all references removed.
-       (macro frq_extensions) Removed.
-       (static vars min_n, max_degree) Removed, all references removed.
-       (internal_cmd_frequencies) Doesn't handle extensions.  Doesn't
-       calculate `min_n', `max_degree'.
-       (postcalc) Passes new arg to dump_statistics().
-       (dump_full) Honor NOLABEL option.  Buggy?  Adds variable name
-       title.
-       (dump_condensed) Adds variable name title.
-       (sum_freqs) Removed.
-       (calc_stats) Updated calculation algorithm.
-       (dump_statistics) Removed warning for too-few observations.
-       Changed table formatting.  Adds variable name title if passed new
-       arg is nonzero.
-
-       * output.h: Comment fix.
-
-       * recode.c, sample.c, sort.c: Disabled debug code.
-
-       * som-frnt.c: (som_set_value, som_set_float, som_set_text)
-       Improved debug code.
-
-       * var.h: (enum series frq_*) Removed Fiasco extensions.
-
-Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added PROCESS IF to command table.
-
-       * Lots & lots of places, removed checks for NULLs preceding calls
-       to free_expression(), which itself checks.
-
-       * descript.q: Removed Fiasco extensions.  Removed optimizations
-       for non-weighted active files.  Implemented some options.
-       Finished polishing output format.  Comment fixes.  Merged
-       `descript.g'.
-       (static vars n_glob_miss_list, n_glob_valid, n_glob_missing,
-       max_degree, min_n) Removed.
-       (macro dsc_extensions) Removed.
-       (struct dsc_info_struct) Removed `min_n' member, all references
-       fixed.
-       (internal_cmd_descriptives) Removed calculation of min_n,
-       max_degree.  Only deals with one `calc' routine instead of two
-       flavors.
-       (precalc) Eliminated redundancy.  Updated for changes to
-       descriptives_proc structure.
-       (calc) Moved here from `descript.g'.  Rewritten to calculate
-       statistics via `moments about the mean' rather than by summing,
-       summing squares, summing cubes, and so on.
-       (postcalc) Rewritten for new-style statistical calculation.
-       (display) Removed support for displaying variables across rows.
-       No longer crushes the descriptives table.  Removed ancient code.
-       Added display of N, by variable and listwise.
-
-       * descript.g: Removed; merged into `descript.q'.
-
-       * expr-evl.c: (evaluate_expression) Now returns a double.  For
-       numeric results, it returns the result as well as storing it in
-       the passed `value' structure if non-NULL.  For string results it
-       just returns 0.0 and it must be passed non-NULL.  Many references
-       to this function were optimized by use of this change, especially
-       but not exclusively in `compute.c'.
-
-       * frequencies.g: Comment fix.
-
-       * glob.c: (glob var process_if_expr) New global var.
-
-       * postscript.c: (static var option_tab[]) Corrected entry for
-       `fixed_size'.
-       (postopen) Sets x->size to x->prop_size.
-       (ps_text_set_font_by_name) Sets font size as well as typeface for
-       PROP and FIXED fonts.
-       
-       * sel-if.c: (cmd_process_if) New function.
-
-       * sfm-write.c: (struct sfm_fhuser_ext) New member `n_cases'.
-       (sfm_write_dictionary) Sets `n_cases' to 0.
-       (sfm_write_case) Increments `n_cases'.
-       (sfm_close) Attempts to seek the system file back to the header
-       and write the number of cases in its proper slot.
-
-       * som-frnt.c: (som_insert_table) Masks off expansion options since
-       only SOPT_X_NORM seems to work sensibly.
-
-       * som-low.c: (get_cell_size) Fixed bug when a table cell was sized
-       with a `fixed' value of 2.
-
-       * sort.c: (cmd_sort_cases) Cancels PROCESS IF.
-
-       * sysfile-info.c: (cmd_sysfile_info) Doesn't display more than 10
-       value labels; uses SOPT_NONE instead of SOPT_X_BOTH.
-
-       * var.h: (enum series dsc_*) Removed Fiasco extensions.
-       (struct descriptives_proc) Removed `miss_noweight'; new members
-       `X_bar', `M2', `M3', `M4', `min', `max'.
-
-       * vars-atr.c: (discard_variables) Cancels PROCESS IF.
-
-       * vfm.c: (close_active_file) Cancels PROCESS IF.
-       (write_case) Doesn't process cases unselected by PROCESS IF.
-
-Fri Feb 14 23:32:58 1997  Ben Pfaff  <blp@gnu.org>
-
-       * glob.c: (glob var err) Removed.
-
-       * sysfile-info.c: (cmd_sysfile_info) When adjusting table size,
-       doesn't have to take into account number of value labels since
-       they're in a subtable anyway.  Also, doesn't display more than 10
-       value labels since we can't yet break pages in subtables.
-
-Tue Feb  4 15:15:50 1997  Ben Pfaff  <blp@gnu.org>
-
-       * som-frnt.c: (som_change_table_size) Simple change for elegance
-       that shouldn't change behavior.
-       (som_set_value) Comment fix.
-
-       * som-high.c: (som_submit_table) Message fix.
-
-Wed Jan 22 21:54:00 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added SYSFILE INFO to command table.
-
-       * file-handle.q: (fh_handle_filename) New function.
-
-       * get.c: (save_trns_proc) Fixed a bug in padding of output data
-       with spaces.
-
-       * main.c: (parse) New return value for command functions, -3.
-
-       * misc.h: Comment fix.
-
-       * output.h: Comment fixes.
-       (macro COMPONENTS) Removed.
-
-       * postscript.c: (write_text) Modified literal_chars[] so that `('
-       and ')' are not written to the output in strings as literals.
-
-       * sfm-read.c: (sfm_read_dictionary) New argument.
-       (read_header) New argument.  Sets the information structure's
-       values from the header information.  
-       (read_variables) [__CHECKER__] Redefines isalnum()--some sort of
-       bizarre Checker problem, I guess.
-       (read_variables) Proper cleanup on lossage.
-
-       * sfm.h: (struct sfm_read_info) New struct for use by
-       sfm_read_dictionary().
-
-       * som-frnt.c: (som_create_table) New argument CREATE_FLAGS,
-       currently used just for tables that can be dynamically resized and
-       thus have to be allocated with arena_malloc() instead of
-       arena_alloc().  All references changed.
-       (som_change_table_size) New function.
-       (som_insert_table) Bugfix: now inserts `cell', not `c'!
-
-       * som-high.c: [GLOBAL_DEBUGGING] (check_table) Moved to som-low.c.
-       (som_submit_table) [GLOBAL_DEBUGGING] Doesn't call check_table()
-       any more.
-
-       * som-low.c: (draw_cell) Calls draw_table_cell() for SCON_TABLE
-       cells.
-       (draw_intersection) Now takes an argument specifying the table in
-       question.  All references changed.
-       (draw_table_cell) New function.
-       (som_get_table_size) [GLOBAL_DEBUGGING] Calls check_table().
-       (som_get_table_size) Many nice new explanatory comments.
-       [GLOBAL_DEBUGGING] (check_table) Moved here from som-high.c.
-
-       * som.h: New enum series SOM_CREATE_* for use as create flags with
-       som_create_table().
-
-       * str.h: Moved a comment here from TODO.
-
-       * sysfile-info.c: New file.  Reference implementation.
-
-Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added RENAME VARIABLES to table of commands.
-
-       * data-in.c: (dls_error) Sets `cust_field'.
-       (parse_N) Message fix.
-       (parse_day_count) New function.
-       (to_roman) Never outputs VX as a `short form' of V.
-       (parse_month) Fixed parsing of Roman numerals.
-       (parse_trailer) Message fix.
-       (parse_DATE, parse_ADATE, parse_EDATE, parse_SDATE, parse_JDATE,
-       parse_QYR, parse_MOYR, parse_WKYR, parse_DTIME) Issue a message if
-       the date is invalid.
-       (parse_SDATE) Fixed swapped day, year.
-       (parse_JDATE) Fixed bug for dates in 1582.
-       (parse_DTIME) Allows days not between 1 and 31.
-       (parse_numeric) Makes local copy of f.type for easier usage.
-       FMT_DOLLAR fixed.
-
-       * data-out.c: (convert_F) When outputting as scientific, properly
-       sets f.type as fp->type.
-       (insert_commas) Fixed operator precedence problem with setting of
-       nitems.  Changed strcpy to memcpy (no null terminator). 
-       (convert_date) Fixed FMT_JDATE: added 1900 to year.
-       (convert_CCx) Essentially rewritten, but now it works.
-
-       * display.c: (cmd_display) Added DISPLAY FILE LABEL (undocumented
-       feature of Fiasco).
-       (display_documents) Implemented.
-
-       * error.c: (glob var cust_field) New var.
-       (vmsg) Displays cust_field as part of message classes DE and DW.
-
-       * formats.c: (debug_print) Fixed to compile under updated
-       dictionary format.
-
-       * get.c: (cmd_get, cmd_save_internal) Close file handle on
-       failure.
-
-       * misc.c: (parse_format_specifier) Formatting fix.
-
-       * modify-vars.c: (struct var_modification) Renamed `n_reorder' as
-       `n_rename' for clarity.
-       (cmd_modify_vars) Initializes `forward' and `positional' at
-       appropriate times.  Frees lists of vars to rename on failure.
-       Comment fix.  Frees memory on success.  
-       (rearrange_dict) Simplified `for' loop condition.
-
-       * rename-vars.c: New file (reference implementation).
-       
-       * set.q: (internal_cmd_set) Fixed `emu' test condition.
-
-       * sfm-read.c: (read_header) File label is created only if file
-       label in file is not blank.
-       (read_variables) Initializes `dict' local variable.
-       (read_documents) Proper behavior on lossage.
-
-       * sfm-write.c: (write_header) Doesn't blank out the file label
-       (why was this here to begin with?!)
-
-       * temporary.c: (save_dictionary) File label is copied only if
-       non-NULL.  Doesn't try to xstrdup() dictionary documents.
-       Adapted so as to not irritate Checker.
-       (free_dictionary) Only destroys var_by_name if non-NULL.
-
-       * title.c: (cmd_file_label) Doesn't skip FILE, LABEL tokens.
-       (cmd_document) Doesn't skip DOCUMENT token.  Adds some header
-       lines to the document, indents the document.  Also, it works now.
-       (add_document_line) New function.
-
-       * var.h: (struct dictionary) Reordering.
-
-       * vars-prs.c: (parse_variables) On lossage, only local_free()'s
-       bits if it was allocated to begin with.
-
-Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added MODIFY VARS to list of commands.
-
-       * configure.in: Updated custom macros for autoconf 2.12.  Removed
-       mmap reference; fixed termcap library reference.
-
-       * display.c: (display_variables) Fixed a few bugs although it's
-       still not well written.
-
-       * error.c: [!__CHECKER__] (chkr_disp_call_chain) New function.
-       (induce_segfault) Calls chkr_disp_call_chain() instead of
-       inducing an actual SIGSEGV.
-
-       * expr-opt.c: (evaluate_tree) Swapped order of arguments to
-       str_search() and str_rsearch().  Fixed tests for matches on
-       OP_INDEX and OP_RINDEX.
-
-       * filename.c: (good_getcwd) Removed as the new libc for Checker
-       doesn't contain this bug, apparently.
-
-       * misc.c: (str_search, str_rsearch) Changed order of arguments for
-       consistency with GNU memmem.
-       (blp_getdelim) Changed `len' from `int' to `size_t'.
-
-       * modify-vars.c: Reference implementation.
-
-       * som-frnt.c: (zero_length) New global var.
-       (som_create_table) Message fix.
-
-       * som.h: Added gcc attributions to som_set_text(),
-       som_output_text() prototypes.  blank_line() refers to
-       zero_length[] instead of a literal null string to suppress gcc
-       warnings.
-
-       * sort.c: (do_external_sort) Fixed fencepost error on lossage.
-       (allocate_cases) Decrements x_max so the last element of x[] can
-       be used by the algorithm.
-
-       * var.h: Changed minor details of `variable' declaration.  
-       (struct modify_vars_proc) New struct.
-       (struct variable) Added field p.mfv.
-
-       * vars-atr.c: Comment fix.
-
-       * vars-prs.c: (fill_all_vars) More optimal implementation.
-
-       * vfm.c: (dump_splits) Sets the last byte of temp_buf to a null
-       character, which it shouldn't have to do but printf() seems to
-       read the null byte even though I supply a maximum length...
-
-Fri Jan 10 20:22:08 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Removed command alias X for QUIT.
-       (parse_cmd) Fixed comment parsing.
-
-       * dfm.c: (struct dfm_fhuser_ext) Fields `len', `size' are now of
-       type size_t.
-       (read_record) Fixed references to len, size.
-       (dfm_get_record) Restructured.
-
-       * file-handle.h: (struct file_handle) Field `lrecl' now of type
-       size_t.
-
-       * file-handle.q: (internal_cmd_file_handle) Checks for nonpositive
-       record length.
-
-       * modify-vars.c: New file.  Not complete.
-       
-       * set.q: (set_ccx) Fixed operator precedence problem regarding ^
-       and ==.
-
-       * sfm-read.c: (bswap_flt64, read_header, write_variable) Fixed
-       problems caused by int/size_t differences.
-
-       * sort.c: (output_record, merge_once) Cast `size_t's to `int's in
-       appropriate spots.
-
-       * str.c: (strcasecmp) Fixed bug that cropped up when the strings
-       being compared were of equal length.
-
-Thu Jan  2 19:08:23 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added DOCUMENT, DROP DOCUMENTS, FILE LABEL.
-
-       * lexer.c: (get_dotted_rest_of_line) New function.
-
-       * sel-if.c: (cmd_filter) Cannot choose string or scratch variables
-       as filters.
-
-       * sfm-read.c: (sfm_read_dictionary) Calls read_documents() to read
-       type 6 records.  Frees the dictionary properly.
-       (read_header) Initializes the dictionary instead of letting
-       read_variables() do it.  Sets the dictionary file label from the
-       system file.
-       (read_documents) New function.
-
-       * sfm-write.c: (sfm_write_dictionary) Calls write_documents() to
-       write type 6 record if appropriate.
-       (write_header) Writes file label from dictionary.
-       (write_documents) New function.
-
-       * temporary.c: (save_dictionary, restore_dictionary,
-       free_dictionary) Properly handle new fields in dictionary struct.
-
-       * title.c: (get_title) Returns after failure().
-       (cmd_file_label, cmd_document, cmd_drop_documents) New functions
-       for new commands FILE LABEL, DOCUMENT, DROP DOCUMENTS.  Untested.
-
-       * var.h: (struct dictionary) New fields `label', `n_documents',
-       `documents'.
-
-Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added FILTER to list of commands.
-
-       * frequencies.g: [WEIGHTING] Removed test for weighting!=-1 since
-       it's always true.
-
-       * get.c: (cmd_save_internal) Removed weighting code since it's now
-       handled by sfm-write.c.  Properly commented out debug code.
-
-       * glob.c: (glob var weighting) Removed.
-
-       * sel-if.c: Comment fixes.
-       (cmd_filter) New function.
-
-       * sfm-read.c: (struct sfm_fhuser_ext) New field `weight_index'.
-       (sfm_read_dictionary) Sets weighting variable direct in the
-       created dictionary now.  (Apparently we previously didn't support
-       weighting on GET?)
-       (read_header) Sets weight_index field in sfm_fhuser_ext from
-       header read from disk.
-
-       * sfm-write.c: (sfm_write_dictionary) Comment fix.
-       (write_header) Now sets the weighting in the header from the
-       passed primary dictionary instead of from the sfm_write_info.
-
-       * sfm.h: (struct sfm_write_info) Removed field `weight'.
-
-       * som-high.c: (dump_crush_table) Fixed a couple of assertions that
-       broke on boundary conditions.
-
-       * var.h: (struct dictionary) New fields `weight_var',
-       `weight_index', and `filter_var'.
-       (glob var weighting) Removed.  This is now part of struct
-       dictionary.  All references changed; the less mechanical changes
-       are described above.
-
-       * vars-atr.c: (find_dict_variable) New function.
-
-       * vfm.c: (static var filter_index) New variable.
-       (open_active_file) Initializes filter_index from default_dict.
-       (write_case) Calls proc_func() only if the filter variable is
-       nonzero; this implements FILTER behavior.
-
-       * weight.c: (static var weight_varname) Removed.
-       (cmd_weight) Modified default_dict instead of glob vars.
-       (update_weighting) Changed the signature to modify a dictionary
-       instead of glob vars.  Now returns the weighting variable.
-       (get_weighting_variable) Removed; its function is absorbed by
-       update_weighting().
-       (stop_weighting) Operates on a dictionary now.
-
-Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: Removed debugging info from messages.
-       (do_external_sort) Cleans up after itself by deleting the
-       temporary directory on failure.  (On success it is deleted by the
-       input program.)
-       (allocate_cases) Removed debug code.  Added clean up code.
-       (output_record) Removed debug code.
-       (merge) Added code to close all the input files that are currently
-       open.  This is a likely location for bugs, because I'm not sure
-       about boundary conditions.  Removed an unnecesary heap_delete().
-       (merge_once) Removed input file "optimization" that in fact
-       screwed up the rest of the code.  Message and comment fixes.
-
-Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
-
-       * error.c: [__CHECKER__] (induce_segfault) Flushes output streams.
-
-       * heap.c: (heap_delete) New argument.
-
-       * sort.c: Finished implementation of external sort.
-
-       * vfm.c: (read_from_disk) Returns after a disk error.
-
-Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: (static var state) Removed.
-       (static vars max_handles, tmp_basename, tmp_extname,
-       huffman_queue) New variables.
-       (do_external_sort) Moved most code to new functions.
-       Creates huffman_queue.
-       (allocate_file_handles, allocate_cases) New functions.
-       (static vars run_no, run_length, file_index, case_count) New
-       variables. 
-       (output_record) Returns success.  Now really writes to the output
-       file.
-       (begin_run, end_run) New functions.
-       (write_initial_runs) Returns success.  Initializes run_no to -1.
-       Calls begin_run(), end_run() at appropriate times.  Outputs debug
-       messages.
-       (write_to_sort_cases) Calls begin_run(), end_run() at appropriate
-       times.
-       (merge) New function.
-
-       * heap.c, heap.h: New files.  Hopefully in near-final form.
-
-Sat Dec 21 21:51:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       * glob.c: Added write_active_file to global vars.
-
-       * sort.c: Several new miscellaneous static variables.
-       (cmd_sort_cases) Big comment fix.
-       (perform_case_2) Renamed `do_external_sort' and completely
-       rewritten.
-       (case_2_proc_func) Removed.
-       (output_record, write_initial_runs, write_to_sort_cases,
-       compare_record) New functions.
-
-       * vfm.c: [DEBUGGING] (index_to_varname) Excised bit rot.
-
-Tue Dec 17 18:57:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: (perform_case_2) Changed the method for allocation of
-       lots of memory--now allocates one case at a time in hopes that
-       more cases can be allocated with heavily fragmented memory.
-
-       * var.h: (write_active_file) New global var.
-
-       * vfm.c: (procedure, close_active_file, write_case,
-       SPLIT_FILE_procfunc) Now allow beginfunc, procfunc, and endfunc
-       arguments to procedure() to be NULL.  All references to
-       procedure() that made use of dummy functions were changed to NULL
-       functions.
-       (open_active_file) If write_active_file is non-NULL, the output
-       device becomes DEV_PGM (a new enum).
-       (close_active_file) Sets write_active_file to NULL.
-       (read_from_memory) Comment fix.
-       (record_case) Calls write_active_file() when the output device is
-       DEV_PGM.
-
-Sun Dec 15 15:32:16 1996  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c: New file.
-
-       * autorecode.c: (cmd_autorecode) Fixed parsing of options.
-       Fixed checking for duplicate varnames.
-       (recode) xmalloc()'s the transformation instead of arena_alloc()'ing
-       it.
-       (autorecode_trns_free) Destroys hash tables for each recoding
-       specification.
-       (autorecode_proc_func) Compares NULL to *vpp instead of vpp.
-
-       * command.c: Added SORT CASES to cmd_table.
-       (null_func, null_int_func) Prototyped.
-
-       * descript.g: (calc_weight, calc_noweight) Computes own case
-       number now.
-       
-       * frequencies.q: (dump_statistics) Fixed problem with
-       too-few-cases warning message.
-
-       * get.c: (cmd_save_internal) Handles weighting properly.
-
-       * hash.c: (hsh_dump) Output format changed.
-       (force_hsh_insert) Actually works now, prototype changed.
-
-       * list.q: (static var case_num) New variable.
-       (cmd_list) Initializes case_num.
-       (list_cases) Increments case_num.
-
-       * var.h: Added definitions for SORT CASES.  Comment fixes.
-
-       * vfm.c: Some definitions moved to new file vfmP.h.  Comment
-       fixes.  `active' renamed vfm_active, `rep' renamed
-       vfm_replacement, all references changed.
-       (procedure) The procfunc no longer receives a case number.  All
-       references changed.
-       (write_case) Subtle reordering.
-       (SPLIT_FILE_procfunc) Counts cases differently.  Slightly less
-       redundant.
-
-       * weight.c: (get_weighting_variable) New function.
-
-       * vfmP.h: New file with definitions from vfm.c.
-
-Sat Dec 14 10:35:30 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (FILE_TYPE_okay) Commented out some tests because
-       they're clumsy and not yet needed.
-
-       * var.h: Most *_trns structures moved to their respective source
-       files.  Some were moved into a new file, do-ifP.h.  Comment fixes.
-       (union any_trns) Changed to a typedef for trns_header.
-       (struct input_program_pgm) Removed.
-
-       * vars-prs.c: (parse_variables) Only local_free()'s bits if it
-       was allocated in the first place.
-
-Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.c: New file.
-       
-       * command.c: Added AUTORECODE to command table; re-enabled SET.
-
-       * data-out.c: (convert_F) Handles infinities and NaNs properly.
-
-       * error.c: (vmsg) Comment fixes.
-
-       * hash.c: Comment fix.
-       (hashpjw_d) New function.
-       (hashpjw) Reimplemented as call to more general function
-       hashpjw_d().
-       (internal_comparison_fn) Initializes pointers properly.
-       (hsh_sort) [GLOBAL_DEBUGGING] New debugging code.
-       (force_hsh_insert, force_hsh_find) New debugging wrapper
-       functions.
-
-       * main.c: (main) Message fix.
-
-       * output.c: (outp_read_devices) Message fix.
-
-       * set.q: Comment fixes.
-       (custom_results) Implemented Wnd/X form of subcommand.
-       (set_routing) New function.
-       (internal_cmd_set) Implemented ERRORS, MESSAGES.
-
-       * settings.h: (SET_ROUTE_*) New enum series.
-       (set_results) Renamed set_results_file, all references changed.
-       (set_messages) Removed.
-       (glob vars set_errors, set_messages, set_results) New vars.
-
-       * title.c: (get_title) Remembers to xstrdup() the result of
-       get_rest_of_line().
-
-       * var.h: (arc_item, arc_spec, autorecode_trns) New structures for
-       use by AUTORECODE.
-       (union any_trns) New element `arc'.
-
-Fri Dec  6 23:53:47 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (output_line) Removed references to set_screen.
-
-       * error.c: (static var terminating) New var.
-       (hcf) Sets terminating to 1.
-       (vmsg) If terminating is nonzero, does not attempt to call hcf().
-       This prevents an infinite loop if an error occurs within hcf().
-
-       * expr-evl.c: (evaluate_expression) [__CHECKER__] Replaced case
-       statement circumlocution with `case 42000' trick.
-       (evaluate_expression) New support for OP_STR_MIS.
-
-       * expr-opt.c: (evaluate_expression) [__CHECKER__] Replaced case
-       statement circumlocution with `case 42000' trick.
-       (dump_node) Handles OP_STR_MIS.
-
-       * expr-prs.c: (MISSING_func, SYSMIS_func) Rewrote to handle string
-       variables exceptions.
-       (parse_function) Message fix.
-       (ops[]) Added OP_STR_MIS.
-
-       * expr.h: Added OP_STR_MIS to OP_* enum.  Comment fixes.
-
-       * exprP.h: [__CHECKER__] Removed case statement circumlocution.
-
-       * glob.c: Removed set_scrnfile glob var.
-       (init_glob) set_errorbreak set to 0 by default.
-
-       * groff-font.c: Changed included files.
-       (groff_read_font) Initializes font_arena local var correctly.
-       (default_font) New function.
-
-       * output.c: Comment fixes.
-       (glob var disabled_devices) New variable.
-       [GLOBAL_DEBUGGING] (static var iterating_driver_list) New
-       variable.
-       [GLOBAL_DEBUGGING] (reentrancy) New function.
-       [GLOBAL_DEBUGGING] (outp_read_devices, outp_done, find_driver,
-       outp_iterate_enabled_drivers) Calls to reentrancy().
-       (destroy_list) New function.
-       (outp_done) Moved code to destroy_list().
-       (parse_options) Parses `listing', `screen', `printer' options
-       internally.
-       (configure_driver) Sets new `device' member of driver.
-       (outp_iterate_enabled_drivers, outp_enable_device) New functions.
-
-       * output.h: Comment fixes.  New enum series OUTP_DEV_*.
-       (struct outp_driver_struct) New member `device'.
-
-       * postscript.c: (find_encoding_file) Doesn't display its own error
-       messages.
-       (default_encoding) New function.
-       (switch_font) Calls default_encoding() if no encoding can be
-       found.
-       (text) Makes up a character metric if none exists for the desired
-       character.
-       (load_font) Properly copies a fallback filename.  Calls
-       default_font() for a font if none at all are known.
-
-       * set.q: Comment fixes.  Removed OUTPUT subcommand.
-       (custom_listing) Calls outp_enable_device() to enable/disable
-       listing device.
-       (turn_screen_on) Removed.
-       (internal_cmd_set) Calls outp_enable_device() to enable/disable
-       screen, printer devices.
-
-       * settings.h: Comment fixes.
-       (glob vars set_output, set_printer, set_screen, set_scrnfile)
-       Removed.
-
-       * som-high.c: (som_submit_table, som_eject_page) Use
-       outp_iterate_enabled_drivers() instead of iterating
-       outp_driver_list directly.
-
-Wed Dec  4 21:34:17 1996  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: (parse_EDATE, parse_SDATE) New functions.
-       (parse_string_as_format) Handles new formats.
-       (parse_numeric) Now handles DOT and PCT formats.
-
-       * data-out.c: (convert_E, convert_F, insert_commas) Handle DOT
-       format now.
-       (convert_date) Handle EDATE and SDATE formats.
-       (convert_CCx) Now if there's not room for the currency characters,
-       converts it as F format if it's positive instead of giving up
-       quickly.  Also fixed save-and-restore bug with decimal point
-       characters.  
-       (convert_format_to_string) Handles new formats.
-
-       * misc.c: (formats[]) Added new formats.
-       (convert_fmt_ItoO) Supports new formats.
-
-       * sfm-read.c: (parse_format_spec) Supports new formats.  Better
-       data checking.  New argument, all references changed.
-
-       * sfm-write.c: (write_format_spec) Supports new formats.
-
-       * var.h: New formats FMT_DOT, FMT_PCT, FMT_EDATE, FMT_SDATE.
-       Comment fixes.
-
-Sun Dec  1 17:19:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: Comment fixes.
-       (parse_command_line) Changed return type to void.
-
-       * data-in.c: (parse_string_as_format) Added FMT_CCA...FMT_CCE to
-       switch.
-       (parse_numeric) Handles international numbers (comma as decimal
-       point).  Some reformatting.
-
-       * data-list.c: (parse_free) Default output format is now
-       set_format instead of hard-coded F8.2.
-       (read_from_data_list_list) Emits error message on undefined data
-       only if set_undefined is nonzero.
-
-       * data-out.c: (convert_E) Changes decimal point from period to
-       comma if appropriate.  Restructured.  Better comments.
-       (convert_F) Changes decimal point from period to comma if
-       appropriate.
-       (insert_commas) Major bug with handling of negative values fixed.
-       Also, inserts periods instead of commas if appropriate.
-       (convert_CCx) New function.
-       (convert_format_to_string) Added FMT_CCA...FMT_CCE to switch.
-       (num_to_string) Changed `.' to set_decimal.
-
-       * dfm.c: Comment fixes.
-       (dfm_close) Frees ext->line even in inline_file.
-       (open_inline_file) New function.
-       (open_file_r) When opening the inline file: now properly
-       recognizes `BEGIN DATA.' line, and calls open_inline_file() to
-       finish up.
-       (read_record) Calls fh_close_handle() instead of dfm_close() to
-       close the inline file.  Makes a copy of the line getl_buf to avoid
-       interlock problems.
-       (dfm_get_record) Restructured.  Now checks the return value of
-       open_file_r().
-       (cmd_begin_data) Moved open code into open_inline_file().  Relaxed
-       checking for use of inline file.  No longer tries to close inline
-       file.
-
-       * error.c: (glob var error_already_flagged) New var.
-       (vmsg) Message change.  Now checks max number of errors/warnings,
-       acts on it.
-
-       * file-handle.q: (fh_handle_name) Now allows closing of
-       inline_file.
-       (fh_init_files) Reformatted.
-
-       * get.c: (trim_dictionary) Checks SCOMP option instead of COMP.
-
-       * getline.c: (getl_include) Fixed bug that popped up when called
-       when file queue was empty.
-       (read_console) Resets error_count, warning_count,
-       error_already_flagged to zero.
-
-       * glob.c: Many changes to update list of variables.
-       (init_compat_dependent) Now this function is called whenever
-       `compat' changes.  It now sets set_seed only if it hasn't
-       previously been referenced.  It now calls
-       lex_init_compat_dependent().
-
-       * include.c: (cmd_include_at) Frees temporary buffer instead of
-       line buffer.  
-       (cmd_include) Doesn't make copy of include file name.
-
-       * lexer.c: Comment fixes.
-       (init_lex) Moved some code into new function
-       lex_init_compat_dependent().
-       (lex_init_compat_dependent) New function.
-       (hex_val) Simplified.
-       (preprocess_line) Uses set_endcmd instead of hardcoding `.'.
-
-       * main.c: Comment fixes.
-       (main) Reformatted.
-
-       * misc.c: (formats[]) Added FMT_CCA...FMT_CCE.
-       (check_input_specifier) Disallows FMT_CCA...FMT_CCE.
-       (convert_fmt_ItoO) Detects FMT_CCA...FMT_CCE.
-       (setup_randomize) Sets set_seed_used.
-
-       * set.q: Comment fixes.
-       (custom_results) Conditionalizes on `compat'.
-       (custom_log) Calls custom_journal().
-       (set_ccx) New function.
-       (cmd_set) Calls init_compat_dependent() when `compat' changes.
-       Calls set_ccx() to handle CCA...CCE.  Sets set_grouping
-       when set_decimal changes.  Range-checks values for MITERATE,
-       MNEST.  Message fixes.
-
-       * settings.h: Comment fixes.
-       (struct set_cust_currency) New struct.
-       (set_cc[], set_grouping, set_seed_used) New global vars.
-
-       * var.h: (FMT_CCA...FMT_CCE) New output formats.
-       (FCAT_OUTPUT_ONLY) New FCAT_* constant.
-
-Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
-
-       * glob.c: Revised variables to correspond to settings.h.
-       (init_glob) Initializes variables from settings.h properly.
-
-       * set.q: Began long-overdue major revision to correspond to new
-       philosophy.  Most code changed. 
-
-       * settings.h: Mostly changed; reorganized, reordered, large new
-       comment.
-
-Thu Nov 28 19:46:10 1996  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (cmd_save_internal) No longer forces compression off.
-
-       * sfm-read.c: (read_compressed_data) If eof is reached when
-       reading a new instruction octet, only signal error if we're in the
-       middle of a case.
-
-       * sfm-write.c: (COMPRESSION_BIAS) New #define.
-       (struct sfm_fhuser_ext) New member `end'.
-       (write_header) Refers to COMPRESSION_BIAS instead of magic 100.0.
-       (ensure_buf_space) New function.
-       (sfm_write_case) Reimplemented in order to support compression.
-       (sfm_close) Writes out the remaining contents of the compression
-       buffer if any.
-
-Wed Nov 27 23:18:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Defined SAVE and XSAVE commands in command table.
-
-       * common.h: second_lowest_value is of type flt64, not double.
-
-       * file-handle.h: Comment fix.
-
-       * get.c: Comment fixes.
-       (static var `trns') New.
-       (save_write_case_func, save_trns_proc, save_trns_free, null_func,
-       cmd_save_internal, cmd_save, cmd_xsave) New functions.
-       (dict_delete_run) Clears the variables and frees them now.
-       (trim_dictionary) Sets default for compression.
-       On KEEP subcommand, frees deleted variables as well as clearing
-       them.  Finally got the sense of the test for deleting all
-       variables correct.
-       [DEBUGGING] (dump_dict_variables) Message fix.
-
-       * glob.c: (init_glob) set_compression set to 1 by default.
-
-       * list.q: Properly #includes config.h.
-
-       * misc.h: New macro REM_RND_UP.
-
-       * settings.h: Comment fix.
-
-       * sfm-read.c: (structs sysfile_header, sysfile_format,
-       sysfile_variable; inline function bswap_int32) Moved to new file
-       sfmP.h.
-       (corrupt_msg) [__CHECKER__] No longer induces segfault.
-       (sfm_read_dictionary) Fixed bug caused by failing to initialize
-       var_by_index.
-       (read_machine_flt64_info) Fixed some problems caused by confusion
-       between flt64 and double types.
-       (read_header) Message fix.
-       (read_variables) Fixed set of cases in which we byte-swap sv.print
-       and sv.write.  Fixed confusion of flt64 and double.
-
-       * sfm.h: (struct sfm_write_info) New.
-
-       * som-high.c: (som_draw_title) Properly frees `s'.
-
-       * temporary.c: (save_dictionary) Comment fix.
-
-       * var.h: Comment fixes.  New FMT_* enum, FMT_NUMBER_OF_FORMATS.
-       (struct trns_header) Formatting fix.
-       (struct save_trns) New.
-
-       * vars-atr.c: (discard_variables) Comment fix.
-
-       * sfm-write.c: New file, baseline release.
-
-       * sfmP.h: New file, baseline release.
-
-Sun Nov 24 14:53:53 1996  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: (parse_command_line) `--version' output updated.
-       (glob var syntax_message[]) Added my e-mail address.
-
-       * file-handle.q, lexer.c, vfm.c: Changed many instances of
-       `illegal' to `invalid'.
-
-       * sfm-read.c: (struct sfm_fhuser_ext) New fields used as
-       uncompression buffer.
-       (sfm_close) Frees decompression buffer.
-       (sfm_read_dictionary) Initializes decompression buffer.
-       (buffer_input, read_compressed_data) New functions.
-       (sfm_read_case) Restructured; now calls read_compressed_data() to
-       handle compressed system file data.
-
-       * var.h: Comment fix.
-
-Mon Nov 11 15:34:09 1996  Ben Pfaff  <blp@gnu.org>
-
-       * dfm.c: (dfm_close) Does not set h->{ext,class} because the
-       caller handles it.
-        
-       * get.c: New comments.  New static var `get_file'.
-       (cmd_get) Now fully implemented.  Calls discard_variables();
-       initializes fv and lv for all variables; new debug code; sets
-       up the dictionary; sets up the input program.
-       (read_from_get, cancel_get) New functions.
-
-       * sfm-read.c: Comment fixes.
-       (sfm_close) New static function.
-       (sfm_read_dictionary) Properly sets up the class of the
-       file_handle.  No longer cares what size the data is in records of
-       type 7.  Also, on failure, properly cleans up the file_handle and
-       free()s some stuff.
-       (read_variables) No longer thinks it knows `nval' of the
-       dictionary.  Now sets p.get.fv, etc., instead of speculatively
-       setting fv itself.
-       (read_value_labels) Fixed off-by-one error in indexing of
-       var_by_index[].
-       (sfm_read_case) New function.
-       (sfm_r_class) New static var.
-
-       * var.h: (get_proc) New struct.
-       (struct variable) New member p.get.
-
-Thu Nov  7 20:52:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Removed GTSV_OPT_MAP because of a misinterpretation of
-       the manual's meaning.
-       (rename_variables) New function.
-       (trim_variables) Doesn't try to parse MAP any more.  Removed debug
-       code.  Now properly reorders the dictionary on the KEEP keyword.
-
-       * sfm-read.c: (read_value_labels) Fixed some bugs regarding
-       garbage collection.
-
-       * vars-atr.c: (clear_variable) New argument `dictionary *'.
-       (rename_variable) New function.
-       (free_val_lab) Reformatted.
-
-Thu Nov  7 17:29:16 1996  Ben Pfaff  <blp@gnu.org>
-
-       * var.h: Reindented entire file.  Comment fixes.
-       (glob vars var, var_by_name, nvar, N, nval, n_splits, splits)
-       Removed.
-       (glob var default_dict) New.
-       (struct indirect_dictionary) Removed.
-
-       * Many other source files were changed to add `default_dict.'
-       before all references to the dictionary of the active file.
-       
-       * vars-atr.c: (make_indirect_dictionary) Removed.
-
-       * glob.c: Reindented all variable declarations.  Updated for
-       changed var.h.  Comment fixes.
-
-       * temporary.c: (restore_dictionary, save_dictionary) Simplified
-       because now we can mainly copy dictionary structs.
-
-       * vars-prs.c: (is_dict_varname, parse_dict_variable,
-       parse_variables) Takes dictionary instead of indirect_dictionary
-       first argument.
-       (parse_variables) Instead of calling make_indirect_dictionary,
-       just sets DICT to &default_dict if DICT is NULL.  Of course, lots
-       of `*dict.' references had to be changed to `dict->'.  Removed
-       debug code.
-
-Thu Nov  7 15:48:52 1996  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Added GTSV_OPT_* series of enums.
-       (trim_dictionary, dict_delete_run) New functions.
-       [DEBUGGING] (dump_dict_variables) New function.
-       (cmd_get) Calls trim_dictionary() to get dictionary fully set-up.
-       [DEBUGGING] Calls dump_dict_variables() to display results.
-
-       * glob.c: (cmp_variable) Now a public function declared in var.h.
-
-       * sfm-read.c: Turned off debug code.  Comment fixes.
-       (read_machine_int32_info, read_machine_flt64_info) New functions
-       to parse type 7 records.
-       (sfm_read_dictionary) Properly byteswaps several fields now.
-       Calls read_machine_*_info() to parse type 7 subtypes 3 and 4
-       records.  [DEBUGGING] Dumps dictionary.
-       (read_variables) Sets `index' field of variables created properly.
-       Constructs avl tree of variables in dictionary.  [DEBUGGING] No
-       longer dumps dictionary.
-       (read_value_labels) Properly byteswaps fields.  [DEBUGGING] New
-       debug code.
-       [DEBUGGING] (dump_dictionary) No longer stubbed out.
-
-       * temporary.c: (restore_dictionary) Destroys `var_by_name' glob
-       var before destroying any variables just to save a little time.
-
-       * var.h: (struct variable) Reordered in order to make name[] the
-       first member; this makes pointers to `variable' pointers to the
-       variable name, simplifying avl trees, etc.
-       (struct indirect_dictionary) New struct.
-
-       * vars-atr.c: (find_variable) Rewritten for efficiency.
-       (make_indirect_dictionary, is_dict_varname, parse_dict_variable)
-       New functions.
-       (is_varname) Rewritten for efficiency.
-       (parse_variables) New argument, which is a `dictionary *'.  All
-       references changed.  This function now reads variable names from
-       the dictionary passed, or from the default dictionary if NULL.
-
-Tue Nov  5 18:34:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * misc.h: Added new macro DIV_RND_UP to perform integer division,
-       rounding up.  Changed many references to ROUND_UP to use this
-       instead.
-
-       * sfm-read.c: Includes avl.h.
-       (corrupt_msg) Induces a segfault under Checker.
-       (macro assertive_bufread) New.  Many references to bufread() now
-       use this instead.
-       (sfm_read_dictionary) Split up into several functions.  Added code
-       to read dictionary records following the the type 2 records.  Not
-       quite complete.  New variable `var_by_index'.
-       (read_header, read_variables) New functions extracted from
-       sfm_read_dictionary().
-       (read_value_labels) New function.
-       (bufread) Checks ferror() if fread() doesn't return the expected
-       value; if ferror() is zero it's just EOF.
-       (dump_dictionary) Stubbed out.
-
-       * BTW: The source code now exceeds 50000 lines!
-       
-Mon Nov  4 22:03:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added GET to cmd_table[].
-
-       * list.q: Removed reference to alloca headers.
-       (cmd_list) Gave prototype.
-
-       * sfm-read.c: Added DEBUGGING comments.
-       (sfm_read_dictionary) Checks bias correctly.  Sets
-       dict->var_by_name to NULL.  Calculates long_string_count
-       correctly.  realloc's dict->var[] array to minimum size.
-       [DEBUGGING] Calls dump_dictionary.
-       [DEBUGGING] (dump_dictionary) New function.
-
-       * temporary.c: (save_dictionary) Sets var_by_name to NULL.
-       (restore_dictionary) If the dictionary contains a non-NULL
-       var_by_name, uses that instead of generating one.
-       (free_dictionary) Destroys var_by_name.
-
-       * var.h: (struct dictionary) Added field `var_by_name'.
-
-       * get.c: New file, not complete.
-
-Sun Nov  3 12:24:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * mis-val.c: New enums MV_NOR_*.  New struct num_or_range.
-       (parse_num_or_range) New function.
-       (parse_numeric) Reimplemented in order to support LOW THRU <n> and
-       <n> THRU HIGH missing values.
-
-       * output.h: [__GNUC__>1 && __OPTIMIZE__] (width, height) Made
-       __attribute__((const)).
-
-       * q2c.c: (get_token) Merged isdigit || isalpha into isalnum.
-
-       * sfm-read.c: Finished reference implementation.
-
-       * sfm.h: Includes var.h.
-
-       * var.h: Comment fixes.
-       (struct `variable') Reordered some fields.
-
-       * vars-atr.c: (is_num_user_missing) Added support for MISSING_*
-       constants added previously.
-
-Wed Oct 30 17:13:08 1996  Ben Pfaff  <blp@gnu.org>
-
-       * common.h: Comment fixes.  Added declaration of
-       `second_lowest_value' as variable or macro.  Made `compat_type',
-       `pgm_state_type' into anonymous enums.
-
-       * display.c: Comment fix.
-
-       * glob.c: [ENDIAN==UNKNOWN] Added definition for `endian' global
-       var.
-       [!defined SECOND_LOWEST_VALUE] Added definition for
-       `second_lowest_value' global var.
-       (compat, pgm_state global vars) Changed types to `int'.
-       (init_glob) Initializes `second_lowest_value'.
-
-       * sfm-read.c: Continued work, not complete.
-
-       * var.h: Added new MISSING_* constants to handle LOWEST and
-       HIGHEST.
-
-Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
-
-       * sfm-read.c: New file, not complete.
-
-       * cases.c: (vec_insert) Changed vector expansion algorithm.
-       (vec_delete) Fixed bug that screwed up deletion sometimes, it was
-       mucking up the RECODE transformation in particular.
-       (envector) Harmless change in notation.
-
-       dfm is now fairly well tested again.  
-       * dfm.c: (dfm_get_record) Only returns ext->ptr if ext is
-       non-NULL--duh.
-       (cmd_begin_data) if(ext->line) replaced by if(ext && ext->line).
-
-       * recode.c: Comment fix.
-
-       * sfm.h: Interface should be fairly final now, or at least for a
-       day or so...
-
-       * vfm.c: [DEBUGGING] (index_to_varname) New function.
-       (open_active_file) [DEBUGGING] Translates ccase indices into
-       variable names now to make it easier to understand what's really
-       going on.
-
-Sat Oct 26 20:46:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: Comment fix.
-
-       * data-list.c: Includes dfm.h.
-       (do_reading) Uses new function dfm_push_cust().
-
-       * data-out.c: (convert_time, convert_WKDAY, convert_MONTH) Added
-       `return 1;' at end.
-
-       * file-handle.h: Completely changed.  Some parts split off into
-       new file dfm.h.  Implemented in file-handle.q.
-       (enum FH_*) Removed.
-       (struct fh_ext_class) New struct.
-       (struct file_handle) Retained only these fields: name, norm_fn,
-       fn, recform, lrecl, mode.  New fields class, ext.
-       (get_handle_by_name, get_handle_by_filename, parse_file_handle,
-       close_handle, handle_name) Added `fh_' prefix to name, all
-       references changed.
-
-       * dfm.h: New file, implemented in dfm.c.
-       (get_record, put_record, fwd_record, bkwd_record, set_record,
-       get_cur_col) Functions moved from file-handle.h, now prefixed with
-       `dfm_'.
-       (dfm_push_cust) New function.
-
-       * sfm.h: New file.  Incomplete.
-
-       * dfm.c: All functions adjusted/rewritten for new dfm/fhp
-       interface.  Functions reordered, comments changed.  Not well
-       tested, probably full of bugs.
-       (struct dfm_fhuser_ext) New struct.
-       (dfm_close) New function.
-       (open_file_r) Pickier about finding `BEGIN DATA.' line.
-       (open_file_w) User messages changed.
-       (get_record) Comment fixed.
-       (read_record) Increments ext->ln even for inline_file.  Calls
-       dfm_close() for inline_file when `END DATA.' encountered.
-       (dfm_get_record) Experimental restructuring.
-       (dfm_push_cust) New function.
-       (cmd_begin_data) Detects whether the inline file was fully read by
-       checking whether it is still open; detects whether it was read at
-       all by checking whether the line number is greater than zero.
-
-       * file-handle.q: All functions adjust/rewritten for new dfm/fhp
-       interface.  Functions reordered, comments changed.  Not well
-       tested, probably full of bugs.
-       (init_file_handle) Removed initializers for obsolete fields, added
-       new fields.
-       (fh_close_handle) Much simpler, now mainly calls the class
-       function.
-       (fh_init_files) Renamed inline file internal filename.
-
-       * file-type.c: Includes dfm.h.
-       (read_from_file_type) Doesn't use dfm internal state anymore.
-
-       * inpt-pgm.c, print.c: Include dfm.h.
-
-       * recode.c: (internal_cmd_recode) Casts strlen() return value to
-       int in comparison with other int.
-
-       * som-high.c: (build_target) Fixed operator precedence problem in
-       if statement (& versus ==).
-
-Sat Oct 26 10:39:25 1996  Ben Pfaff  <blp@gnu.org>
-
-       * dfm.c: (read_record) Can now read fixed-length records; not
-       tested.
-       (put_record) Can now write fixed-length records; not tested.
-
-       * file-handle.h: FH_* defines changed to enums.  New enum series
-       FH_RF_*, FH_MD_*.
-       (struct file_handle) New members recform, lrecl, mode.
-
-       * file-handle.q: Parser changed.
-       (internal_cmd_file_handle) Added support for new /RECFORM, /MODE,
-       /LRECL subcommands.  These are compatible with Windows.
-       (init_file_handle) Initializes recform, mode fields.
-
-       * q2c.c: (get_line) When outputting `!' comment lines, now
-       increments the output file line number so that `#line' directives
-       are correct.
-       (make_identifier) New function that converts an arbitrary string
-       into a valid C identifier.
-       (dump_vars) Calls make_identifier() in two places in order to
-       suppress some errors for bad identifiers.
-       (make_match) Allows TRUE as synonym for YES and FALSE as synonym
-       for NO.  Allows numbers to be prefixed by underscores to make them
-       acceptable C identifiers but still to be parsed as numbers by the
-       Fiasco lexer.
-
-Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Re-enabled RECODE, SAMPLE, SELECT IF.
-       
-       * dfm.c: Comment fixes. (get_record) Gives error if file handle
-       was opened for writing.
-       (open_file_w) New function.
-       (read_record) Uses strncasecmp if available.  Improved error
-       messages, comments.
-       (put_record) New function.
-
-       * file-handle.h: Moved function comments into dfm.c and
-       file-handle.q.  Comment fixes.  Removed declarations of
-       tilde_expand() and normalize_filename().
-       (struct file_handle) Changed `open' from boolean to enumerated
-       field to allow for three states--closed, open for reading, open
-       for writing--all references changed.
-
-       * file-handle.q: Includes filename.h.
-
-       * print.c: (CMD_* enums) Renamed PRT_* and moved into var.h; all
-       references changed.
-       (alloc_line) Makes allowance for line terminator characters in
-       calculations.
-       (print_trns_proc) Now handles OUTFILE, WRITE differences.
-       (print_space_trns_proc) Handles OUTFILE differences.
-
-       * recode.c, sample.c: Comment fixes.
-
-       * var.h: (struct print_trns) Changed boolean field `eject' to
-       bitmapped field `options'; all references changed.  New enums
-       PRT_* for use with this field.
-
-       * exception.h, test-exception.c: Removed.
-
-Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (delineate) Turned off debug output.
-
-       * common.c: [Checker and Linux] (__assert_fail, __eprintf) Moved
-       to error.c.
-
-       * data-in.c: (parse_string_as_format) Sets the entire string value
-       to spaces, not just the short string part of it.  Is this correct
-       now? 
-
-       * data-out.c: (convert_date) Fixed DATETIME format problems with
-       decimal places, removed debug code.
-
-       * dfm.c: (open_file_r) Fixed bug where an error would occur in the
-       middle of parsing BEGIN DATA that would cause the lexer to read
-       from a wild pointer `prog'; now calls new function
-       preprocess_line() in lexer.c.
-
-       * error.c: [__CHECKER__] (hcf) Calls induce_segfault() on improper
-       termination.
-       [Checker and Linux] (__assert_fail, _eprintf) Moved from common.c.
-       Now call induce_segfault() to induce the segfault.
-       (induce_segfault) New function.
-
-       * expr-opt.c: Comment fix.
-       (parse_sysvar) New function.
-       (parse_primary) Added system variable support--calls
-       parse_sysvar().
-       (global var ops) Added OP_CASENUM operator.
-
-       * expr.h: Comment fixes.
-       (OP_* enum) added OP_CASENUM operator.
-       (struct casenum_node) New struct.
-       (union any_union_union) New member `cas' of type `casenum_node'.
-
-       * glob.c: (global var last_vfm_invocation) New var.
-       (init_glob) Initializes last_vfm_invocation.
-
-       * lexer.c: (lookahead) Fixed reversed condition on if statement.
-
-       * getline.c: (get_line) Split into get_line() and preprocess_line().
-       (preprocess_line) New function.
-
-       * var.h: Declares last_vfm_invocation.
-
-       * vfm.c: (procedure) Sets last_vfm_invocation.
-
-Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (parse_cmd) Fixed bad assertion related to
-       lookahead().
-
-       * data-in.c: (parse_month) Implemented to parse months according
-       to full interpretation of standard.
-       (to_roman) New function.
-       (parse_wk_delimiter) Bug fix (forgot to skip `WK' in string).
-       (parse_weekday) Bug fix (forgot to skip all the day name).
-
-       * data-list.c: (read_from_data_list_fixed) Fixed bug that screwed
-       up parsing of multirecord data items.  Also fixed user message.
-
-       * data-out.c: Comment fix.
-       (year2, year4, convert_date, convert_time, convert_WKDAY,
-       convert_MONTH) New functions to support time & date output.
-       (convert_format_to_string) Calls new time & date output routines.
-
-       * expr-prs.c: (nary_num_func) Found a bug, but didn't fix it yet.
-
-       * lexer.c: (lookahead) Noted a previously unnoticed caveat in
-       comment.
-
-       * main.c: [DEBUGGING] (dump_token) Updated to handle getline.h.
-
-       * misc.c: (global var formats) Fixed declarations of DATETIME,
-       TIME, DTIME.
-
-       * postscript.c: (text) Fixed a pair of bugs in the reallocation of
-       the output_char buffer.
-
-       * vars-prs.c: (parse_DATA_LIST_vars) Fixed a failure to free
-       memory bug.  Fixed user messages.
-
-Tue Oct 22 17:27:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Removed #pragma argsused from lots of places.
-       
-       * data-in.c: Implemented zoned decimal and time-date formats.
-       Untested.  This is a huge chunk of code--maybe 1000 lines and 50
-       new functions.
-
-       * data-out.c: Implemented zoned decimal format.
-
-       * expr.h: Moved yrmoda() declaration here from exprP.h.
-
-       * misc.c: (global var formats) Minor fixes--added
-       FCAT_SHIFT_DECIMAL to formats N and Z.
-       (convert_fmt_ItoO) Added support for format Z.
-
-       * som-frnt.c: (som_set_value) Fixed bug regarding string values.
-
-Mon Oct 21 20:39:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (parse_cmd) [GLOBAL_DEBUGGING] Inserted call to
-       som_check_workspace() that is activated between commands.
-
-       * data-list.c: (dump_fixed_table, dump_free_table) Finished these
-       for good, I hope.
-
-       * list.q: (begin_row) Changed title expansion style from
-       SOPT_X_VERT to SOPT_X_SHSP.
-
-       * som-frnt.c: Now includes `somP.h'.
-       (som_push_workspace, som_pop_workspace) New functions that, taken
-       together, form a solution to the recursive table building problem
-       mentioned yesterday.  Surrounded every table output routine
-       throughout the program with calls to these functions.
-       [GLOBAL_DEBUGGING] (som_check_workspace) New function.
-       (som_create_table) Checks that there's an active workspace.
-       (som_destroy_all_tables, som_crush) Removed.
-
-       * som-high.c: (global var som_preserve_tables) Removed, all
-       references deleted.
-       (som_submit_table) Checks that there's an active workspace.
-       (dump_columnated_table) Doesn't columnate tables that would have
-       just one row per column.
-       (dump_crush_page, som_dump_crush_page) Removed debugging code.
-       (som_dump_crush_page) Moved row number labels from left side of
-       tables to right side.
-       (som_get_table_size) Added support for SOPT_X_SHSP.
-
-       * som.h: New cell expansion type SOPT_X_SHSP.
-
-       * somP.h: (global vars arena_stack, n_arena_stack, m_arena_stack)
-       New vars.
-       (global var curtab_arena) Moved from som-frnt.c.
-
-Sun Oct 20 13:45:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: [GLOBAL_DEBUGGING] (SUPPRESS_WARNINGS) New debug option
-       that causes bad location warnings to be suppressed.
-       (delineate) Saves current font when calling draw_text(); fixed
-       handling of NULLs when backing up.  Also fixed line-wrapping bug.
-
-       * command.c: Re-enabled `LEAVE', `NUMERIC', `PRINT', `PRINT EJECT',
-       `PRINT FORMATS', `PRINT SPACE', `STRING', `TITLE', `WRITE'.
-
-       * common.c: Added code to cause assertion failure to dump core
-       when run under Checker.
-
-       * data-list.c: (dump_fixed_table) Fixed some inconsistencies, but
-       there are still bugs.
-
-       * glob.c: (__eprintf) Removed.
-
-       * list.q: Inserted som_preserve_tables kluge that prevents tables
-       from being thrown away due to recursive table building through
-       som_output_line being called from a transformation during the LIST
-       procedure invocation.  This is a general problem that must be
-       solved in a better way since it applies to all procedures in
-       general.
-       (begin_row) Changed title options to SOM_X_VERT from SOM_X_BOTH.
-       (flush_table) Removed SOM_TOPT_PRESERVE from submission options.
-
-       * numeric.c: Fixed several errors in the form of msg() calls.
-
-       * print.c: Updated for use of som.
-       (dump_table) Reimplemented.
-       (print_trns_proc) Calls som_eject_page() instead of eject_page().
-       Calls som_output_text() instead of outs_line().
-
-       * som-frnt.c: (som_destroy_all_tables) Sets som_preserve_tables to
-       0.
-       (som_output_text) Function moved from som-low.c.  Interface
-       changed.
-
-       * som-high.c: (som_preserve_tables) New global public variable
-       declared in som.h.
-       (som_submit_table) Destroys the tables only if som_preserve_tables
-       is 0.
-       (paginate_horizontally) Bugfix: sets som.mpw even if there's only
-       one subrow per row.  Now labels subrows if there's more than one
-       subrow per row.
-       (dump_crush_table) Added wishlist comment.
-       (som_eject_page) New public function declared in som.h.
-
-       * som-low.c: (som_dump_crush_page) Draws row labels if there's
-       more than one subrow per row.
-       (som_output_text) Moved to som-frnt.c.
-
-       * som.h: (SOM_TOPT_PRESERVE) Removed.
-
-       * title.c: (get_title) Changed interface.
-       (cmd_title) Changed `title' to `outp_title'.
-       (cmd_subtitle) Changed `subtitle' to `outp_subtitle'.
-
-Sun Oct 20 09:04:15 1996  Ben Pfaff  <blp@gnu.org>
-
-       * list.q: (flush_table) Conforms to new partial options in
-       som_submission_form.
-
-       * som-high.c: (paginate_horizontally) Changed form of subrow
-       number labels.
-       (build_target) Omits spacing before table if
-       SOM_TOPT_PARTIAL_OMIT_TOP is selected.
-       (dump_crush_page) Changed interface.  Only trims bottom rule if
-       SOM_TOPT_PARTIAL_OMIT_BTM is not selected.
-       (dump_crush_table) Handles partial tables.
-       (output_row_label) New function.
-       (som_dump_crush_page) Emits subrow number labels.  Draws vertical
-       rule on the right edge of narrow subrows.
-
-       * som.h: Changed SOM_SUB_PARTIAL_* series of submission type
-       constants to a series of SOM_TOPT_PARTIAL_* submission options.
-       All references updated.
-
-Fri Oct 18 19:46:49 1996  Ben Pfaff  <blp@gnu.org>
-
-       * misc.c: Comment fix.
-
-       * som-high.c: (examine_table) Treats crushed tables separates for
-       purpose of determining header size.
-       (paginate_horizontally) Allots space for line numbers in crushed
-       tables with lots of subrows per row.  Calculates the `maximum page
-       width', the width of the widest horizontal page.
-       (build_target) Removed trim argument; all references changed.
-       Stricter assertions.  (dump_crush_page) New function.
-       (dump_crush_table) Reimplemented.
-
-       * som-low.c: (som_dump_page) Uses new RULE_ROW &c. constants.
-       (som_dump_crush_page) Reimplemented, interface changed.
-
-       * somP.h: Many many new helper macros for use with crushed tables.
-       (global var som) Removed `tv', `cum_y' members; all references
-       removed.  New members `mpw', `digit_space'.
-
-Sun Sep 29 19:37:03 1996  Ben Pfaff  <blp@gnu.org>
-
-       * arena.c: (arena_alloc) [!DISCRETE_BLOCKS] Removed `size'
-       variable, changed to constant 1024.
-       (arena_ca_strdup) Changed `sizeof(a_string)' to
-       `sizeof(c_string)'.
-       (arena_ca_strdup) [!DISCRETE_BLOCKS] Changed bad cast from
-       `(c_string *)' to `(char *)'; this fixed some offset problems.
-
-       * filename.c: (readlink_malloc) Changed initial allocation from
-       100 bytes to 128.
-       (good_getcwd) Changed from xmalloc() to local_alloc(); removed
-       comment.
-
-       * postscript.c: (read_fontmap) Fixed leak by changing &owner to
-       &fm->owner in several places.
-
-       * som-high.c: (output_table) Changed interface to rest of world.
-       (examine_crush_table) Removed.  Crushed tables are re-broken now,
-       in preparation for rewrite.
-
-       * som.h: Comment fix.
-
-Sat Sep 28 21:28:07 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_init_driver) Disposes of x->file.filename and x
-       itself in the cleanup stage.
-
-       * descript.q: (display) At least temporarily, changed the table
-       format to a crushed table.
-
-       * list.q: (begin_row) At least temporarily, added horizontal lines
-       between cases.
-
-       * som-high.c: (examine_crush_table) Sets som.hh to the width of
-       the horizontal "headers," that is, to the width of the far left
-       and far right rules.
-       (justify_pagination) Sets som.th to the width of the widest row
-       in the crushed table.  Fixed inner loop off-by-one error.
-
-       * som-low.c: (som_dump_crush_page) Added code to draw horizontal
-       rules.
-
-       * somP.h: Comment fix.
-
-Fri Sep 27 20:08:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * filename.c: (open_file_ext) Now, doesn't set f->file to NULL
-       before closing it; also, opens the constructed filename `s'
-       instead of f->filename.
-
-       * postscript.c: Moved initialization of x->loaded, x->prop,
-       x->fixed, x->current, also the add_encoding() calls, into
-       postopen().
-       (preclose) Destroys x->combos; sets x->loaded, x->combos to NULL;
-       sets x->last_font to NULL; sets x->next_combo to zero.
-
-       * som-high.c: (crushed_row_height) Moved definition farther up.
-       (som_submit_table) Doesn't calculate line width, font size until
-       after calling open_page(), to accomodate changes to PostScript
-       driver.
-       (vert_headers) Removed; equivalent functionality moved to
-       examine_table(), examine_crush_table().
-       (justify_pagination) Replaced with different algorithm.
-       (dump_crush_table) Bugfix that caused tables to fail to be clipped
-       at the bottom of the page.
-
-Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Added cmd_list back into cmd_table.
-
-       * freq.c, frequencies.q, repeat.c, list.q, vars-atr.c, vfm.c:
-       Comment fix: `#define DEBUGGING' --> `#define DEBUGGING 1'.
-
-       * list.q: (flush_table) Updated to new som_submission_form format.
-
-       * som-frnt.c: Comment fix.
-
-       * som-high.c: Changed `#endif' to `#undef EXTERN'.
-       (output_table) Calls som_get_table_size() directly; handles
-       crushed tables.
-       (examine_crush_table) New function; calls vert_headers().
-       (examine_table) Moved some code into new function, vert_headers().
-       (justify_pagination) New function.
-       (dump_plain_table) Removed `static' from `cy'.
-       (dump_crush_table) New function.
-
-       * som-low.c: (som_dump_crush_page) New function.
-
-       * som.h: Comment fixes.
-       (enum SOM_TOPT_CRUSH) New.
-       (SOM_SUB_PARTIAL_BEG, SOM_SUB_PARTIAL_MID, SOM_SUB_PARTIAL_END)
-       Temporarily set to zero to make do with LIST procedure.
-
-       * somP.h: Re-ordering.
-
-Wed Sep 25 19:36:11 1996  Ben Pfaff  <blp@gnu.org>
-
-       * som.c: Split into som-frnt.c, som-high.c, som-low.c.
-
-       * somP.h: New file for use by som-high.c, som-low.c.
-
-       * q2c.c: Added definition for VME.
-       (get_line) Now dumps `!' comment lines to the output file
-       verbatim.
-
-       * crosstabs.q, descript.q, file-handle.q, frequencies.q, list.q,
-       set.q: Changed format of `!' comment lines.
-
-Tue Sep 24 18:39:09 1996  Ben Pfaff  <blp@gnu.org>
-
-       * All source files: Added copyright notice.
-
-       * common.c: (xmalloc, xrealloc, xstrdup) Cast size_t's to unsigned
-       longs in msg() calls.
-
-       * con32s.c: (xmalloc, xrealloc) Updated from common.c.
-
-       * q2c.c: (xmalloc, xrealloc, xstrdup) Updated from common.c.
-
-Sat Sep 21 23:16:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * output.c: (outp_read_devices) Changed criteria for
-       distinguishing different types of lines.
-
-Fri Sep 20 22:52:28 1996  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: Changed syntax message.
-
-       * filename.c: (good_getcwd) Bug fix (?).
-       (normalize_filename) [__BORLANDC__] Uses _fullpath() library
-       function.
-       (search_path) Appends DIR_SEPARATOR to directory name only if it
-       does not already end with one.
-
-       * glob.c: Checks STAT_PAGER envvar before PAGER.
-
-       * output.c: Checks environment variables instead of just local
-       macros.
-
-Tue Sep 10 21:39:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * arena.c: (arena_destroy) Swatted a subtle bug that cropped up
-       when the pointer passed to the function was within the arena
-       itself, so that it couldn't properly be set to NULL _after the
-       arena was freed_.
-
-       * command.c: Re-enabled DISPLAY.
-
-       * display.c: Rewritten to handle tables.  Untested.
-
-       * filename.c: (search_path) Fixed memory leak.
-
-       * frequencies.q: (cmd_frequencies) Frees v_variables.
-       (postcalc) Calls cleanup_freq_tab() after displaying statistics.
-       (cleanup_freq_tab) New function to garbage collect.
-       (dump_full) Elegantized.
-
-       * main.c: New comment.
-
-       * output.h: New tag for tagged quotes: TAG_NEWLINE.
-
-       * postscript.c: Comment fix.
-       (release_fontmap, free_font_entry) New functions.
-       (ps_init_driver) Sets free_font_entry() as the freefunc for
-       hashtable `loaded'.  Calls release_fontmap() when destroying a
-       driver; also frees the output filename; also frees the
-       ps_driver_ext block.
-       (free_ps_encoding) Frees the filename as well as the encoding
-       block.
-       (output_encodings) Frees the line buffer and pops the msg-filename
-       stack.
-       (read_fontmap) Frees the fontmap filename and the line buffer.
-       (postopen, preclose) Misc. garbage collection fixes.
-       (ps_open_page) Destroys the `combos' hash table; sets `last_font'
-       to NULL; this fixes some output problems.
-       (text) Handles TAG_NEWLINE.  Untested.
-
-       * som.c: (cell_byte_size) Merged SCON_VALUE and SCON_TEXT cases.
-       (som_set_string) Removed.  All references changed to
-       `som_set_text'.
-       (som_set_text) Rewritten.  New interface.  More general.
-
-       * som.h: Minor format changes.
-       (struct som_value_cell) Removed; all references changed to
-       `som_text_cell'.
-       (enums SOT_*) Changed.
-
-Mon Sep  9 21:43:13 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: Re-enabled SPLIT FILE.
-
-       * postscript.c: Comment fix.
-
-       * som.h: Added `SOT_NONE'.
-
-       * split-file.h: (cmd_split_file) Removed superfluous parenthesis.
-
-       * vfm.c: (dump_splits) Reimplemented.
-
-Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Compiled the project under gcc 2.7.2, which gave some new
-       warnings.  This led to many additions of casts from unsigned to
-       int sprinkled throughout the code.
-       
-       * arena.c: Many uses of `unsigned' changed to `size_t'.
-
-       * command.c: Added END FILE, END REPEAT to command table.
-       (var cmd_end_repeat) Renamed cmd_end_repeat_p.
-       (find_command, FILE_TYPE_okay) Not commented out anymore.
-       (parse_cmd) Calls FILE_TYPE_okay again.
-       (output_line) Added calls to som_output_text() to put the line
-       in the output files.
-
-       * common.c: (macro VME) Format changes.
-       (xstrdup) Asserts that its argument is not NULL.
-       
-       * data-list.c: Implemented dump_fixed_table().
-       
-       * inpt-pgm.c: Formatting changes.  Comment changes.
-       (end_case_proc) Renamed end_case_trns_proc.
-       (cmd_end_file, end_file_trns_proc) New functions.
-
-       * misc.c: Many uses of `int' and `unsigned' changed to `size_t'.
-
-       * misc.h: (local_strdup) New macro corresponding to strdup() but
-       allocating its data through local_alloc() if possible--that is, if
-       GNU C is in use.
-
-       * postscript.c: Comment changes.
-       (quote_ps_name, quote_ps_string, output_encodings) New functions.
-       (output_line, add_string) New macros supporting
-       output_encodings().
-       (postopen) Fixed contents of ${fixed-font} and ${prop-font}
-       substitution vars.  Calls output_encodings() when a line
-       consisting of `!encodings' is encountered.
-       (preclose) Some code moved into quote_ps_string().
-       (dump_line) Changed into macro supporting dump_fancy_line().
-       (switch_font) Now outputs DSC "%%IncludeResource: font (...)"
-       command when appropriate.
-       (write_text) Fixed `literal_char' array (I think it's fixed, at
-       least.)
-       (text) Fixed bug when width was zero.  Now exits immediately on
-       zero height_left.  Now, when executing `goto restart;', checks
-       that cp<end, so that we don't read beyond end-of-string.  Also,
-       outputs the correct code to the output file by outputting the code
-       from the metric instead of the internal metric index.
-
-       * repeat.c: (cmd_end_repeat) New function.
-
-       * som.c: (var som) `headers' renamed `options' and semantics
-       changed.  All references changed.
-       (draw_title) `if(px!=-1 || px!=-1)' --> `if(px!=-1 || py!=-1)'.
-       (build_target) Only inserts spacing if SOM_TOPT_SPACING not
-       selected.
-       (som_text_table) Removed.
-       (som_output_text) New function.
-
-       * som.h: (struct som_submission_form) Removed `header', `reuse',
-       replaced with bitmapped field `options'.
-       (SOM_TOPT_*) New enum set for som_submission_form.options.
-       (SOT_*) New enum set for som_output_text().
-
-       * temporary.c: (copy_variable) When copying the var label, only
-       calls xstrdup() if it's non-NULL.
-
-       * var.h: (enum type `vartype') Removed; all references changed to
-       `int'.
-
-       * vars-atr.c: (init_variable) Changed local var `nbytes' from
-       `int' to `size_t'.
-
-Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
-
-       * font.h: Comment changes.
-
-       * groff-font.c: (groff_read_font) Initializes `name' field to
-       NULL.  Handles `encoding' field.
-
-       * hash.c: (hsh_dump) [GLOBAL_DEBUGGING] Output formatting changes.
-
-       * postscript.c: (struct font_entry) Removed `position' field.
-       (struct ps_font_combo) New struct.
-       (struct ps_driver_ext) Removed field `next_position'.  New fields
-       `combos', `next_combo'.  `last_font' field changed from
-       `font_entry *' to `ps_font_combo *'.
-       (ps_init_driver) Reformatted; handles new fields.  When
-       OPO_AUTO_ENCODE is set, adds the two default fonts' encodings to
-       the encoding list.
-       (get_encoding, find_encoding_file) New functions.
-       (add_encoding) Some code moved out into find_encoding_file().
-       (postopen) Changed value for ${title}.
-       (preclose) Sets `loaded' field to NULL after destroying the hash
-       table.
-       (ps_open_page) Added comment.  Inits the `combos' and `next_combo'
-       fields.
-       (ps_text_set_font_by_position) Figures out the current family if
-       not known.
-       (compare_ps_combo, hash_ps_combo, free_ps_combo) New functions.
-       (switch_font) Implemented.
-       (write_text) Calls switch_font() more often.  Format changes.
-       #undefs its macros after they're no longer useful.
-       (text) Changed `continue' at one point to a jump to the top of the
-       loop because we don't want `separate' reset to 0 at that point.
-       (load_font) No longer sets `position' in the font_entry created.
-
-Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * font.h: (struct font_desc) New member `encoding', which is not
-       properly handled yet.
-
-       * glob.c: (init_glob) Some new i18n code, which is probably
-       screwed up.
-
-       * output.c: (outp_read_devices, outp_get_paper_size) Changed
-       `size' local from `int' to `size_t'.
-
-       * postscript.c: New driver configuration parameter `auto-encode'.
-       New enums OPO_AUTO_ENCODE, ODA_COUNT.
-       (struct font_entry) New member `position'.
-       (struct ps_driver_ext) Reordered.  New hash table member
-       `encodings'; new members `next_position', `next_encoding',
-       `last_font'.  Members `current', `prop', `fixed' changed from type
-       `font_desc *' to `font_entry *'; all references changed.
-       (struct ps_encoding) New struct.
-       (read_ps_encodings, compare_ps_encoding, hash_ps_encoding,
-       free_ps_encoding, add_encoding) New functions.
-       (ps_init_driver) Added OPO_AUTO_ENCODE to default
-       x->output_options.  Initializes new members of ps_driver_ext.
-       Changed default value for prologue_fn, encoding_fn.  Calls
-       read_ps_encodings after loading default fonts.
-       (option_tab[], ps_option) Handle new configuration parameter.
-       (switch_font) New function.
-       (struct output_char) `font' member changed from `font_desc *' to
-       `font_entry *'.  New member `separate'.
-       (read_fontmap) Changed `size' from `int' to `size_t'.
-       (output_line, put_number) New macros for write_text().
-       (write_text) Optimizes text output by consolidating multiple
-       calls to PostScript `show' operator.
-       (text) Keeps track of when text arguments can't be consolidated by
-       write_text(), and marks those spots in the output stream.
-       (load_font) Sets `position' of the allocated font_entry to -1, cuz
-       the font hasn't been switched to by switch_font(), which is where
-       the position is important--the PostScript is what cares about the
-       position.
-
-Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * hash.c: (hsh_destroy) Ignores NULL argument.  Doesn't try to
-       call a NULL free_func.
-       (hsh_rehash) Elegantized.
-       (hsh_probe) Fix bug that manifested when the table was expanded
-       and thus had to change location in memory.  Good thing
-       too--otherwise could have been much more subtle.
-       (hsh_find) [GLOBAL_DEBUGGING] Not stubbed out anymore.
-       (hsh_foreach) New function for hash table iteration.
-
-       * hash.h: (struct hsh_iterator) New.
-
-       * lexer.c: (parse_tagged_quote) Font and family name strings in
-       tags are now null-terminated.
-
-       * output.c: (outp_evaluate_dimension) Fixed over-aggressive unit
-       parsing.
-       (internal_get_paper_size, outp_get_paper_size) Fixed; now work as
-       documented.  (Never before tested?)
-
-       * output.h: Comment changes.
-
-       * postscript.c: New driver options `optimize-text-size',
-       `optimize-line-size', `max-fonts-simult'.  New enum set for
-       specing cached line types.  Comment fixes.
-       (struct line_form) New struct.
-       (struct ps_driver_struct) New members `text_opt', `line_opt',
-       `max_fonts', `lines'.
-       (ps_init_driver) Initializes new members of ps_driver_struct.
-       (user option type enum set) New member `nonneg_int_arg'.
-       (static var option_tab[]) Supports new options.
-       (ps_option) Handles new options.
-       (find_ps_file) Made static.  No longer calls hsh_dump().
-       (ps_get_var) Made static.
-       (preclose) Dumps out proper DSC trailer.
-       (ps_open_page) Elegantized.
-       (ps_close_page) Calls dump_lines() if appropriate.
-       (ps_line_horz, ps_line_vert, ps_line_intersection) Reduced to
-       wrappers around line().
-       (int_2_compare, compare_line, dump_line, dump_fancy_line,
-       dump_lines, hash_line, free_line, line) New functions for support
-       of line caching.
-       (write_text, text) Made static.
-       (text) Added to font support, not finished.
-
-Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
-
-       * font.h: (struct font_desc) New members ascent, descent.
-
-       * groff-font.c: (groff_read_font) Calculates font ascent and
-       descent from the ascent and descent of the `d' and `p' characters,
-       respectively, as per a suggestion on comp.fonts.
-
-       * postscript.c: (ps_open_page, ps_close_page, ps_line_horz,
-       ps_line_vert, ps_line_intersection) Rewritten to deal with changed
-       prologue.
-       (write_text) Handles text right-justification and centering (not
-       full justification).  Still very inefficient.  (One output line
-       per character?!)
-       (struct output_char) Added fields for font and font size.
-       (text) Many bugfixes.
-
-Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * cmdline.c: (usage) Calls outp_list_classes().
-
-       * font.h: Comment fix.
-
-       * groff-font.c: New exported global var `space_index'.
-       (groff_init) New function to initialize `space_index'.
-       (hash_kern) Casts result to unsigned.
-       (font_name_to_index) Renamed font_char_name_to_index.  All
-       references changed.  Also, now returns the value of `space_index'
-       when passed an ASCII space character as an argument.  Fixed
-       handling of nulls.
-       (font_get_kern_adjust) Changed i from `int' to `unsigned'.
-       Handles passed NULL pointers properly.
-
-       * lexer.c: (parse_tagged_quote) Comment fix.  Better range
-       checking.
-
-       * output.c: (outp_list_drivers) Removed.  Removed all references.
-       
-       * output.h: Comment fixes.
-
-       * postscript.c: (ps_open_global) Calls groff_init().
-       (output_char) New structure.
-       (write_text) New function.
-       (text) No longer stubbed out!  Now the output is correct--with a
-       few exceptions, one of them being that the page has to be held
-       upside down into a mirror.
-
-Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
-
-       * font.h: Comment fix.
-       
-       * font.c: (name_to_index) Renamed font_name_to_index, made extern.
-       All callers changed.
-       (number_to_index) Renamed font_number_to_index, made extern.  All
-       callers changed.
-       (font_get_kern_adjust, font_get_char_metrics) New functions.
-
-       * output.h: New constant OUTP_T_INTERNAL_DRAW.
-
-       * postscript.c: Changed default line width back to 1/2 point.
-       (ps_line_horz, ps_line_vert, ps_line_intersection) Now lines are
-       in the center of the space allotted for them, not just a fixed
-       offset from the edge of the space; this fixes some bugs.
-       (ps_line_intersection) Now supports all command line styles.
-       (ps_text_get_size) Bug fix in computation of em width.
-       (text) New function, the meat behind ps_text_metrics and
-       ps_text_draw.  Not complete.
-       (ps_text_metrics, ps_text_draw) Removed the stub taken from
-       ascii.c; call text().
-
-Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
-
-       * arena.c: (arena_free) Assert that the argument is non-NULL.
-       
-       * groff-font.c: (add_kern) Calls arena_free() for old_kern if and
-       only if old_kern is non-NULL.
-
-       * postscript.c: (ps_init_driver) Changed default line width to 1
-       point.
-       (postopen) New prologue variables.
-       (ps_line_horz, ps_line_vert, ps_line_intersection) Implements some
-       more of the common line styles properly, but not all.
-       (ps_text_metrics) Fixed problem with this stubbed out version that
-       kept it from taking font sizes into account.
-
-Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
-
-       * arena.c: (arena_malloc) Bug fix.
-       (arena_dump) [GLOBAL_DEBUGGING] New function.
-
-       * ascii.c: Comment fix.
-       (count_fancy_chars, delineate) Now static functions.
-       
-       * filename.c: (interp_vars) Bug fixes.
-
-       * font.h: Comment fixes.
-
-       * glob.c: (init_glob) Sets set_viewwidth, set_viewlength at
-       beginning in case we have an error message to display before
-       initializing the display.
-
-       * groff-font.c: Comment fix.  Changed rehash threshold from 2/3
-       full to 1/2 full.
-       (groff_read_font) Bug fixes.
-       (name_to_index) Increments hash.used.  Sets `name' field of hash
-       entry properly.
-       (add_kern) Sets kern_max_used after rehashing.  Other bug fixes.
-
-       * hash.c: Return type changed.
-
-       * postscript.c: Continued development.  Now marks lines on the
-       paper, but very buggy.
-
-Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Changed comments in many source files from `/* xxx /* yyy */' to
-       `/* xxx */ /* yyy */' for cleanliness.
-
-       * arena.c: (arena_sd_strdup) New function.
-       
-       * ascii.c: (struct ascii_driver_ext) New member `file'.
-       (ascii_init_driver) Fills out member `file' for initing; uses
-       close_file_ext for closing drivers.
-       (ascii_option) Changed %.*s back to %s because the a_string's are
-       always null-terminated.
-       (postopen, preclose) New functions.
-       (ascii_open_page) Uses new style of open_file_ext.
-       (ascii_option, commit_line_buf, output_lines) Use ext->file.file
-       instead of this->output.
-       (__assert_fail) Removed.
-
-       * cmdline.c: Changed syntax_message[].
-
-       * error.c: #include's <readline/history.h> only if the history
-       library is available, not if just the readline library is
-       available.
-
-       * filename.c: (expand_line) Removed alloca() support.
-       (interp_vars) No longer tilde-expands argument.  Limit on output
-       length removed.
-       (tilde_expand) Now treats argument as path rather than filename.
-       [!unix] Now is a no-op function.
-       (search_path) Better verbose message formatting.
-       (open_file, close_file) Comment fixes.
-       (close_file) [!unix] Doesn't bother with pipes.
-       (open_file_ext) Completely rewritten, interface revamped.
-       (close_file_ext) New function.
-
-       * font.h: Comment changes.
-
-       * frequencies.q: Removed AIX alloca support since it doesn't use
-       alloca.
-
-       * hash.c: Comment changes & additions.
-       (hsh_create) Initializes entire table instead of first M entries.
-       (hsh_probe) Stupid bug fixed.  Now it works.
-       (hsh_dump) [GLOBAL_DEBUGGING] New function.
-
-       * main.c: (parse) Detects EOF properly in token-eating loop.
-       Should the STOP token have its value changed to 0?
-
-       * misc.c: (blp_getdelim) [HAVE_GETDELIM] Now it's a macro.
-       (blp_getline) Now it's a macro.
-
-       * output.h: (struct outp_driver) Removed members output, filename.
-       
-       * output.c: (outp_init) [!NO_POSTSCRIPT] Installs PostScript
-       drivers in driver table.
-       (outp_read_devices) Frees buf.  Warns if there are no active
-       output drivers.
-       (outp_configure_clear) Sets outp_configure_vec to NULL after
-       deleting its elements.
-       (configure_driver, destroy_driver) Removed references to output,
-       filename members of outp_driver.
-       (outp_evaluate_dimension, internal_get_paper_size,
-       outp_get_paper_size) New functions.
-
-       * postscript.c: Continued development.  Now links but doesn't make
-       any marks on the page.  Lotsa bugs I suppose.
-
-       * str.c: (strcasecmp) [!HAVE_STRCASECMP] New function.
-
-       * str.h: Comment changes.
-
-Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Removed dependencies on non-nested comments in several files.
-       Also removed references to (unix || __unix__) in #if's since
-       prefh.orig makes those two equivalent.
-       
-       * ascii.c: (ascii_open_global) Creates ascii_arena.
-       (ascii_close_global) Destroys ascii_arena.
-       (ascii_init_driver) Doesn't create ascii_arena.
-       (ascii_copy_driver) Removed.
-       (ascii_option) Possible bugfix regarding %s vs. %.*s with a_string's.
-       (outp_class ascii_class) Removed ascii_copy_driver reference.
-
-       * frequencies.q: Now can display all statistics except median.
-       Still not finished.
-
-       * output.c: Handles outp_class.ref_count so output class
-       destructors are called properly.
-       (add_class) Sets ref_count to 0.
-       (configure_driver) Initializes class if ref_count++ is 0.
-       (destroy_driver) Destructs class if --ref_count is 0.  Frees the
-       class output file name.
-       
-       * output.h: (struct outp_class) Removed copy_driver, inited.
-       Added ref_count.
-
-       * postscript.c: Completely replaced but not finished.
-       
-Tue Jul 23 21:48:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * approx.h: #includes <float.h>.
-
-       * arena.h, arena.c: Many functions changed to take an arena **
-       instead of an arena *, for consistency.  All callers changed.
-       (arena_alloc) Now creates a new arena if passed *A that is NULL.
-       (arena_destroy) Sets *A to NULL.
-       
-       * ascii.c: (delineate) Implements OUTP_T_VERT correctly.  Removed
-       assertion that `width' be positive.
-
-       * command.c: Removed #if's from cmd_table.
-       (walk_cmdtable_func) [0] New function (debug code).
-       (init_cmd_parser) [0] Dumps out cmd_table (debug code).
-       (parse_cmd) Doesn't return failure for unimplemented commands.
-
-       * common.h: (SYSMIS) Changed from DBL_MAX to -DBL_MAX.
-       (SYSCODE) New constant macro.
-
-       * descript.q: Checks for positive n_variables before performing
-       analysis.
-
-       * file-handle.q: (get_handle_by_filename) Bug fix: passes &f to
-       avl_find instead of &fp as arg 2.
-
-       * frequencies.g, frequencies.q: Continued updating; now compiles &
-       works again, but not complete.
-
-       * main.c: Changes to user messages.
-
-       * misc.c: (reverse) [0] New function.
-
-       * settings.h: Comment removed.  #includes "common.h".
-
-       * som.c: (som_set_null) New function.
-       (som_set_value, som_set_string, som_set_text) More detailing
-       assertions.
-       (som_set_float) Implemented function.
-       (dump_columnated_table) Bug fix regarding page breaks.
-       (draw_cell) Bug fix regarding text that spilled out of a cell.
-       (draw_intersection, draw_horz_rule, draw_vert_rule) No longer draw
-       null lines.
-       (get_cell_size) Support SCON_EMPTY cells.
-       (get_table_size) When calculating rules' widths and heights, mask
-       out SLIN_SPACING bit.  Added SOPT_X_HLTL support.
-       
-       * som.h: (som_any_cell) New option SOPT_X_HTLT.  Removed
-       SOPT_X_SHADE.
-       (struct som_submission_form) New member `header'; all users
-       changed.
-
-       * val-labs.c: (get_label) User messages changed.
-
-       * var.h: Changed FREQUENCIES structures.
-
-       * vars-atr.c: (is_num_user_missing, is_str_user_missing) Made
-       inline.
-       
-Fri Jul 19 19:11:13 1996  Ben Pfaff  <blp@gnu.org>
-
-       * approx.h: Definition of EPSILON now depends on system's
-       DBL_EPSILON.  Removed GNU C specific code.
-       (cmpapx) Renamed approx_compare.
-
-       * frequencies.g, frequencies.q: Continued updating; still doesn't
-       compile.
-
-       * groff-font.c: (name_to_index) Fix bug that kept it from
-       compiling.
-
-       * hash.c, hash.h: Completed work.
-
-       * var.h: Changes to freq_tab, frequencies_proc.
-       
-Wed Jul 17 21:23:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       New hashing code.
-       * hash.c, hash.h: New files.  Not completed.
-       * Makefile.am: Added hash.c to source file list.
-       * font.h: (struct font_desc) New member kern_size_p.
-       * groff-font.c: Uses hash.h.
-       (hashpjw) Moved to hash.c.
-       (next_prime_power) Rewrote, renamed hsh_next_prime, moved to
-       hash.c.
-       (static var hash) New member size_p.
-       * var.h: Includes hash.h.
-       (struct freq_tab) Changed AVL_TREE to hash_tab.
-
-       * vars-prs.c: Comment, formatting fixes.
-
-       * frequencies.g, frequencies.q: Continued updating.  Not yet
-       working.
-
-       * formats.c: Bug fix.
-
-Tue Jul 16 22:10:04 1996  Ben Pfaff  <blp@gnu.org>
-
-       Increasing parallelism between DESCRIPTIVES and FREQUENCIES.
-       * descript.g: Comment fixes.
-       * descript.q: Comment fixes.  Moved some declarations into var.h.
-       Made dsc_info a static table.  Updated FIXMEs.
-       (internal_cmd_descriptives) Beautified.
-       
-       * frequencies.q: Started updating into working order.
-       * frequencies.g: New file analogous to descript.g.
-       * var.h: Comment fixes.  Added structures for FREQUENCIES.
-       
-       * som.c: Removed vestiges of crushing and partial table support.
-
-Sun Jul 14 15:45:31 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Many more changes to som.c especially, but these will not be
-       documented as I have resolved to remove them.  This patchlevel is
-       being released solely so that I can fall back to it if I decide
-       that removing the changes is not a good idea.
-
-Sat Jul 13 09:58:44 1996  Ben Pfaff  <blp@gnu.org>
-
-       * som.c: (global var som) New member `cum_y'.
-       (build_target) Properly handles titles for partial tables.
-       (dump_partial_beg, dump_partial_mid, dump_partial_end)
-       Merged into single new function dump_partial().  Fixed problem
-       with titles on partial tables.
-       (dump_table) Calls dump_partial() for all parts of partial tables.
-       (dump_page) Criteria for drawing title changed.
-       
-Fri Jul 12 22:03:36 1996  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (cmd_table) Added LIST, WEIGHT.
-
-       * command.c: (cmd_remark) No longer frees `s' since it's not
-       dynamically allocated.
-       
-       * data-out.c: (convert_f) Now correctly handles the case where
-       abs(v->f)<1 but v->f rounds to a value of 1.00 given the specified
-       number of decimals.
-       (som_destroy_all_tables) Removed argument.  All callers changed.
-       (som_vline, som_hline) Argument validity checking corrected.
-       (som_set_value) Implemented half-heartedly.
-       (replicate_table) Copies tables piece-by-piece when using Checker.
-
-       * som.h: New line style SLIN_1THIN, currently equivalent to
-       SLIN_0.  New enum set SOM_SUB_*.
-       (struct som_submission_form) Removed `seq_no'.  Added `type'.
-       
-       * list.q: Newly working file; uses partial tables.
-       
-       * som.c: (som_reduce_table) Renamed som_set_table_height().
-       (som_crush) Removed argument `group'.
-       (global var som) Removed `nt', `seq_no'.  Added `type'.
-       (som_submit_table) Arguments changed.
-       (output_table) Removed partial table code.
-       (build_target) New arg; partial table support added.  All callers
-       changed.
-       (dump_plain_table) Removed partial table code.
-       (dump_partial_beg, dump_partial_mid, dump_partial_end) New functions.
-       (dump_table) Supports partial tables.
-       (dump_page) New argument to allow not drawing top and/or bottom
-       headers.  All callers changed.  Supports partial tables.
-
-Sat Jul  6 22:22:25 1996  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c: Changed `#include <approx.h>' to `#include
-       "approx.h".
-       (convert_F) Comment fix.  Now won't print `-.000', etc.
-
-       * descript.q: Now Z-scores work, although there appears to
-       be a bug (which might actually be in data-out.c:convert_F()).
-       (descriptives_trns_proc, descriptives_trns_free) New functions.
-       (run_z_pass) Implemented.
-       
-       * var.h: Comment fixes.
-       (dsc_z_score, descriptives_trns) New structs.
-       (descriptives_trns) Added to any_trns as `dsc'.
-
-       * error.c, error.h: New error class, IS (Installation Script
-       error), used in those instances where the error is in the
-       installation, but there is a script file or installation file that
-       can be usefully referred to.
-       
-       * output.c: Change many IE classes to IS classes.
-
-       * cases.c, command.c, common.c, crosstabs.q, expr-evl.c,
-       frequencies.q, list.q, vars-prs.c, vfm.c: Removed reference to
-       HAVE_MALLOC_H because Borland C++ alloca() is broken, so why
-       include the corresponding header?
-       
-       * glob.c: (init_glob) Don't malloc term_buffer under Checker.
-       Don't bail out if termcap can't be read.
-
-       * som.c: (som_destroy_table) Removed.
-       (som_reduce_table, som_destroy_all_tables) New functions.
-       (som_crush) New function, not implemented.
-       
-       * som.h: New table option STAB_CRUSH.  Comment fix.  New struct
-       som_submission_form.  Function prototypes revised.
-
-       Outputting huge tables (1000s of rows) a few rows at a time
-       is supported, though untested.  May even break everything.
-       Actually, the code doesn't even compile right now.
-       * som.c: (struct som) New fields htv, nt, seq_no.
-       (som_submit_table) Multiple arguments changed to a single
-       pointer to struct submission_form.  Only increments subtable_num
-       if seq_no is zero.  Only destroys table if it's not going to
-       be reused.
-       (replicate_table) New function.
-       (output_table) Comment fix.
-       (examine_table) Changed inline code to code calling
-       replicate_table().  Calculates htv.  Supports partial tables.
-       (draw_title) Removed comment.
-       (build_target) Only allows for title on first part of partial
-       tables.
-       (dump_plain_table) Only resets table chunk number on first part
-       of partial tables; FIXME: doesn't work quite right.  Supports
-       partial tables.
-       (dump_page) Titles only on first part of partial tables.
-
-Fri Jul  5 20:16:19 1996  Ben Pfaff  <blp@gnu.org>
-
-       * Thanks to an unreliable IDE hard drive, I have spent the last
-       day reconstructing my Debian GNU/Linux installation and redoing
-       the previous day's changes--somehow I managed to save every file
-       except for output.c and output.h.  So the following changes could
-       really be considered independent of the output.c, output.h changes
-       from Jul 4.
-
-       * output.h, output.c: Moved the outp_configure_vec global var,
-       outp_names struct, and enum set OUTP_S_* from output.h to output.c.
-       outp_configure_vec is now static.
-       
-Thu Jul  4 20:20:24 1996  Ben Pfaff  <blp@gnu.org>
-
-       * The entire philosophy behind configuration of the output drivers
-       changed.  Now there is a termcap-type configuration where drivers
-       to be read are determined beforehand, rather than parsing the
-       entire output init file and storing it in memory & deciding what
-       to actually use later.  Faster & more memory-efficient at the same
-       time, cool.
-       
-       * output.c: Comment fix.  Removed outp_init_drivers global var.
-       Removed all references to synonyms.  New structure outp_defn.  New
-       global vars outp_macros, outp_configure_vec.
-       (search_name, delete_name, add_name, check_configure_vec,
-       expand_name, find_defn_value) New static functions.
-       (outp_configure_clear, outp_configure_add, outp_configure_macro,
-       outp_read_devices) New extern functions.
-       (outp_init) Much functionality moved into outp_read_devices.
-       (outp_read_devices) Format of output init file changed; name of
-       file is `devices' rather than `output' to avoid Makefile
-       conflicts.
-       (outp_clear) Renamed outp_done.
-       (outp_list_classes) Bug fix, cleaned up.
-       (outp_list_drivers) Not implemented anymore.
-       (outp_configure_driver) Now a static function; simplified; now
-       interpolates macros; supports new structure.
-       (outp_enable_driver, match_synonym) Removed; all references
-       removed.
-       (find_driver) First argument removed.
-       
-       * output.h: Global var outp_init_drivers removed; new structure
-       outp_names; new enum set OUTP_S_*; new global var
-       outp_configure_vec; function prototypes for output.c exports
-       updated.
-       
-       * main.c: (main) Calls outp_read_devices() after parsing the
-       command line.
-       
-       * cmdline.c: (parse_command_line) New option -v --verbose;
-       --version changed to -V.  --device option changed syntax to just
-       take a single device name.  Accepts key=value declaration of
-       output init file macros.  Syntax message updated.
-
-       * filename.c: (expand_line) New function.
-       (interp_environ_vars) Renamed interp_vars; no longer uses
-       fixed-size buffer.
-       (blp_getenv) Allows $ARCH and $VER pseudo-environment-vars to be
-       overridden by real environment vars.
-       (search_path) Uses verbose_msg() instead of #ifdef'd printf().
-       * filename.h: interp_environ_vars() renamed interp_vars().
-       
-       * error.c, error.h: Added extern variable `verbosity', message
-       class MM.
-       
-       * error.c: (vmsg) Support message class MM.
-       (verbose_msg) New function.
-
-       * descript.q: (generate_z_varname) Bug fix in generation of
-       Z-score varnames.
-       (dump_z_table) Bug fix in column headers.
-       
-       * ascii.c: (ascii_init_driver) Changed minimum number of lines per
-       page from 29 to 15.  Don't set a default for ops[OPS_INIT,
-       OPS_DONE].  Writes the uninit string when the driver is closed.
-       (ascii_open_page) Write the init string before the first page.
-       (output_shorts) Form of main loop changed from `while' to `for'.
-       Bug fix with overstrikes: the character is printed *after* the
-       backspace.  Eliminated a lot of `& 0xff' modifiers.
-       (advance_to_left_margin) New function.
-       (return_carriage, output_lines) Handle left margin.
-
-Thu Jul  4 00:35:59 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: New option `carriage-return-style'.
-
-       * ascii.c: (count_fancy_chars) New function.
-       (delineate, text_metrics) Use new function; bug fixes regarding
-       rich text strings.
-       (text_draw) Bug fix with rich text.
-       (output_string, output_shorts) Reordered.
-       (output_shorts) Now handles boxchars and some overstrike font
-       changes.
-       (output_char, return_carriage) New functions.
-       (output_lines) Now handles overstriking and font changes properly;
-       some code moved to output_shorts.
-
-Tue Jul  2 22:13:23 1996  Ben Pfaff  <blp@gnu.org>
-
-       [GLOBAL_DEBUGGING]
-       * ascii.c: New member `debug' in ascii_driver_ext.
-       (ascii_init_driver, delineate) Uses new member.
-
-       Now you can set a vertical height on writing text.
-       * ascii.c: (delineate) Keeps track of vertical position.
-       (text_draw) No longer considers fully justified text an internal
-       error.
-       
-       * output.h: New flag OUTP_T_VERT; other OUTP_T_ values changed.
-
-       Tables' titles are drawn; they can have variable height.
-       * som.c: `som' struct has new member, title_height.
-       (draw_title) New argument.  Moved within file.  All caller
-       changed.
-       (build_target) New argument, amount of space needed for first row.
-       Calculates height of title, takes that into account.  All callers
-       changed.
-       (dump_plain_table, dump_columnated_table) Took calculation of y1,
-       y2 out of loop.
-       (dump_columnated_table) [GLOBAL_DEBUGGING] Debugging code
-       improved.
-       (dump_columnated_table) Organized for readability.
-       (dump_page) Makes use of som.title_height.
-
-       * som.c: Many comment bug fixes.
-
-       * descript.q: (try_name, generate_z_name) Bug fix regarding
-       generation of Z-score variable names.
-       * var.h: Removed num from descriptives_proc; all referents removed.
-
-Mon Jul  1 22:13:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c: (ascii_line_horz, ascii_line_vert,
-       ascii_line_intersection) Added debugging code.
-
-       Added a descriptive line above each table to describe it.
-       * command.c: (parse_cmd) Calls som_new_series.
-       
-       * som.c: New static vars table_num, subtable_num.  New `som'
-       member `title'.
-       (dump_page) New arguments.
-       (som_submit_table) Handle new variables.
-       
-       * som.c, som.h: (som_submit_table) New arguments.  All callers
-       changed.
-       (som_new_series) New function.
-       (build_target) Makes room for extra line.
-       (draw_title) New function.
-       (dump_page) Calls draw_title.  Bug fix: doesn't always set
-       som.ext->cp to 0.
-       
-       Columnation of tables support.
-       * som.h: Deleted fr, lr, ri from som_table.  Reorganized.
-       
-       * som.c: Deleted references to fr, lr, ri.
-       (som_columnate) Bux fix: sets group member of table.
-       (som_add_options) Function removed.
-       (dump_table) Split into three functions; extensively reworked.
-       
-       * descript.q: (dump_z_table) Better output table formatting; added
-       title support to correspond to som.h changes.
-       (display) Title support.
-
-       * output.h: Added OUTP_T_NONE.
-       
-Mon Jul  1 13:00:00 1996  Ben Pfaff  <blp@gnu.org>
-
-       * descript.q: Improved handling of Z scores; still not perfect.
-       
-       * output.h, ascii.c: Added hook for getting em width of current
-       font.
-       
-       * som.c: Uses new em-width hook.  Added debugging code to
-       several functions.
-       (som_columnate) New argument.
-       (som_add_options) Removed.
-
-Jun 29 17:40:47 1996  Ben Pfaff  <blp@gnu.org>
-
-       * som.h, som.c, output.c, output.h, ascii.c: Updated to work with
-       rules as a property of the table instead of as a property of the
-       cells.
-       
-       * ascii.c: Added `header' to table of options.
-       
-       * descript.q: Added even shorter statistic names; modified to work
-       with new som interface.
-       
-       * misc.c (blp_getdelim): Bug fix.
-       
-       * version.c: includes 'conf.h'.
-       
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/src/OChangeLog b/src/OChangeLog
new file mode 100644 (file)
index 0000000..bba2afa
--- /dev/null
@@ -0,0 +1,14204 @@
+2007-11-03 John Darrington <john@darrington.wattle.id.au>
+
+       * gnumeric-reader.c gnumeric-reader.h: New files.
+
+Thu May  4 21:47:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, move
+       procedure.c and procedure.h from src to src/data.  Update
+       makefiles and #includes accordingly.
+
+       * automake.mk: Remove special rule for src/procedure.o.
+
+       * procedure.c: Moved to src/data.
+
+       * procedure.h: Moved to src/data.
+
+Wed May  3 22:24:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * procedure.c: (global var vfm_source) Make static.  Changed
+       external references to use in_input_program(), proc_set_source(),
+       or proc_capture_output() instead.
+       (global var vfm_sink) Make static.  Changed external references to
+       use proc_set_sink() instead.
+       (global var default_dict) Move here from data/dictionary.c.
+       (static var permanent_trns_chain) New var.
+       (static var temp_dict) Renamed permanent_dict, updated references.
+       (static var temporary_trns_chain) New var.
+       (static var cur_trns_chain) New var.
+       (static var in_procedure) Removed.
+       (global var t_trns) Removed.
+       (global var n_trns) Removed.
+       (global var m_trns) Removed.
+       (global var f_trns) Removed.
+       (procedure) Even if there's "nothing to do" we need to clear
+       PROCESS IF, N OF CASES, vector state.  (This should be
+       abstracted.)
+       (multipass_callback) New function.
+       (multipass_procedure) New function.
+       (open_active_file) Add N OF CASES, FILTER, PROCESS IF
+       transformations.  Finalize transformations.  No need to call
+       ctl_stack_clear() anymore because finalizers will do that.
+       (write_case) Simplify and rewrite.
+       (execute_transformations) Removed.
+       (filter_case) Removed.
+       (close_active_file) Use proc_cancel_temporary_transformations().
+       No need to clear PROCESS IF, N OF CASES here anymore because
+       helpers do that.
+       (multipass_procedure_with_splits) Keep track of success.
+       (multipass_split_callback) Ditto.
+       (multipass_split_output) Ditto.
+       (discard_variables) No need to call ctl_stack_clear() anymore
+       because finalizers will do that.
+       (proc_capture_transformations) New function.
+       (add_transformation) Rewrite in terms of trns_chain_append().
+       (add_transformation_with_finalizer) New function.
+       (next_transformation) Rewrite in terms of trns_chain_next().
+       (proc_in_temporary_transformations) New function.
+       (proc_start_temporary_transformations) New function.
+       (proc_make_temporary_transformations_permanent) New function.
+       (proc_cancel_temporary_transformations) New function.
+       (cancel_transformations) Rename proc_cancel_all_transformations(),
+       rewrite in terms of trns_chain_destroy().
+       (proc_init) New function.
+       (proc_done) New function.
+       (proc_set_sink) New function.
+       (proc_set_source) New function.
+       (proc_has_source) New function.
+       (proc_capture_output) New function.
+       (add_case_limit_trns) New function.
+       (case_limit_trns_proc) New function.
+       (case_limit_trns_free) New function.
+       (add_filter_trns) New function.
+       (filter_trns_proc) New function.
+       (add_process_if_trns) New function.
+       (process_if_trns_proc) New function.
+       (process_if_trns_free) New function.
+
+Wed Apr 26 20:00:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c (create_trns_case): Fix inverted decision on whether
+       numeric values should be initialized to 0 or SYSMIS.
+
+Wed Apr 26 19:48:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, assert
+       that add_transformation() is not called during procedure
+       execution.  Thanks to John Darrington for the suggestion.
+       
+       * procedure.c: (static var in_procedure) New var.
+       (internal_procedure) Get rid of recursive_call local var and
+       logic.
+       (open_active_file) Set in_procedure and make sure it wasn't
+       already set.
+       (close_active_file) Reset in_procedure and make sure it was
+       already set.
+       (add_transformation) Make sure we're not in a procedure.
+
+Wed Apr 26 19:33:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, break
+       procedure.c into multiple files.
+       
+       * procedure.c (vfm_last_invocation): Rename
+       time_of_last_procedure().  Update all references.
+       (struct storage_stream_info) Move to data/storage-stream.c.
+       (storage_sink_open) Ditto.
+       (destroy_storage_stream_info) Ditto.
+       (storage_sink_write) Ditto.
+       (storage_sink_destroy) Ditto.
+       (storage_sink_make_source) Ditto.
+       (var storage_sink_class) Ditto.
+       (storage_source_count) Ditto.
+       (storage_source_read) Ditto.
+       (storage_source_destroy) Ditto.
+       (storage_source_class) Ditto.
+       (storage_source_get_casefile) Ditto.
+       (storage_source_create) Ditto.
+       (null_sink_class) Move to data/case-sink.c.
+       (create_case_source) Move to data/case-source.c.
+       (free_case_source) Ditto.
+       (case_source_is_class) Ditto.
+       (create_case_sink) Move to data/case-sink.c.
+       (free_case_sink) Ditto.
+
+       * procedure.h: (struct case_source) Move to data/case-source.h.
+       (struct case_source_class) Ditto.
+       (struct case_sink) Move to data/case-sink.h.
+       (struct case_sink_class) Ditto.
+
+Thu Apr 27 09:28:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * automake.mk: Removed explicit dependencies for message.o, since
+       that module no longer exists.
+
+Wed Apr 26 15:29:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start reforming procedure execution.  In this phase, get rid of
+       function prototypes for never-defined functions.
+       
+       * procedure.h: Get rid of function prototypes for never-defined
+       functions.
+
+Wed Apr 26 12:58:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       Improve the way we handle the various parsing "states".  Until now
+       we've hard-coded the state transitions in the command definition
+       file, but that's error-prone and, worse, it's redundant--we can
+       figure out what state we're in anyhow.  We can cleanly handle
+       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
+       
+       * procedure.c (case_source_is_complex): Removed.
+       (discard_variables) No need to set pgm_state anymore.
+
+Tue Apr 25 11:06:49 2006  Ben Pfaff  <blp@gnu.org>
+
+       Finish reforming error message support.  In this phase, move
+       message.c into libpspp.
+       
+       * message.c: Move to libpspp.
+
+Tue Apr 25 10:47:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * message.c: (var err_error_count) Renamed error_count and moved
+       to ui/terminal/msg-ui.c.
+       (var err_warning_count) Renamed warning_count and moved to
+       ui/terminal/msg-ui.c.
+       (err_check_count) Renamed check_msg_count() and moved to
+       ui/terminal/msg-ui.c.
+       (dump_message) Rewrote to take stream instead of function pointer
+       and moved to ui/terminal/msg-ui.c.
+       (msg_emit) Moved its guts to ui/terminal/msg-ui.c as handle_msg()
+       and rewrote to just pass message to callback.
+       
+       (var err_verbosity) Renamed "verbosity" and moved to
+       libpspp/verbose-msg.c.
+       (verbose_msg) Moved to libpspp/verbose-msg.c.
+       
+       (var err_already_flagged) Removed.
+       (puts_stdout) Removed.
+       
+       (var msg_handler) New static variable.
+       (msg_init) New function.
+       (msg_get_command_name) New function.
+       
+Mon Apr 24 17:40:08 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, rename
+       all the message functions and types to start with "msg", except
+       for the ones that will be moving to other modules anyway.
+
+       All references to the identifiers below were updated likewise.
+       
+       * message.c: (err_done) Renamed msg_done().
+       (err_push_file_locator) Renamed msg_push_msg_locator().
+       (err_pop_file_locator) Renamed msg_pop_msg_locator().
+       (err_location) Renamed msg_location().
+       (err_set_command_name) Renamed msg_set_command_name().
+
+Mon Apr 24 14:11:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       * message.c: Use exit.h from gnulib instead of checking for and
+       defining EXIT_SUCCESS and EXIT_FAILURE by hand.
+
+Sun Apr 23 22:00:23 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+
+       * message.c: (tmsg) Removed.
+       (msg) Use err_msg() instead of err_vmsg().  Format message
+       ourselves.
+       (err_vmsg) Renamed err_msg().  Changed interface, dropping message
+       and va_list args which are now in the error struct.
+               
+Sun Apr 23 20:35:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.
+
+       * message.c: Use linebreak module from gnulib instead of home-brew
+       line breaking.
+       (puts_stdout) Rewrote.
+       (dump_message) Rewrote.  Changed interface and updated all callers.
+       (compulsory_break) Removed.
+       (char_is_break) Removed.
+       (break_before) Removed.
+       (break_after) Removed.
+       (macro BREAK_LONG_WORD) Removed.
+
+Sun Apr 16 20:41:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we
+       divide the classification of messages along "category" and
+       "severity" axes.
+
+       * message.c: (err_vmsg) Rewrite to deal with categories and
+       severities in a straightforward manner instead of mixing them into
+       classes.
+       [0] (puts_stderr) Removed (dead code).
+       (msg) Changed first argument from `int' to `enum msg_class'.
+       (tmsg) Ditto.
+
+Sun Apr 16 18:53:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       GNU standards require "file name" instead of "filename" in
+       documentation.  It's nice for our code to follow the convention
+       too.
+
+       Basically did search and replace in the whole source tree.  Major
+       changes in function names or struct member names have their own
+       change log entries.
+
+Sun Apr 16 15:58:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we get
+       rid of VM() and the other msg() support for "verbosity", replacing
+       it by a new function verbose_msg().
+
+       * message.c: (verbose_msg) New function.
+       (err_vmsg) Remove support for verbosity levels.
+
+Sun Apr 16 11:46:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start reforming error message support.  In this phase, we get rid
+       of "installation errors" and change all uses of msg() in the
+       output drivers to uses of error() or error_at_line().
+
+       * message.c: (err_vmsg) Get rid of IE, IS support.
+
+Sat Mar 11 14:17:47 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk: Changed the pattern specific AM_CPPFLAGS to two target 
+         specific ones. Eventually there will be none at all.
+
+       * automake.mk: Moved the pspp binary to ui/terminal
+
+Sat Mar  4 12:59:08 2006  Ben Pfaff  <blp@gnu.org>
+
+       * In many source files, #include "compiler.h" to get GCC attribute
+       definitions.
+
+Sat Mar  4 12:28:09 2006  Ben Pfaff  <blp@gnu.org>
+
+       * In many source files, replace INT_DIGITS by
+       INT_STRLEN_BOUND(int) and include intprops.h.
+
+John Darrington:
+       
+       * Replaced '_' with '-' in most filenames.
+
+       * Renamed files as follows:
+               vfm.[ch] to procedure.[ch]
+               error.[ch] to message.[ch]
+               getl.[ch] to line-buffer.[ch]
+               mkfile.[ch] to make-file.[ch]
+               pfm-write.h to por-file-writer.h
+               pfm-write.c to por-file-writer.c
+               sfmP.h to sfm-private.h
+               lex-def.c to identifier.c
+               lex-def.h to identifier.h
+               sfm-read.c to sys-file-reader.c
+               sfm-read.h to sys-file-reader.h
+               sfm-write.h to sys-file-writer.h
+               sfm-write.c to sys-file-writer.c
+               chart.[ch] to chart-geometry.[ch]
+               val.h to value.h
+               var.h to variable.h
+               vars-atr.c to variable.c
+               ctl-stack.c to control-stack.c
+               ctl-stack.h to control-stack.h
+               dfm-read.c to data-reader.c
+               dfm-write.c to data-writer.c
+               dfm-write.h to data-writer.h
+               dfm-read.h to data-reader.h
+               apply-dict.c to apply-dictionary.c
+               mis-val.c to missing-values.c
+               sysfile-info.c to sys-file-info.c
+               modify-vars.c to modifiy-variables.c
+               rename-vars.c to rename-variables.c
+               val-labs.c to value-labels.c
+               var-display.c to variable-display.c
+               var-labs.c to variable-label.c
+               format-prs.c to format-parser.c
+               range-prs.c to range-parser.c
+               range-prs.h to range-parser.h
+               subclist.c to subcommand-list.c
+               subclist.h to subcommand-list.h
+               vars-prs.c to variable-parser.c
+               descript.c to descriptives.c
+               sort-prs.c to sort-criteria.c/sort-cases.c
+               sort-prs.h to sort-criteria.h
+               sel-if.c to select-if.c
+               algorithm.c to array.c
+               algorithm.h to array.h
+               bitvector.h to bit-vector.h
+               som.c to manager.c
+               som.h to manager.h
+               tab.h to table.h
+               tab.c to table.c
+               readln.c to read-line.c
+               readln.h to read-line.h
+               cmdline.c to command-line.c
+               cmdline.h to command-line.h
+
+
+Sat Feb 11 22:35:20 2006  Ben Pfaff  <blp@gnu.org>
+
+       General clean-ups and minor bug fixes.
+
+       * filename.h: Move DIR_SEPARATOR, PATH_SEPARATOR here from
+       pref.h.orig.
+
+       * lex-def.h: (macro CHAR_IS_ID1) Removed.  All references changed
+       to lex_is_id1().
+       (macro CHAR_IS_IDN) Removed.  All references changed to
+       lex_is_idn().
+       
+       * lex-def.c: (lex_is_id1) New function.
+       (lex_is_idn) New function.
+       (lex_skip_identifier) New function.
+       (lex_id_match_len) Return bool instead of int.
+       (lex_id_match) Ditto.
+
+       * command.c: (parse_command_name) Convert parsed words to
+       uppercase to make error messages easier to read.
+       (cmd_host) Fix return value.
+
+       * dfm-read.c: (read_inline_record) Use tokens to check for BEGIN
+       DATA, not specialized lexical analysis.
+
+       * print.c: (print_space_trns_proc) Count of lines should be `int',
+       otherwise we might never finish.
+       (print_space_trns_free) Close writer.
+
+       * lexer.c: (enum string_type) New enum.
+       (lex_get) Remove essentially unused local variable `cp'.
+       Use enum string_type values.  Use parse_id().
+       (parse_id) New function.
+       (lex_look_ahead) Recognize octal strings too.
+       (strip_comments) New function.
+       (lex_get_line) Rewrite.
+       (lex_preprocess_line) Removed.
+       (convert_numeric_string_to_char_string) Use enum string_type.
+       (parse_string) Ditto.
+
+       * autorecode.c: (recode) Clone correct number of bytes based on
+       source string width.
+
+Sat Feb 11 22:34:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reduce dependencies on getl, and of getl.
+
+       * data-in.c: (vdls_error) Don't output different message depending
+       on whether we're interactive.
+
+       * getl.h: (struct getl_line_list) Removed.
+       (struct getl_script) Removed.
+       (GETL_PRPT_*) Removed.
+       (GETL_MODE_*) Removed.
+       (GETL_PROMPT_FIRST, GETL_PROMPT_LATER, GETL_PROMPT_DATA,
+       GETL_PROMPT_CNT) New enums.
+
+       * settings.c: (static var prompt) Removed.
+       (static var cprompt) Removed.
+       (static var dprompt) Removed.
+       (settings_done) Don't initialize prompt, cprompt, dprompt.
+       (get_prompt) Removed.
+       (set_prompt) Removed.
+       (get_dprompt) Removed.
+       (set_dprompt) Removed.
+       (get_cprompt) Removed.
+       (set_cprompt) Removed.
+
+       * pfm-read.c: (corrupt_msg) Don't show filename and line number,
+       to get rid of getl_location().
+
+       * sfm-read.c: (corrupt_msg) Ditto.
+
+       * getl.c: (struct getl_source) New.
+       (static var cur_source) New.
+       (static var last_source) New.
+       (static var DO_REPEAT_level) Removed.
+       (global var getl_head) Removed.
+       (global var getl_tail) Removed.
+       (getl_initialize) Call init_prompts().
+       (getl_add_file) Removed.
+       (getl_include) Removed.
+       (getl_add_DO_REPEAT_file) Removed.
+       (getl_handle_line_buffer) Removed.
+       (getl_close_file) Removed.
+       (getl_close_all) Removed.
+       (getl_is_separate) Removed.
+       (getl_set_separate) Removed.
+       (getl_reading_script) Removed.
+       (append_source) New function.
+       (include_source) New function.
+       (create_source) New function.
+       (create_syntax_file_source) New function.
+       (create_filter_source) New function.
+       (create_function_source) New function.
+       (create_interactive_source) New function.
+       (getl_append_syntax_file) New function.
+       (getl_include_syntax_file) New function.
+       (getl_include_filter) New function.
+       (getl_include_function) New function.
+       (getl_append_interactive) New function.
+       (getl_abort_noninteractive) New function.
+       (getl_is_interactive) New function.
+       (close_source) New function.
+       (getl_location) Use new `cur_source' var.
+       (getl_uninitialize) Use close_source().  Call uninit_prompts().
+       (read_syntax_file) New function.
+       (read_line_from_source) New function.
+       (do_read_line) New function.
+       (getl_read_line) Rewrite.
+       (static var prompts) New.
+       (static var current_style) New.
+       (init_prompts) New function.
+       (uninit_prompts) New function.
+       (getl_get_prompt) New function.
+       (getl_set_prompt) New function.
+       (getl_set_prompt_style) New function.
+       (get_prompt) New function.
+
+       * command.c: Merge the EXIT (aka Q, aka QUIT) and FINISH commands,
+       and make EXIT undocumented.  EXIT was a PSPP extension that never
+       really entirely made sense.
+       (cmd_exit) Removed.
+       (cmd_finish) Return CMD_EOF unconditionally.
+       (cmd_clear_transformations) Drop requirement of interactivity.
+
+       * command.def: Merge the EXIT (aka Q, aka QUIT) and FINISH
+       commands.
+
+       * repeat.c: Major changes to match getl revision.
+       (struct line_list) New struct.
+       (enum repeat_entry_type) New.
+       (struct repeat_entry) Made `type' an enum repeat_entry_type.
+       (struct repeat_block) New.
+       (static var repeat_tab) Removed.
+       (static var count) Removed.
+       (static var line_buf_head) Removed.
+       (static var line_buf_tail) Removed.
+       (cmd_do_repeat) Rewritten.
+       (clean_up) Removed.
+       (append_record) Removed.
+       (recognize_keyword) New function.
+       (internal_cmd_do_repeat) Removed.
+       (parse_specification) New function.
+       (skip_indentor) New function.
+       (recognize_do_repeat) New function.
+       (recognize_end_repeat) New function.
+       (parse_lines) New function.
+       (create_vars) New function.
+       (parse_ids) Use enum repeat_entry_type.
+       (parse_strings) Ditto.
+       (find_DO_REPEAT_substitution) Renamed find_substitution(),
+       rewrote.
+       (perform_DO_REPEAT_substitutions) Renamed do_repeat_filter(),
+       rewrote.
+       (do_repeat_read) New function.
+       (do_repeat_close) New function.
+
+       * data-list.c: Don't need to keep track of eof from getl anymore,
+       because getl can tell us now.
+       (struct data_list_pgm) Removed `eof' member.
+       (cmd_data_list) Don't assign to `eof'.
+       (get_data_list_read_func) Renamed read_from_data_list(), changed
+       interface.
+       (read_from_data_list_fixed) Changed interface.
+       (read_from_data_list_free) Changed interface.
+       (read_from_data_list_list) Changed interface.
+       (data_list_trns_proc) Rewrote based on dfm_eof() and
+       dfm_reader_error().
+       (data_list_source_read) Check for dfm reader errors.
+
+       * dfm-read.c: (enum dfm_reader_flags) Removed DFM_EOF in favor of
+       new `eof_cnt' member in struct dfm_reader.
+       (struct dfm_reader) New `eof_cnt' member.
+       (dfm_close_reader) Check `eof_cnt', not DFM_EOF.
+       (dfm_open_reader) Initialize `eof_cnt'.
+       (read_inline_record) Set prompt style with
+       getl_set_prompt_style().  
+       (read_record) Rewrite.
+       (cmd_begin_data) Set prompt style with getl_set_prompt_style().
+
+       * include.c: (cmd_include) Use getl_include_syntax_file().
+
+       * set.q: (cmd_set) Use getl_set_prompt().
+
+       * html.c: (postopen) Remove "source-file" expansion variable, to
+       avoid use of getl_location().
+
+       * postscript.c: (postopen) Remove "source-file" expansion
+       variable, to avoid use of getl_location().
+
+       * cmdline.c: (parse_command_line) Drop -c command line option,
+       because it wasn't very useful.  -i command line option now calls
+       getl_append_interactive().  Use new getl function interfaces.
+       Drop support for clearing dictionary between syntax files and thus
+       the "+" command line syntax.
+       (static var pre_syntax_message) Remove description of now-gone -c
+       option.  Remove "+" command line syntax.
+
+       * main.c: (main) Only call handle_error() if the return value is
+       an error.
+       (execute_command) Use getl_set_prompt_style().  Drop support for
+       clearing dictionary between syntax files.
+       (handle_error) Handle CMD_CASCADING_FAILURE.  Don't call err_break().
+
+       * readln.c: Drop lots of #ifdefs.  Now that the Autoconf tests are
+       pickier, we can just use HAVE_READLINE.
+       (static var welcomed) Move into welcome().
+       (welcome) Make `welcomed' a local static var.  Check for and read
+       history file here.
+       (global var getl_mode) Removed.
+       (global var getl_interactive) Removed.
+       (global var getl_prompt) Removed.
+       (getl_read_line) removed.
+       (readln_read) New function.
+       (read_console) Removed.
+       
+
+Sat Feb 11 22:16:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       Try to reduce some of the nastier dependencies on the error
+       module, and at the same time make PSPP nicer to deal with, by
+       getting rid of fatal errors.  All the existing calls to msg (FE,
+       ...) or err_cond_fail() or err_failure() have been replaced by
+       propagating an error upward to the command-dispatch layer.
+       Unfortunately this propagation took a fair bit of extra mechanism,
+       because now a lot of functions can fail that couldn't before.
+
+       New command return value CMD_CASCADING_FAILURE which indicates to
+       the command processor that syntax file processing should be
+       abandoned.  Many commands were modified to return
+       CMD_CASCADING_FAILURE.  When this modification was trivial it
+       isn't mentioned in detail below.
+
+       Transformation procedures (trns_proc_func) and free functions
+       (trns_free_func) now have a `bool' return type, which is normally
+       true, but false when an I/O or other serious error occurs.  All
+       transformation functions were modified to have this return type.
+       When this modification was trivial it isn't mentioned in detail
+       below.
+
+       * pspp-error.h: (FE) Removed this error class.
+
+       * error.c: (err_failure) Removed.
+       (err_cond_fail) Removed.
+       (err_break) Removed (it was unused).
+       (err_check_count) Don't cause a fatal error--instead, stop reading
+       the syntax file.
+       (err_vmsg) Don't have FE anymore, so no need to call terminate().
+
+       * any-reader.c: (any_reader_error) New function.
+
+       * any-writer.c: (any_writer_write) Propagate
+       scratch_writer_write_case()'s new return value.
+       (any_writer_error) New function.
+       (any_writer_close) Propagate underlying function's new return
+       value.
+
+       * casefile.c: Add an "error state" to a casefile.  A casefile that
+       encounters an I/O error enters the error state, and afterward
+       reading and writing cases fails.
+       (struct casefile) Add `ok' member.
+       (casefile_create) Set `ok' to true.
+       (casefile_destroy) Use io_error().
+       (casefile_error) New function.
+       (casefile_sleep) Now returns bool to indicate success.
+       (casefile_append) Ditto.
+       (casefile_append_xfer) Ditto.
+       (casefile_to_disk) Ditto.
+       (write_case_to_disk) Don't do anything in error state.
+       (flush_buffer) Don't do anything in error state.  Use io_error().
+       (reader_open_file) Ditto.
+       (fill_buffer) Ditto.
+       (casereader_read) Don't do anything in error state.  Handle
+       errors.
+       (casereader_read_xfer_assert) Removed, because now an I/O error
+       can occur even if the caller knows a case exists.
+       (io_error) New function.
+
+       * mkfile.c: (make_temp_file) Make failure non-fatal.
+       (make_unique_file_stream) Ditto.
+
+       * pfm-read.c: Add an error state.
+       (struct pfm_reader) Add `ok' member to indicate error state.
+       (error) Set `ok' to false.
+       (pfm_open_reader) Set `ok' to true.  Make failure non-fatal.
+       (pfm_read_case) Don't do anything in error state.
+       (pfm_read_error) New function.
+
+       * pfm-write.c: Postpone most error checking in favor of checking
+       ferror() afterward.
+       (pfm_open_writer) Make failure non-fatal.  Check for write error
+       after writing header.
+       (buf_write) Don't do anything if error has occurred.  Postpone
+       error checking.  Change return type to void.
+       (write_float) Postpone error checking.  Change return type to
+       void.
+       (write_int) Ditto.
+       (write_string) Ditto.
+       (write_header) Ditto.
+       (write_version_data) Ditto.
+       (write_format) Ditto.
+       (write_value) Ditto.
+       (write_variables) Ditto.
+       (write_value_labels) Ditto.
+       (pfm_write_case) Don't do anything if error has occurred.
+       (pfm_write_error) New function.
+       (pfm_close_writer) Change return type to bool.  Return false if an
+       I/O error occurred.
+
+       * scratch-reader.c: (scratch_reader_error) New function.
+
+       * scratch-writer.c: (scratch_writer_write_case) Change return type
+       to bool.  Propagate casefile error return.
+       (scratch_writer_error) New function.
+       (scratch_writer_close) Change return type to bool.  Propagate
+       casefile error return.
+
+       * sfm-read.c: Add an error state.
+       (struct sfm_reader) Add `ok' member.
+       (sfm_open_reader) Initialize `ok'.  Make errors non-fatal.
+       (buf_read) Set `ok' to false on error.
+       (buffer_input) Do nothing in error state.  Set `ok' to false on
+       error.
+       (read_compressed_data) Set `ok' false on error.
+       (sfm_read_case) Return false in error state.
+       (fread_ok) Set `ok' false on error.
+       (sfm_read_error) New function.
+
+       * sfm-write.c: Postpone most error checking in favor of checking
+       ferror() afterward.
+       (sfm_open_writer) Make failure non-fatal.  Check for write error
+       after writing header.
+       (write_header) Postpone error checking.  Change return type to
+       void.
+       (write_variable) Ditto.
+       (write_value_labels) Ditto.
+       (write_documents) Ditto.
+       (write_variable_display_parameters) Ditto.
+       (write_longvar_table) Ditto.
+       (write_rec_7_34) Ditto.
+       (buf_write) Ditto.
+       (ensure_buf_space) Ditto.
+       (sfm_write_case) Do nothing if write error has occurred.
+       (sfm_write_error) New function.
+       (pfm_close_writer) Change return type to bool.  Return false if an
+       I/O error occurred.
+
+       * var.h: Introduced a new return value for trns_proc_func that
+       means "a serious error has occurred, so abort the procedure
+       entirely".  Because the hard-coded values of -1, -2, etc. were
+       becoming even a worse idea now, also introduced some macros for
+       them: TRNS_CONTINUE, TRNS_DROP_CASE, TRNS_ERROR, TRNS_NEXT_CASE,
+       TRNS_END_FILE.  Also replaced all references to the hard-coded
+       values by uses of the macros.
+       
+       * command.h: New command return value CMD_CASCADING_FAILURE which
+       indicates to the command processor that syntax file processing
+       should be abandoned.
+
+       * dfm-read.c: (dfm_open_reader) Make failure non-fatal.
+       (dfm_reader_error) New function.
+       (read_inline_record) Make unexpected end of file nonfatal.
+       (read_file_record) Make read error nonfatal.
+       (dfm_eof) Make second unexpected end of file nonfatal.
+       (cmd_begin_data) Make errors nonfatal.  
+       
+       * dfm-write.c: (dfm_open_writer) Make failure non-fatal.
+       (dfm_write_error) New function.
+       (dfm_put_record) Do nothing in error state.  Now return error
+       state.
+       (dfm_close_reader) Now return `bool' indicating error state.
+
+       * file-type.c: (file_type_source_read) Now return `bool'
+       indicating error state.
+
+       * get.c: (case_reader_source_read) Now return `bool' indicating
+       write error.
+       (case_writer_destroy) Ditto.
+       (case_writer_write_case) Ditto.
+       (struct mtf_proc) New member `ok' indicating error state.
+       (cmd_match_files) Initialize and deal with `ok'.
+       (mtf_processing_finish) Now return `bool' indicating I/O error.
+       (mtf_free_file) Renamed mtf_close_file().  Now return `bool'
+       indicating I/O error.
+       (mtf_free) Now return `bool' indicating I/O error.
+       (mtf_delete_file_in_place) Ditto.
+       (mtf_read_nonactive_records) Ditto.
+       (mtf_processing) Ditto.
+
+       * inpt-pgm.c: (input_program_source_read) Now return `bool'
+       indicating I/O error.  Handle new TRNS_ERROR transformation return
+       value.
+
+       * matrix-data.c: Introduce error state.
+       (cmd_matrix_data) Check error return values.
+       (read_matrices_without_rowtype) Now return `bool' indicating I/O
+       error.
+       (matrix_data_read_without_rowtype) Ditto.
+       (dump_cell_content) Ditto.
+       (nr_output_data) Ditto.
+       (read_matrices_with_rowtype) Ditto.
+       (matrix_data_read_with_rowtype) Ditto.
+       (wr_output_data) Ditto.
+
+       * lexer.c: (lex_init) Make unexpected eof non-fatal.
+       (lex_get) Ditto.
+       (lex_look_ahead) Ditto.
+       (unexpected_eof) Removed.
+       (convert_numeric_string_to_char_string) Make unexpected eof
+       non-fatal.
+       (parse_string) Ditto.
+
+       * flip.c: Make I/O errors non-fatal.
+       (struct flip_pgm) Add `pool', `output_buf' members.
+       (cmd_flip) Create and use pool.  Propagate errors.
+       (destroy_flip_pgm) Rewrite, using pool.
+       (struct flip_sink_info) Removed.
+       (flip_sink_create) Use pool.  Make errors non-fatal.
+       (flip_sink_write) Make errors non-fatal.
+       (flip_file) Make errors non-fatal.  Make `bool' return type to
+       indicate failure.
+       (flip_sink_destroy) Remove.
+       (static var flip_sink_class) Use NULL as destroy func, not
+       flip_sink_destroy().
+
+       * sort.c: Make I/O errors non-fatal.  Propagate errors.
+       (sort_active_file_in_place) Propagate errors.
+       (sort_active_file_to_casefile) Ditto.
+       (do_internal_sort) Ditto.
+       (do_external_sort) Ditto.
+       (write_runs) Ditto.
+       (destroy_initial_run_state) Propagate errors via new `bool' return
+       type.
+       (merge) Propagate errors.
+       (merge_once) Ditto.
+
+       * output.c: [GLOBAL_DEBUGGING] Remove reentrancy detection,
+       because it used msg (FE, ...) and wasn't very useful.
+
+       * main.c: (handle_error) Handle CMD_CASCADING_FAILURE.
+
+       * vfm.c: (struct write_case_data) Change `proc_func' return type
+       to bool.
+       (procedure) Add `bool' return type to indicate I/O error.
+       Propagate errors.
+       (internal_procedure) Ditto.
+       (write_case) Ditto.
+       (execute_transformations) If a transformation returns TRNS_ERROR,
+       propagate the error.
+       (close_active_file) Add `bool' return type to indicate I/O error.
+       Propagate errors.
+       (cancel_transformations) Add `bool' return type to indicate I/O
+       error.  Propagate errors.
+       (struct split_aux_data) Change `proc_func' return type to bool.
+       (procedure_with_splits) Change `proc_func' return type to bool.
+       Add `bool' return type to indicate I/O error.
+       (multipass_procedure_with_splits) Change `split_func' return type
+       to bool.  Add `bool' return type to indicate I/O error.
+       (multipass_split_callback) Add `bool' return type to indicate I/O
+       error.  Propagate errors.
+
+       * vfm.h: (struct case_source_class) Change `read' return type from
+       void to bool to allow reporting I/O errors.  Updated all
+       implementations to do so.
+       (struct case_sink_class) Change `write' return type from void to
+       bool to allow reporting I/O errors.  Updated all implementations
+       to do so.
+
+Sun Feb 12 18:12:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * pool.c: Useful new functions.
+       (pool_tmpfile) New function.
+       (pool_attach_file) New function.
+       (pool_detach_file) New function.
+       (pool_fopen) Reimplement in terms of pool_attach_file().
+       (pool_fclose) Reimplement in terms of pool_detach_file().  Fix
+       double-free.
+
+       * str.c: Useful new functions.
+       (ds_swap) New function.
+       (ds_rtrim_spaces) New function.
+       (ds_chomp) New function.
+       (ds_is_empty) New function.
+       (ds_first) New function.
+       (ds_last) New function.
+
+Sat Feb 11 21:51:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of finished, start_interactive globals.
+
+       * command.c: (cmd_exit) Instead of setting `finished', return
+       CMD_EOF.
+       (cmd_finish) Ditto.
+
+       * command.h: New enum CMD_EOF.
+
+       * main.c: (global var finished) Removed.
+       (global var start_interactive) Removed.
+       (main) Execute commands until CMD_EOF is the return value.
+       If parse_command_line() returns false, don't execute any commands
+       at all.
+
+       * cmdline.c: (parse_command_line) If the command line indicates we
+       shouldn't execute syntax files, return false instead of
+       terminating.
+       (usage) Don't terminate.
+
+Sat Feb 11 21:48:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of cur_proc global.  Replace by functions in err and tab
+       modules, which were the users.
+
+       * error.c: (static var command_name) New static var.
+       (err_vmsg) Use command_name.
+       (err_set_command_name) New function.
+
+       * tab.c: (static var command_name) New static var.
+       (tabi_title) Use command_name.
+       (tab_set_command_name) New function.
+
+       * command.c: (global var cur_proc) Removed.
+       (cmd_parse) Call err_set_command_name(), tab_set_command_name()
+       around executing command to set and clear command name.
+
+Sat Feb 11 21:44:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of glob.c, glob.h.
+
+       * Makefile.am: (pspp_SOURCES) Remove glob.c, glob.h.
+       
+       * dictionary.c: Move default_dict definition here.
+
+       * glob.c: Removed.
+       (global var FILTER_before_TEMPORARY) Variable removed.  All
+       references deleted.  The info in this var was redundant with
+       temp_dict, so they were changed to use temp_dict where needed.
+
+       * glob.h: Removed.
+
+       * start-date.c: New file. Moved get_start_date() here.
+
+       * start-date.h: New file.
+
+Fri Feb  3 20:34:52 2006  Ben Pfaff  <blp@gnu.org>
+       * font.h: (struct font_set) Removed, because unused.
+Sat Jan 28 17:45:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       Cleaner (faster?) way to compact cases.
+
+       * dictionary.c: (dict_compact_case) Removed.
+       (dict_needs_compaction) New function.
+       (struct copy_map) New structure.
+       (struct dict_compactor) New structure.
+       (dict_make_compactor) New function.
+       (dict_compactor_compact) New function.
+       (dict_compactor_destroy) New function.
+       
+Sat Jan 28 17:24:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       Cleanups.
+
+       * data-list.c: Make data_list_source_class static.
+       (dump_fixed_table) Use fh_get_name() to describe source of data.
+       (dump_free_table) Ditto.
+       (cmd_repeating_data) Eliminate special cases for inline file.
+
+       * dictionary.c: (dict_contains_var) Change return value from int to
+       bool.
+       (dict_rename_vars) Ditto.
+       (dict_create_vector) Ditto.
+
+Sat Jan 28 17:20:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       Add scratch file handles.
+
+       Now a file handle can refer to a disk file, to an in-memory
+       structure, or to the "inline" file, instead of just to a disk
+       file.  The introduction of new categories means that special cases
+       for the inline file in a few places could be eliminated, but it
+       also means that code that assumed that a handle refers to a file
+       has to check for that.
+
+       Also, now file handles can be freed, so code now must be sure not
+       to access a handle after closing it (with fh_close()).
+
+       * Makefile.am: Add any-reader.c, any-reader.h, any-writer.c,
+       any-writer.h, scratch-handle.c, scratch-handle.h,
+       scratch-reader.c, scratch-reader.h, scratch-writer.c,
+       scratch-writer.h to pspp_SOURCES.
+
+       * any-reader.c: New file.
+       
+       * any-reader.h: New file.
+       
+       * any-writer.c: New file.
+       
+       * any-writer.h: New file.
+
+       * scratch-handle.c: New file.
+       
+       * scratch-handle.h: New file.
+
+       * scratch-reader.c: New file.
+       
+       * scratch-reader.h: New file.
+
+       * scratch-writer.c: New file.
+       
+       * scratch-writer.h: New file.
+
+       * aggregate.c: Use an any_writer instead of an sfm_writer, to add
+       flexibility.
+
+       * apply-dict.c: Use an any_reader instead of an sfm_reader, to add
+       flexibility.
+
+       * command.def: Add CLOSE FILE HANDLE command.
+
+       * dfm-reader.c: Now fewer special cases for inline file.
+       (static var inline_open_cnt) Removed.
+       (static var inline_file) Removed.
+       (dfm_close_reader) Eliminate a special case for inline file.
+       Reorganize to avoid access-after-free.
+       (dfm_open_reader) Eliminate a special case for inline file.
+       (read_inline_record) Use bool instead of int.  No need to
+       increment line number.
+       (read_file_record) Use bool instead of int.
+       (read_record) Check whether file handle is inline file, instead of
+       for null pointer.
+       (dfm_eof) Ditto.
+       (dfm_expand_tabs) Ditto.
+       (dfm_push) Ditto.
+       (dfm_pop) Ditto.
+       (cmd_begin_data) Fix inaccurate check for whether the inline file
+       is in use--now we can tell by checking whether the inline file's
+       open count is positive.
+       
+       * file-handle-def.c: (struct file_handle) Reorder members.  Add
+       `deleted' member.  Add `referent' member.  Add `sh' member.
+       (static var default_handle) New variable.
+       (static var inline_file) New variable.
+       (fh_init) Initialize inline file.
+       (free_handle) New function.
+       (fh_done) Rewrite.
+       (fh_from_name) Don't return deleted handles.
+       (fh_from_filename) Ditto.
+       (fh_create) Removed.
+       (create_handle) New function.
+       (fh_create_file) New function.
+       (fh_create_scratch) New function.
+       (fh_inline_file) New function.
+       (fh_free) Rewrite.
+       (fh_open) Now requires a referent type mask and verifies it.  All
+       references updated.
+       (fh_close) If open_cnt goes to 0 on a deleted handle, free it.
+       (fh_is_open) New function.
+       (fh_get_referent) New function.
+       (fh_get_filename) Limit to handles that refer to files.
+       (fh_get_mode) Ditto.
+       (fh_get_record_width) Limit to handles that refer to files or the
+       inline file.
+       (fh_get_tab_width) Ditto.
+       (fh_get_scratch_handle) New function.
+       (fh_set_scratch_handle) New function.
+       (fh_get_default_handle) New function.
+       (fh_set_default_handle) New function.
+
+       * file-handle.h: (enum fh_referent) New type.
+       (enum fh_mode) Rename MODE_TEXT to FH_MODE_TEXT, MODE_BINARY to
+       FH_MODE_BINARY, and update all usages.
+
+       * file-handle.q: Add "scratch" as a possible mode.
+       (cmd_file_handle) Mention CLOSE FILE HANDLE in error message.
+       Use lex_end_of_command(), lex_sbc_missing().  Support creating
+       scratch handles.
+       (cmd_close_file_handle) New function.
+       (referent_name) New function.
+       (fh_parse) Now takes a referent type mask to specify handles that
+       can be accepted.  Updated all references.
+       
+       * filename.c: (fn_extension) New function.
+
+       * get.c: Use any_reader and any_writer and thereby merge code that
+       has been duplicated for each kind of file.  Also, we had something
+       here called `any_writer' before, so its name had to be changed to
+       `case_writer'.
+       (enum operation) Removed, because unused.
+       (struct get_pgm) Removed.
+       (get_pgm_free) Removed.
+       (get_source_destroy) Removed.
+       (get_source_read) Removed.
+       (global var get_source_class) Removed.
+       (static var case_reader_source_class) Removed.
+       (enum reader_command) New enum.
+       (struct case_reader_pgm) New struct.
+       (parse_read_command) New function.
+       (case_reader_pgm_free) New function.
+       (case_reader_source_destroy) New function.
+       (case_Reader_source_Read) New function.
+       (cmd_get) Rewrote as a call to parse_read_command().
+       (cmd_import) Ditto.
+       (struct any_writer) Rename to case_writer.  Drop `writer_type',
+       `writer' members in favor of an `any_writer' member named
+       `writer'.
+       (any_writer_destroy) Rename case_writer_destroy.  Use
+       any_writer_close().
+       (parse_write_command) Allow scratch files.  Use any_writer.
+       (any_writer_write_case) Rename case_writer_write_case().  Use
+       any_writer_write().
+`      (struct mtf_file) Use any_reader.
+       (cmd_match_files) Allow scratch files.  Use any_reader.
+       (mtf_free_file) Use any_reader_close().
+       (mtf_read_nonactive_records) Use any_reader_read().
+       (mtf_processing) Use any_reader_read().
+       (struct import_pgm) Removed.
+       (import_pgm_free) Removed.
+       (import_source_destroy) Removed.
+       (import_source_read) Removed.
+       (global var import_source_class) Removed.
+
+       * glob.c: (global var default_handle) Removed.  Replaced all
+       references by fh_get_default_handle() or fh_set_default_handle().
+
+       * pfm-read.c: (static var portable_to_local) Moved from inside
+       read_header() to top level.
+       (pfm_detect) New function.
+
+       * pfm-write.c: (pfm_write_case) Make case argument const.
+       Reorganize to avoid access-after-free.
+
+       * print.c: (dump_table) Use fh_get_name() to describe source of
+       data.
+
+       * sfm-read.c: (sfm_close_reader) Reorganize to avoid
+       access-after-free.
+       (sfm_detect) New function.
+
+       * str.c: (str_lowercase) New function.
+
+       * vfm.c: Use new compaction interface.
+       (static var compaction_necessary) Removed.
+       (static var compactor) New variable.
+       (open_active_file) Initialize compactor.
+       (write_case) Use compactor.
+       (close_active_file) Free compactor.
+       
+Wed Jan 11 19:28:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       Clean up file handle code in preparation to add scratch file
+       handles.
+       
+       * file-handle-def.c: Lots of formatting cleanup.  Added function
+       comments.
+       (struct file_handle) Renamed `length' member
+       to `record_width'.  All references updated.
+       (fh_init) New function.  Moved here from file-handle.q.
+       (fh_done) New function.  Moved here from file-handle.q and
+       rewrote.
+       (get_handle_with_name) Renamed fh_from_name().
+       (get_handle_for_filename) Renamed fh_from_filename().
+       (create_file_handle) Renamed fh_create().  Changed to take a
+       `struct fh_properties' instead of discrete values.  Updated all
+       references.
+       (create_file_handle_with_defaults) Removed.  Updated all
+       references to use fh_create() with fh_default_properties().
+       (fh_default_properties) New function.
+       (destroy_file_handle) Removed.  The code is now in fh_done().
+       (handle_get_name) Renamed fh_get_name().
+       (handle_get_filename) Renamed fh_get_filename().
+       (handle_get_record_width) Renamed fh_get_record_width().
+       (handle_get_tab_width) Renamed fh_get_tab_width().
+
+       * file-handle-def.h: Formatting, comment fixes.
+       (enum file_handle_mode) Renamed struct fh_mode.
+       (struct fh_properties) New structure.
+       (fh_init) Move prototype here from file-handle.h.
+       (fh_done) Ditto.
+       (fh_close) Ditto.
+
+       * file-handle.q: (static var handle_list) Removed.
+       (fh_parse) Don't add handle to handle_list, because
+       file-handle-def.c has its own list.
+       (fh_init) Moved to file-handle-def.c.
+       (fh_done) Ditto.
+
+Sun Jan 9 01:09  Jason Stover  <jason@sakla.net>
+
+       * regression.q: (run_regression) Moved coefficient initialization
+       to the linreg library. Altered other functions accordingly.
+
+Sat Jan  7 13:30:54 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+        * command.c data-in.c main.c: Fixed bug which crept in when 
+          separating getl from readline.
+
+        * vars-atr.c value-labels.h: Fixed constness of  val_labs_count.
+
+Fri Dec 23 20:59:01 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * getl.c error.c: Separated file_loc functionality from error.c
+
+Mon Dec 19 14:01:56 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * format.c: Additional error checking.
+       * getl.[ch]: Separated into getl.c and readln.c
+       * settings.[ch]: Made CC_CNT public
+
+Fri Dec 16 09:11:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q: Fixed buglet when cleaning up at end of procedure.
+
+Tue Dec 13 22:34:42 2005  Ben Pfaff  <blp@gnu.org>
+
+       Move global initialization and cleanup code into main.c.
+       Remove vestigial log infrastructure.
+       Minor related cleanups.
+       
+       * command.c: (shell) When execl() fails, use _exit(), not
+       err_hcf().
+
+       * error.c: (err_hcf) Move into main.c, rename terminate().  All
+       callers updated.
+       (err_done) New function with just the error.c-specific code for
+       err_hcf().  Called by terminate().
+
+       * glob.c: Removed all Borland C, DJGPP cruft.
+       (init_glob) Merged into main().
+       (done_glob) Merged into terminate().
+       (get_date) Removed.
+       (get_start_date) New function.  All users of curdate updated to call
+       this function instead.
+
+       * lexer.c: (lex_init) Moved initialization of tokstr here, from
+       init_glob().
+       (lex_done) Moved destruction of tokstr here, from done_glob().
+
+       * main.c: (global var pgmname) Removed.  Changed all references to
+       program_name, which is defined by gnulib.
+       (global var curdate) Removed.
+       (main) Moved init_glob() code here.  Merged parse_script() in
+       here.
+       (parse_script) Removed.
+       (terminate) Moved err_hcf() here from error.c and renamed
+       terminate().  Merged done_glob() code in here.  Call err_done().
+       All callers updated.
+       (i18n_init) New function.
+       (fpu_init) New function.
+
+       * output.c: (outp_init) Make void.
+       (init_default_drivers) New function.
+       (outp_read_devices) If no drivers are initialized successfully,
+       call init_default_drivers() to initialize a default driver.
+       (outp_done) Make void.
+       (static var prog) Make const.
+       (parse_options) Make parameter const.
+       (colon_tokenize) Make return value const.
+       (configure_driver) Change prototype to take a broken-down driver
+       configuration instead of a line of text.
+       (configure_driver_line) New function that does what
+       configure_driver() did before.
+
+       * q2c.c: (global var pgmname) Rename program_name.
+
+       * settings.c: (settings_init) Renamed from init_settings().
+       (settings_done) Renamed from done_settings().
+
+       * vfm.c: (global var last_vfm_invocation) Make static.
+       (vfm_last_invocation) New function.  All references to
+       last_vfm_invocation update to call this.
+       (procedure) Call update_last_vfm_invocation().
+       (internal_procedure) Ditto.
+       (update_last_vfm_invocation) New function.
+       
+Sat Dec 10 23:30:19 2005  Ben Pfaff  <blp@gnu.org>
+
+       Separate random numbers from other settings because of GSL
+       dependency.
+
+       * Makefile.am: Add random.c, random.h to sources.
+
+       * glob.c: (init_glob) Call random_init().
+       (done_glob) Call random_done().
+
+       * settings.c: (static var rng) Move to random.c.
+       (done_settings) Move freeing of RNG to random_done().
+       (get_rng) Move to random.c
+       (set_rng) Ditto.
+
+       * random.c: New file.
+
+       * random.h: New file.
+
+Sat Dec 10 18:13:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       Separate settings and the SET command, for modularity.
+       
+       * Makefile.am: Add settings.c to sources.
+
+       * glob.c: (global variable test_mode) Removed.
+
+       * set.q: Remove all the set_* variables.  Remove a lot of obsolete
+       SPSS/PC+ settings.  Remove the aux_*() routines.  Moved the
+       get_*() functions into settings.c.  Rewrite the settings code and
+       functions to call the new set_*() functions.  Rewrite custom
+       currency parsing.  Write new by-hand cmd_show().
+
+       * esttings.c: New file.  Moved the get_*() functions here from
+       set.q.  Created new set_*() functions to correspond with them.
+       Regularized the names and types of some functions and updated
+       their callers.  Added static, file-scope variables to support the
+       settings.
+
+       * q2c.c: Remove "aux" support, which was only needed by set.q.
+       
+Sun Nov 27 06:43:46 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * data-out.c format.h: Added return value to data_out function.
+
+       * value-labels.c: Fixed bug in val_labs_remove.
+
+Sat Nov  5 18:37:26 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Remove devind.c, devind.h from list of source
+       files.
+
+       * devind.c: Removed.
+
+       * devind.h: Removed.
+
+       * list.q: Removed "support" for devind.
+
+       * output.c: Don't add devind class.
+
+Sat Nov  5 18:21:00 2005  Ben Pfaff  <blp@gnu.org>
+
+       * var.h: (struct variable) Make `init', `reinit' bool values.
+       Rearrange fields.
+
+Fri Nov  4 19:43:01 2005  Ben Pfaff  <blp@gnu.org>
+
+       * recode.c: Rewrote whole file, as clean-up.
+
+Fri Nov  4 19:37:50 2005  Ben Pfaff  <blp@gnu.org>
+
+       * pool.c: Don't make alignment exception for x86.
+       (pool_alloc) Return null for 0-size blocks.
+       (pool_alloc_unaligned) New function.
+       (pool_strndup) Removed.  Changed callers to use pool_clone_unaligned().
+       (pool_clone_unaligned) New function.
+       (pool_strdup) Use pool_clone_unaligned().
+
+       * var.h: (enum var_type) Give the NUMERIC, ALPHA enum this name.
+       (struct variable) Use `enum var_type' for `type'.
+
+       * vars-atr.c: (var_type_adj) New function.
+       (var_type_noun) New function.
+
+       * vars-prs: (parse_mixed_vars) Fix freeing code.
+       (parse_mixed_vars_pool) New function.
+
+Wed Nov  2 21:24:48 2005  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle-def.c: Needed another #include, to avoid missing
+       prototype warning.
+
+       * file-handle.q: (cmd_file_handle) Declarations must precede
+       statements.  Free parse data on success as well as on failure, to
+       avoid memory leak.
+
+       * get.c: (parse_write_command) Destroy dict on success, to avoid
+       memory leak.
+       
+       * data-list.c: (cmd_repeating_data) Fix usage of saw_occurs,
+       saw_length, saw_continued, saw_id, which were boolean but
+       incorrectly treated as bitmaps as result of a previous
+       half-finished cleanup.
+
+       * weight.c: (struct weight_trns) Unused, so removed.
+
+       * Makefile.am: Add range-prs.h to sources.
+
+Wed Nov  2 21:24:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       DO IF, LOOP cleanup.
+
+       * Makefile.am: Add ctl-stack.c, ctl-stack.h to source files.
+       Reformat source file list to list one file per file, so that
+       patches for future changes will be easier to read.
+
+       * ctl-stack.c, ctl-stack.h: New files.
+
+       * do-if.c: Rewrote whole file.
+
+       * do-ifP.h: Removed.
+
+       * loop.c: Rewrote whole file.
+
+       * glob.c: (global var ctl_stack) Move into ctl-stack.c.
+
+       * temporary.c: (cmd_temporary) Use ctl_stack_is_empty().
+
+       * vfm.c: (open_active_file) Use ctl_stack_clear().
+
+Wed Nov  2 21:18:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       New pool functions.
+       
+       * pool.c: (pool_create_at_offset) New function.
+       (pool_add_subpool) New function.
+
+       * pool.h: (pool_create_container) New macro.
+       
+       * expressions/parse.c: (expr_parse_pool) New function.
+       
+       * autorecode.c: (recode) Use pool_create_container().
+
+       * count.c: (cmd_count) Ditto.
+
+Wed Nov  2 19:59:32 2005  Ben Pfaff  <blp@gnu.org>
+
+       Clean up transformations, by getting rid of `struct trns_header',
+       replacing it by `struct transformation' that has a void *
+       `private' member.  Updated all uses of transformations to match,
+       which was a lot of code.  Only major related changes listed below.
+
+       * compute.c: (cmd_if) Use get_proc_func().
+       (cmd_compute) Use get_proc_func().
+       (get_proc_func) New function.
+
+       * glob.c: (global var m_trns) Change type to size_t.
+       (global var n_trns) Ditto.
+       (global var f_trns) Ditto.
+       (global var t_trns) Change type to struct transformation *.
+
+       * var.h: (struct trns_header) Removed.
+       (struct transformation) New.
+       (typedef trns_proc_func) Takes a void * instead of a struct
+       trns_header *.
+       (typedef trns_free_func) Ditto.
+
+       * vfm.c: (execute_transformations) Takes an array of
+       transformations instead of trns_headers.
+       (add_transformation) Change prototype from (trns_header *) to
+       (trns_proc_func *, trns_free_func *, void *).
+       (next_transformation) New function.
+
+Sat Oct 29 16:25:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       * count.c: Major cleanups.  Rename practically everything.
+       Rewrite much of the code.  Use pools for memory management.  Use
+       the new parse_num_range().
+
+       * mis-val.c: (cmd_missing_values) Use the new parse_num_range().
+       (parse_number) Removed.
+
+       * missing-values.c: (mv_add_num_range) Don't add out-of-order
+       ranges, e.g. where low > high.
+
+       * pool.c: (pool_2nrealloc) New function.
+
+       * range-prs.c: New file.
+       (parse_num_range) New function.
+       (parse_number) New function.
+       
+Fri Oct 28 22:47:48 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix up potential overflows in size calculations by replacing
+       instances of pool_alloc(p, x * sizeof *y) by pool_malloc(p, x,
+       sizeof *y) everywhere I could find them.  Similarly by
+       pool_malloc(), pool_realloc().
+       (Order is important: pool_alloc(p, sizeof *y, x) will divide by 0
+       if x is 0.)
+
+       * pool.c: (pool_nalloc) New function.
+       (pool_nmalloc) New function.
+       (pool_nrealloc) New function.
+
+Thu Oct 27 11:16:53 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       Separated the definition of a file handle object from the stuff 
+       pertaining to the FILE HANDLE command.
+
+       * file-handle-def.[ch]: New files.
+
+       * dfm-read.c file-handle.h file-handle.q
+       
+Tue Oct 25 21:56:23 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix up potential overflows in size calculations by replacing
+       instances of xmalloc(x * sizeof *y) by xnmalloc(x, sizeof *y)
+       everywhere I could find them.  Similarly by xrealloc(), malloc().
+       (Order is important: xnmalloc(sizeof *y, x) will divide by 0 if x
+       is 0.)
+
+       * alloc.c: (nmalloc) New function.
+       (out_of_memory) Removed.  Replaced references by xalloc_die().
+
+       * sort.c: (allocate_cases) Fix segfault if memory allocation
+       fails.
+
+       * subclist.c: (subc_list_double_create) Use xnmalloc() instead of
+       malloc().
+       (subc_list_double_push) Use xnrealloc() instead of realloc().
+
+Wed Oct 26 08:43:51 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       Dictionary abstraction part #2
+
+       * algorithm.c format.c str.c sysfile-info.c val.h var.h vars-atr.c:
+         Removed unnecessary #include directives
+
+Mon Oct 24 21:35:08 2005  Ben Pfaff  <blp@gnu.org>
+
+       * groff-font.c (font_msg): Use err_vmsg() instead of incorrectly
+       trying to pass a va_list to tmsg().  Thanks to Jason Stover for
+       reporting this bug.
+
+Mon Oct 24 21:24:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       Work to get rid of GCC 4.0 warnings, part 2.
+
+       In many files, change `unsigned char' to `char'.  This often
+       requires adding casts to <ctype.h> functions.
+
+       * data-in.c: (parse_A) Use buf_copy_rpad().
+
+       * str.c: (str_copy_buf_trunc) New function.
+
+       * value-labels.c: (value_to_string) Fix mistaken use of strncpy(),
+       by rewriting.
+
+Mon Oct 24 13:42:32 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       Moved some definitions to make it easier to abstract a dictionary 
+       from the rest of PSPP.
+
+       * format-prs.c lex-def.[ch]:  New files.
+
+       * Makefile.am lexer.[ch] dictionary.c vars-atr.c vfm.c algorithm.c 
+         format.c:  Moved some functions between modules.
+       
+Sun Oct 23 19:28:08 2005  Ben Pfaff  <blp@gnu.org>
+
+       Work to get rid of GCC 4.0 warnings, part 1.
+       
+       In many files, change count parameters to parse_variables(),
+       etc. from `int' to `size_t'.  Also change related variables and
+       struct members.  Also change messages as needed (e.g. %d to %u
+       with cast to unsigned).  Also change arithmetic as necessary
+       (e.g. n >= m - 1 to n + 1 >= m). 
+
+       * crosstabs.q: (crs_custom_tables) Check for size_t overflow in
+       multiplication.
+
+       * q2c.c: (dump_declarations) Generate code for size_t instead of
+       int.
+       
+Thu Oct 20 18:18:40 2005  Ben Pfaff  <blp@gnu.org>
+
+       * output.c: (outp_read_devices) Fix message.
+
+Sat Sep 17 11:13:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       * matrix-data.c: (cmd_matrix_data) Change type of variable whose
+       address is passed to dict_get_vars() from size_t to int to match
+       John's change below.
+
+       * modify-vars.c: (validate_var_modification) Ditto.
+
+Mon Sep 12 19:26:06 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.[ch]  Changed cnt from size_t* to int* since that's
+       what it's called as, and on  x86_64 machines they're different sizes.
+       
+       * str.c: (ds_vprintf) Copied va_list args so they can be re-used
+       
+Sun Aug 21 00:12:24 2005  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (lex_sbc_only_once) New function.
+       (lex_sbc_missing) New function.
+
+Sun Aug 21 00:00:47 2005  Ben Pfaff  <blp@gnu.org>
+
+       * case.h: (case_str) Make it return `unsigned char'.
+
+Sat Aug 20 23:56:14 2005  Ben Pfaff  <blp@gnu.org>
+
+       Revamp SAVE, XSAVE, EXPORT.  Add (or at least parse) all the
+       subcommands that we didn't support.  Fix bug 13911.  Fix bug
+       reported by Adam Pierson (COMPRESSED and other subcommands didn't
+       work on SAVE).  Refactor all related code.
+       
+       * command.def: Add XEXPORT command.
+
+       * dictionary.c: (dict_delete_scratch_vars) New function.
+
+       * get.c: (cmd_get) Fix parsing.
+       (struct save_trns) Removed.
+       (cmd_save_internal) Removed.
+       (cmd_save) Removed.
+       (do_write_case) Removed.
+       (save_write_case_func) Removed.
+       (save_trns_proc) Removed.
+       (save_trns_free) Removed.
+       (trim_dictionary) Removed.
+       (struct export_proc) Removed.
+       (cmd_export) Rewrote.
+       (export_write_case_func) Removed.
+       (export_proc_free) Removed.
+       (enum writer_type) New enum.
+       (enum command_type) New enum.
+       (struct any_writer) New struct.
+       (any_writer_destroy) New function.
+       (parse_write_command) New function.
+       (any_writer_write_case) New function.
+       (parse_output_proc) New function.
+       (output_proc) New function.
+       (cmd_save) Rewrote.
+       (cmd_xsave) Rewrote.
+       (struct output_trns) New struct.
+       (parse_output_trns) New function.
+       (output_trns_proc) New function.
+       (output_trns_free) New function.
+       (cmd_xsave) Rewrote.
+       (cmd_xexport) New function.
+       (parse_dict_trim) New function.
+       (struct mtf_proc) Change `by_cnt' member type to `int'.
+       (cmd_import) Rewrote.
+
+       * pfm-write.c: (struct pfm_writer) Add `digits' member.
+       (pfm_writer_default_options) New function.
+       (pfm_open_writer) Add `opts' argument and handle options.
+       (write_float) Write only as many digits as `digits' member says.
+       (format_trig_double) Limit base-10 precision to LDBL_DIG.
+
+       * pfm-write.h: (enum pfm_type) Moved here from pfm-read.h.
+       (struct pfm_write_options) New struct.
+
+       * sfm-write.c: (sfm_writer_default_options) New function.
+       (sfm_open_writer) Remove `compress', `omit_long_names' args.  Add
+       `opts' argument.  Implement options.
+
+       * sfm-write.h: (struct sfm_write_options) New struct.
+
+       * expressions/helpers.c: (copy_string) Make `old' arg `unsigned
+       char *' instead of `char *'.
+       
+Sat Aug  6 21:29:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       * factor_stats.c: Needed <config.h> included earlier.
+
+       * percentiles.c: Needed to include <config.h>.
+
+       * val.h: Don't include "config.h".
+
+Sat Aug  6 21:26:27 2005  Ben Pfaff  <blp@gnu.org>
+
+       Clean up treatment of missing values by moving all the code into
+       one place.  All references to the missing value function were
+       updated, but only major changes are detailed below.
+
+       * Makefile.am: Add missing-values.c, missing-values.h to sources.
+
+       * apply-dict.c: (cmd_apply_dictionary) Use mv_resize().
+
+       * dictionary.c: (dict_create_var) Initialize `miss' member with
+       mv_init().
+       (dict_clone_var) Copy `miss' member with mv_copy().
+       
+       * get.c: (mtf_merge_dictionary) Use mv_copy().
+
+       * missing-values.c: New file.
+       
+       * missing-values.h: New file.
+
+       * mis-val.c: Rewrite.  New version implements updated semantics.
+
+       * pfm-read.c: (read_variables) Rewrite missing value handling.
+
+       * pfm-write.c: (write_variables) Rewrite missing value handling.
+
+       * sfm-read.c: (read_variables) Rewrite missing value handling.
+
+       * sfm-write.c: (write_variable) Rewrite missing value handling.
+
+       * sfmP.h: Include "magic.h" to get definition of
+       second_lowest_value.
+
+       * sysfile-info.c: (describe_variable) Rewrite missing value
+       handling.
+
+       * val.h: Include "magic.h" to get definition of
+       second_lowest_value.
+
+       * var.h: Include "missing-values.h".  Drop MISSING_* enums.
+       (struct variable) Remove `miss_type', `missing'.  Add `miss'.
+
+       * vars-atr.c: (is_num_user_missing) Removed--use
+       mv_is_num_user_missing().
+       (is_str_user_missing) Removed--use mv_is_str_user_missing().
+       (is_system_missing) Removed--use mv_is_value_system_missing().
+       (is_missing) Removed--use mv_is_value_missing().
+       (is_user_missing) Removed--use mv_is_value_user_missing().
+       
+Sun Jul 31 14:09:57 2005  Ben Pfaff  <blp@gnu.org>
+
+       Adopt use of gnulib for portability.
+
+       * Make.build: Add $(top_srcdir)/gl and $(top_builddir)/gl to
+       include path.
+
+       * Makefile.am: Remove bool.h, stat.h and change getline.[ch] to
+       getl.[ch] in pspp_SOURCES.  Remove libmisc, add libgl in
+       pspp_LDADD.
+
+       * In many source files, added an explicit inclusion of gettext.h
+       and definition of _ macro.  These are no longer in pref.h because
+       it interfered with definitions in a few gnulib source files.
+
+       * In many source files, changed #include "bool.h" to #include
+       <stdbool.h>, which is provided by gnulib.
+
+       * alloc.c: Removed functions defined in gnulib:
+       (xmalloc) Removed.
+       (xcalloc) Removed.
+       (xrealloc) Removed.
+       (xstrdup) Removed.
+       (out_of_memory) Redefined as wrapper for xalloc_die().
+
+       * alloc.h: Replace prototypes by #include "xalloc.h".
+
+       * casefile.c: Use full_read() and full_write() from gnulib instead
+       of our home-grown versions.
+       (full_read) Removed.
+       (full_write) Removed.
+
+       * getline.c: Renamed getl.c.
+
+       * getline.h: Renamed getl.h, updated all references.
+
+       * filename.c: (fn_readlink) Change to wrapper around xreadlink()
+       from gnulib.
+
+       * glob.c: Just #include <time.h> instead of the crazy rigmarole
+       here before.
+       (init_glob) Call set_program_name() to initial gnulib progname
+       module.
+
+       * html.c: (postopen) Use getlogin_r(), gethostname() from gnulib.
+
+       * permissions.c: Use "stat-macros.h" from gnulib.
+
+       * postscript.c: Just #include <time.h> instead of the crazy
+       rigmarole here before.
+
+       * q2c.c: (main) Make generated code #include "gettext.h".
+
+       * str.h: Get rid of most explicit declarations of standard
+       functions, in favor of including gnulib header files.
+
+       * expressions/evaluate.c: Ditto.
+
+       * expressions/operations.h.pl: Make generated code #include
+       <stdbool.h>, not "bool.h".
+
+Sat Jul 30 23:13:17 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/parse.c: (validate_function_args) Fix two msg() bugs
+       found by -Wformat.
+
+Sat Jul 30 23:10:01 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/evaluate.c: (expr_debug_print_postfix) Don't pass
+       null pointer to printf for %.*s.
+
+Sat Jul 30 23:05:33 2005  Ben Pfaff  <blp@gnu.org>
+
+       * vars-atr.c: (var_is_valid_name) Fix three msg() bugs found by
+       -Wformat.
+
+Sat Jul 30 22:58:33 2005  Ben Pfaff  <blp@gnu.org>
+
+       * rank.q: (parse_rank_function) Fix msg() bug found by -Wformat.
+
+Sat Jul 30 22:56:12 2005  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: (postopen) Cast `char' to `unsigned char' before
+       passing to isspace().
+
+Sat Jul 30 22:52:09 2005  Ben Pfaff  <blp@gnu.org>
+
+       * pfm-read.c: (read_variables) Fix msg() bug found by -Wformat.
+
+Sat Jul 30 22:50:57 2005  Ben Pfaff  <blp@gnu.org>
+
+       * histogram.c: Include <config.h>.
+
+Sat Jul 30 22:48:50 2005  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_match_files) Fix msg() bug found by -Wformat.
+
+Sat Jul 30 22:46:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (check_common_specifier) Fix msg() bug found by
+       -Wformat.
+       (check_output_specifier) Ditto.
+
+Sat Jul 30 22:43:57 2005  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.q: (cmd_file_handle) Fix msg() bug found by
+       -Wformat.
+
+Sat Jul 30 22:41:44 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: (parse_Z) [WORDS_BIGENDIAN] Don't declare buf[], to
+       avoid "unused variable" warning.
+
+Sat Jul 30 22:38:46 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (find_word) Cast `char' to `unsigned char' before
+       passing to isspace().
+
+Sat Jul 30 22:36:29 2005  Ben Pfaff  <blp@gnu.org>
+
+       * case.c: (case_compare) Implement as delegating to
+       case_compare_2dict().
+
+Sat Jul 30 22:34:18 2005  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: Inclusion of <alloca.h> is unneeded.
+
+Sat Jul 30 22:01:32 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Make.build: Don't append -ansi to AM_CFLAGS for GCC.  Using
+       -ansi changes the behavior of header files significantly.  It
+       causes __STRICT_ANSI__ to be defined, and some headers interpret
+       that as cause to e.g. not use `long long' or __attribute__.  The
+       former example is bad when off_t is supposed to be `long long',
+       and the latter prevents -Wformat from working.
+
+Sun Jul 24 20:26:59 2005  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of dependency on libgmp by writing our own routine for
+       floating-point base conversion.
+
+       * pfm-write.c: (write_float) Rewrote.
+       (write_int) Rewrote.
+       (pow30_nonnegative) New function.
+       (pow30) New function.
+       (trig_to_char) New function.
+       (format_trig_digits) New function.
+       (recurse_format_trig_int) New function.
+       (format_trig_int) New function.
+       (should_round_up) New function.
+       (try_round_up) New function.
+       (format_trig_double) New function.
+
+Sun Jul 24 18:49:20 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: (parse_numeric) Allow "1+23" even for F format, for
+       compatibility.
+
+Sun Jul 24 18:47:37 2005  Ben Pfaff  <blp@gnu.org>
+
+       * pfm-read.c: (read_version_data) Read and ignore author field.
+
+Wed Jul  6 20:44:27 2005  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (mtf_processing) Don't assume that
+       mtf_compare_BY_values() always returns -1, 0, or 1.  Actually, it
+       returns a negative, zero, or positive result.  Fixes MATCH FILES
+       bug on Mac OS X reported by "Marshall DeBerry" <mdb@radix.net>.
+
+Mon Jul  4 18:01:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: [HAVE_SYS_TYPES_H] Really include <sys/types.h>.  The
+       preprocessor test for sys/types.h was accidentally inverted.  This
+       was bug 12789.
+
+Sun Jul  3 22:47:39 2005  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_match_files) Fix memory leak on `by' and on
+       `vfm_source'.
+
+       * getline.c: [HAVE_LIBREADLINE] (read_console) Fix memory leak on
+       `line'.
+
+       * vfm.c: (close_active_file) Remove unnecessary test.
+
+Sun Jul  3 21:45:32 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix NDEBUG compile errors.
+
+       * hash.h: Needed explicit #include <assert.h>.
+
+       * linked-list.c: (ll_next) First arg is UNUSED when NDEBUG is
+       defined.
+
+Sun Jun 12 23:44:38 2005  Ben Pfaff  <blp@gnu.org>
+
+       Implement embedding for PostScript driver.  Fixes bug 12970.
+
+       * ascii.c: Fix compiler warnings.
+
+       * html.c: Ditto.
+
+       * chart.h: Add `file' member.
+
+       * output.h: (struct outp_class) initialise_chart, finalise_chart
+       should take outp_driver *, not outp_class *.  Update all
+       references.
+
+       * plot-chart.c: (chart_create) Fix segfault when there are no
+       output drivers at all.
+       (chart_submit) Call d->class->finalise_chart.
+
+       * postscript.c: (ps_open_page) Set cp_y to 0.
+       (ps_submit) New function.
+       (ps_chart_initialise) Implement.
+       (ps_chart_finalise) Implement.
+       (static var postscript_class) Add ps_submit.
+       (static var epsf_class) Add ps_submit.
+       
+
+Sun Jun 12 14:54:40 2005  Ben Pfaff  <blp@gnu.org>
+
+       Did some more work on bug 12859 and then realized that a *good*
+       solution would require some fundamental restructuring.  For now,
+       I'm marking REPEATING DATA unimplemented, and then we can revisit
+       it post-0.4.0.
+       
+       * command.def: Make REPEATING DATA unimplemented.
+
+       * data-list.c: (cmd_repeating_data) Assume inline file is 80
+       characters wide.
+       (realize_value) Revert previous changes; no longer needed.
+       Updated all callers.
+
+       * error.c: (err_hcf) Set nfile_loc, mfile_loc to 0 after freeing
+       file_loc, to avoid bad references later.
+
+       * str.c: Fix typo.
+
+Tue Jun  7 00:14:09 2005  Ben Pfaff  <blp@gnu.org>
+
+       Make some code tolerant of reentry.  Should not be needed if other
+       code is correct but it is good to be generally tolerant.
+       
+       * error.c: (err_hcf) Set file_loc to null after free().
+
+       * output.c: (outp_done) Similar changes.
+
+       * str.c: (ds_destroy) Ditto.
+       
+Tue Jun  7 00:10:20 2005  Ben Pfaff  <blp@gnu.org>
+
+       Continue work on bug 12859, plus some code cleanup.
+       
+       * data-list.c: (cmd_repeating_data) Replace `seen' bitmap by
+       boolean variables.  Don't try to compute starts_end, cont_end for
+       inline file.  Calculate length only after parsing variable
+       specifications.  Add proper transformation to list.
+       (realize_value) If the rpd_num_or_var has no value, return new
+       DEFAULT_MEMBER argument (for use with inline file).
+       (repeating_data_trns_proc) Pass default values.
+
+       * dfm-read.c: (dfm_close_reader) Only skip data if *not* still
+       open, and only if we actually started reading data.
+
+Sun Jun  5 18:39:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 11894.
+       
+       * output.c: (outp_read_devices) Fix message.
+
+Fri May 27 12:34:43 WST 2005 John Darrington <john@darrington.wattle.id.au>
+       
+       * sort-prs.[ch] (newfiles), aggregate.c, sort.[ch]: Separated the guts 
+       of the sort algorithm from the parser for the SORT command.
+       
+       * rank.q: Added the parser for the RANK command.
+       
+Thu May 26 12:29:21 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 13192.
+
+       * sort.c: (sort_parse_criteria) Only set *saw_direction if
+       saw_direction is non-null.  Thanks to John Darrington for
+       reporting this bug.
+
+Tue May 24 21:52:55 2005  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (mtf_processing) Handle case of a lookup table as the
+       active file.  Thanks to John Darrington for reporting this bug.
+
+Wed May 25 10:27:02 WST 2005 John Darrington <john@darrington.wattle.id.au>
+       
+       * alloc.c alloc.h: (xcalloc) changed signature to imitate the
+       POSIX  calloc function.
+       
+       * crosstabs.q get.c vars-prs.c: Updated calls to xcalloc to
+       reflect new signature.
+
+       * sfm-read.c: Now much more robust in the face of badly formed
+       system files.
+
+Mon May 23 11:57:31 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       *sfm-read.c: Fixed some bugs regarding long string continuation
+       records, which the previous fix uncovered.
+
+Sat May 21 12:48:34 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * sfm-read.c, sfmP.h:  Allow reading of system files when the 
+       case_size value in the header is -1.  Also changed some Errors to 
+       Warnings when reading system files.
+
+Tue May 17 21:00:57 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: (data_list_trns_free) Don't free the argument
+       because cancel_transformations() will do that itself.
+       (data_list_source_destroy) Destroy the argument to
+       data_list_trns_free(), because it no longer does so itself.
+
+Tue May 17 18:29:35 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c: (format_and_round) Don't output leading `-' if value
+       rounds to zero.
+
+Tue May 17 00:06:43 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 11119.
+
+       * som.c: (output_encodings) If some cell in the table won't fit
+       with the horizontal or vertical headers, cancel those headers.
+
+       * som.h: (struct som_table_class) Add fits_width, fits_length,
+       set_headers members.
+
+       * tab.c: (tabi_fits_width) New function.
+       (tabi_fits_length) New function.
+       (tabi_set_headers) New function.
+       (global var tab_table_class) Add the new functions as appropriate
+       members.
+       
+Mon May 16 22:34:06 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix rest of bug 13054.
+
+       * format.def: Fix EDATE, SDATE, ADATE, JDATE, QYR, MOYR, WKYR,
+       DATETIME, TIME system/portable file values.
+
+Mon May 16 22:31:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: (parse_free) Use make_input_format().
+       
+       * data-out.c: (num_to_string) Use make_output_format().
+
+       * dictionary.c: (dict_create_var) Ditto.
+
+       * format.c: (global var f8_2) New var.
+       (make_input_format) New function.
+       (make_output_format) New function.
+
+       * get.c: (cmd_match_files) Use make_output_format().
+
+       * list.q: (cmd_list) Ditto.
+
+       * matrix-data.c: Ditto.
+
+       * sfm-read.c: (parse_format_spec) Check output specifier
+       thoroughly.
+
+       * tab.c: (tab_float) Use make_output_format().
+
+Sun May 15 23:38:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix more of bug 13054.
+       
+       * format.def: FMT_A should allow 255-character output.  FMT_AHEX
+       should allow 510-character input and output.
+
+       * data-out.c: (num_to_string) Get rid of NEW_STYLE option.
+       (convert_E) Handle non-finite values.
+       (try_F) Rewrite.
+       (format_and_round) New function.
+       (convert_infinite) New function used by try_F() and convert_E().
+
+Sun May 15 23:36:55 2005  Ben Pfaff  <blp@gnu.org>
+
+       Regularize string and buffer function names so that they make some
+       kind of sense.
+
+       * str.c: (mm_reverse) Rename buf_reverse().  Update all
+       references.
+       (mm_find_reverse) Rename buf_find_reverse().  Update all
+       references.
+       (mm_case_compare) Rename buf_compare_case().  Update all
+       references.
+       (st_compare_pad) Rename buf_compare_rpad().  Update all
+       references.
+       (str_compare_rpad) New function.
+       (st_bare_pad_copy) Rename buf_copy_str_rpad().  Update all
+       references.
+       (buf_copy_str_lpad) New function.
+       (st_bare_pad_len_copy) Rename buf_copy_rpad().  Update all
+       references.
+       (st_pad_copy) Rename str_copy_rpad().  Update all references.
+       (st_trim_copy) Rename str_copy_trunc().  Update all references.
+       (st_uppercase) Renamed str_uppercase().  Update all references.
+       
+Sat May 14 08:22:26 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * dfm-read.c: Fixed polarity of test in dfm-close-reader.  Closes 
+       Bug #13082
+
+Tue May 10 20:08:18 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: (data_in) Add assertion to check input specifier.
+
+       * data-out.c: (data_out) Add assertion to check output specifier.
+
+Tue May 10 19:56:35 2005  Ben Pfaff  <blp@gnu.org>
+
+       Start to fix bug 13054.
+
+       * format.c: (check_input_specifier) Improve error message.
+       (check_input_specifier) Check F, COMMA, and DOLLAR formats for
+       valid decimal places.
+       (check_output_specifier) Ditto (but different criteria).
+       (convert_fmt_ItoO) Assert valid input and output specifiers.
+       Also, if input specifier has *any* decimal places, make the output
+       specifier 1 place wider.
+
+Mon May  9 07:14:29 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * sysfile-info.c: Fixed bug [# 13024 ]
+
+Sun May  8 13:52:12 2005  Ben Pfaff  <blp@gnu.org>
+
+       "Fix" bug 13021 by disabling FILE TYPE.  Eventually, we should
+       actually implement it.
+
+       * command.c: (FILE_TYPE_okay) Always return 1.
+
+       * command.def: Change FILE TYPE, END FILE TYPE into UNIMPL.
+
+       * file-type.c: Add prototypes to get rid of warnings.
+
+Sun May  8 08:08:07 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * barchart.c box-whisker.c cartesian.c piechart.c plot-hist.c: Fixed 
+        more ISO/IEC 9899:1990 conformance issues.
+
+Wed May  4 23:54:02 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 12948.  See also new test in
+       tests/bugs/match-file-scratch.sh.
+       
+       * get.c: (mtf_merge_dictionary) Don't compact dictionary because
+       that deletes scratch variables that someone else might be using,
+       and because we can't reassign our sources' value indexes.
+       Instead, simply don't copy scratch variables into the master
+       dictionary.
+
+       * dictionary.c: (dict_compact_values) Delete variables from the
+       dictionary passed in, not from default_dict (!).
+
+Tue May  3 22:25:17 2005  Ben Pfaff  <blp@gnu.org>
+
+       Improve hash.c comments, error-checking.
+       
+       * hash.c: (struct hsh_table) [NDEBUG] Add hash_ordered member.
+       (hsh_create) size == 0 should *not* return NULL!  Set
+       hash_ordered.
+       (hsh_clear) Set hash_ordered.
+       (locate_matching_entry) Check hash_ordered.
+       (hsh_rehash) Rename rehash().  Add assertion.  Set hash_ordered.
+       (hsh_data) Set hash_ordered.  Add const-ness to return value and
+       update all callers.
+       (hsh_sort) Ditto.       
+
+Wed May  4 08:50:11 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c: Removed unnecessary #include <valgrind/valgrind.h>
+
+Tue May  3 19:14:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * copyleft.c: Updated copyright date.
+
+       * Makefile.am: Removed erroneous explicit "-lplot"
+
+       * examine.q oneway.q: Made these files conform to ISO/IEC 9899:1990
+
+Tue May  3 16:20:31 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * command.c command.def: Added description string for unimplemented commands.
+
+       * oneway.q: Sorted the hash tables before shipping out the results. Closes 
+       bug [#12931].
+
+Mon May  2 23:45:01 2005  Ben Pfaff  <blp@gnu.org>
+
+       Code improvements.
+       
+       * data-list.c:  (parse_fixed) Use lex_end_of_command().
+       (parse_free) Ditto.
+       (cmd_repeating_data) Set cont_end.num in right situations.
+       (parse_repeating_data) Remove redundant test.
+
+Mon May  2 23:37:19 2005  Ben Pfaff  <blp@gnu.org>
+
+       Partial fix for bug 12859.
+       
+       * data-list.c: (cmd_data_list) Add transformation properly in
+       vfm_source == NULL case.
+
+Mon May  2 23:27:28 2005  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (lex_error) Improve error messages.
+
+Mon May  2 22:28:17 2005  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_match_files) Check token type before trying to match
+       tokid.  Fixes bug 12923.
+
+Mon May  2 22:16:51 2005  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: [HAVE_SYS_TYPES_H] Include <sys/types.h>.  Fixes bug
+       12789.
+
+Mon May  2 22:02:52 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/generate.pl: (get_token) Make use of /g
+       backward-compatible with Perl 5.6.1.
+
+Sun May  1 23:00:19 2005  Ben Pfaff  <blp@gnu.org>
+
+       * var-display.c: (cmd_variable_alignment) Fix memory leak.
+       (cmd_variable_level) Ditto.
+
+Sun May  1 22:49:04 2005  Ben Pfaff  <blp@gnu.org>
+
+       Hash table had buggy deletion function.  The fix required changing
+       other functions to do probing in the required order.
+
+       * hash.c: (locate_matching_entry) Rewrite and change interface.
+       (hsh_rehash) Rewrite to use locate_matching_entry().
+       (hsh_probe) Ditto.
+       (hsh_find) Ditto.
+       (hsh_delete) Ditto.  Also, fix stupid bugs.
+
+Sun May  1 22:24:58 2005  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c: (dict_clone) Properly copy vectors.
+
+Sun May  1 22:07:58 2005  Ben Pfaff  <blp@gnu.org>
+
+       New implementation of long variable names.  Each variable has a
+       "normal" name, which may be up to 64 bytes long and which is used
+       for all normal operations.  Variables may have a "short" name,
+       which is limited to 8 bytes and used only for system and portable
+       file input and output.
+       
+       Make tokid case-preserving.  Update most uses of tokid to treat it
+       case-insensitively.
+
+       Update many commands to deal with long variable names.
+
+       * autorecode.c: (cmd_autorecode) Use strcasecmp() instead of strcmp().
+
+       * command.c: (cmd_parse) Ditto.
+       (match_strings) Use toupper() before comparing characters.
+       (conflicting_3char_prefixes) Use mm_case_compare() instead of
+       memcmp().
+       (cmd_match_words) Ditto.
+
+       * compute.c: (lvalue_parse) Use st_trim_copy() instead of
+       strncpy().
+
+       * count.c: (struct cnt_var_info) Change n[] to fit long var name.
+       Use st_trim_copy() instead of strcpy().
+
+       * data-in.c: (parse_enum) Use mm_case_compare() instead of
+       memcmp().
+
+       * data-list.c: (struct dls_var_spec) Change name[] to fit long var
+       name.
+       (parse_free) Use st_trim_copy() instead of strcpy().
+
+       * descript.c: (struct dsc_var) Change z_name[] to fit long var
+       name.
+       (try_name) Use strcasecmp() instead of strcmp().
+       (generate_z_varname) Use st_trim_copy() instead of strcpy().
+       (descriptives_compare_dsc_vars) Use strcasecmp() instead of
+       strcmp().
+
+       * dictionary.c: (struct dictionary) Removed `long_name_tab'
+       member.
+       (compare_long_names) Removed.
+       (hash_long_name) Removed.
+       (dict_create) Don't initialize `long_name_tab' member.
+       (dict_clone) Copy short names into new dictionary. 
+       (dict_clear) Don't clear `long_name_tab' member.
+       (dict_get_varname_block) Removed.
+       (dict_add_longvar_entry) Removed.
+       (free_nte) Removed.
+       (dict_destroy) Don't destroy `long_name_tab' member.
+       (dict_create_var_from_short) Removed.
+       (dict_create_var_x) Removed.
+       (dict_create_var) Get rid of longname handling.
+       Clear short name.
+       (dict_clone_var) Get rid of longname parameter and longname
+       handling.
+       (dict_lookup_var) Get rid of longname handling.
+       (dict_reorder_var) New function.
+       (dict_rename_var) Clear short name.
+       (dict_rename_vars) Get rid of longname handling.  Clear short
+       names.
+       (dict_create_vector) Support long vector names.
+       (dict_lookup_vector) Use strcasecmp() instead of strcmp().
+       (quasi_base27) Removed.
+       (make_short_name) Removed.
+       (compare_strings) New function.
+       (hash_string) New function.
+       (dict_assign_short_names) New function.
+
+       * file-handle.q: (get_handle_with_name) Use strcasecmp() instead
+       of strcmp().
+       (get_handle_for_filename) Support long handle names.
+
+       * file-type.c: (struct col_spec) Make `name' fit long var names.
+       (cmd_file_type) Use strcasecmp() instead of strcmp().
+
+       * flip.c: (make_new_var) Rewrite.
+       (flip_sink_write) Use st_trim_copy() instead of strncpy().
+
+       * format.c: (parse_format_specifier_name) Use mm_case_compare()
+       instead of memcmp().
+
+       * get.c: (cmd_save_internal) Rephrase.
+       (rename_variables) Drop test for identical variable name.
+       (struct mtf_proc) Change `first', `last' to fit long var name.
+
+       * hash.c: (hsh_hash_case_string) New function for case-insensitive
+       string hashing.
+
+       * lexer.c: (restore_token) Use st_trim_copy() instead of
+       strncpy().
+       (lex_get) Don't uppercase string when copying into tokid.
+       (lex_put_back_id) Use st_trim_copy() instead of
+       strncpy().
+
+       * list.q: (determine_layout) Consider length of variable names in
+       choosing vertical layout.
+
+       * matrix-data.c: (cmd_matrix_data) Use strcasecmp() instead of
+       strcmp().
+       (string_to_content_type) Ditto.
+
+       * modify-vars.c: (compare_variables_given_ordering) Ditto.
+       (struct var_renaming) Change `new_name' to fit long var name.
+       (compare_var_renaming_by_new_name) Use strcasecmp() instead of
+       strcmp().
+
+       * pfm-read.c: (read_variables) Disallow system variables in system
+       files.
+       (write_variables) Call dict_assign_short_names() and use
+       short_name[] members.
+
+       * repeat.c: (internal_cmd_do_repeat) Use strcasecmp() instead of
+       strcmp().
+
+       * sfm-read.c: (sfm_open_reader) Rewrite code for long variable
+       map.  Reorder variables into same order as long variable map.
+       (read_variables) Set short name.
+
+       * sfm-write.c: (sfm_open_writer) Call dict_assign_short_names().
+       (write_variable) Use st_bare_pad_copy().
+       (write_longvar_table) Rewrite.
+
+       * str.c: (mm_case_compare) New function.
+
+       * sysfile-info.c: (compare_vectors_by_name) Use strcasecmp()
+       instead of strcmp().
+
+       * t-test.q: (tts_custom_groups) Remove redundant test.
+       (tts_custom_pairs) Ditto.
+
+       * var.h: (struct variable) Change `name' to fit long var names.
+       Remove `longname'.  Add `short_name' member.  Reorder some
+       variables.
+       (struct name_table_entry) Removed.
+       (struct vector) Change `name' to fit long vector names.
+
+       * vars-atr.c: (var_is_valid_name) Allow long var names.
+       (compare_var_names) Use strcasecmp() instead of strcmp().
+       (compare_var_ptr_names) Ditto.
+       (hash_var_name) Use hsh_hash_case_string().
+       (hash_var_ptr_name) Ditto.
+       (var_set_short_name) New function.
+       (var_clear_short_name) New function.
+       (var_set_short_name_suffix) New function.
+
+       * vars-prs.c: (parse_DATA_LIST_vars) Support long names.
+       Use strcasecmp() instead of strcmp().
+       (struct array_var_set) Removed `longname_tab'.
+       (array_var_set_lookup_var_idx) Drop longname_tab support.
+       (array_var_set_destroy) Don't destroy `longname_tab'.
+       (var_set_create_from_array) Don't create `longname_tab'.
+
+       * vector.c: (cmd_vector) Use strcasecmp() instead of strcmp().
+       Support long names.
+
+       * expressions/parse.c: (word_matches) Use mm_case_compare()
+       instead of memcmp().
+       (compare_strings) New function.
+       (lookup_function) Use compare_strings() instead of strcmp().
+       
+Sun May  1 22:07:43 2005  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: (move_element) New function.
+
+Sun May  1 22:05:35 2005  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (parse_aggregate_functions) Always initialize
+       destvar.
+
+Sun May  1 22:03:47 2005  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (cmd_aggregate) Use dict_clone_var_assert().
+
+       * dictionary.c: (dict_clone) Ditto.
+       (dict_clone_var_assert) New function.
+
+       * get.c: (mtf_merge_dictionary) Use dict_clone_var_assert().
+
+Sun May  1 15:05:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * error.c: Added a string for the compiler version to the
+       request_bug_report_and_abort function.
+
+       * groff_font.c, font.c: Removed manpage(1) style references from 
+       comments, because RMS frowns upon them.
+
+Thu Apr 28 18:52:06 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/parse.c: Improve previous fix for bug 12858 (LAG).
+
+Fri Apr 29 09:28:00 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * expressions/parse.c: Added handler for OP_LAG_Vn and OP_LAG_Vs.  
+       Fixed bug [#12858] .
+
+Wed Apr 27 12:42:34 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * loop.c recode.c repeat.c: Fixed a couple of instances of SHORT_NAME_LEN 
+       which should be LONG_NAME_LEN
+
+Wed Apr 27 07:43:50 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * command.def echo.c:  Added the ECHO command.
+
+Mon Apr 25 22:55:59 2005  Ben Pfaff  <blp@gnu.org>
+
+       Finish fixing MATCH FILES (bug 11677).
+
+       * get.c: (trim_dictionary) Rewrite in terms of drop_variables(),
+       keep_variables(), rename_variables().
+       (drop_variables) New function.
+       (keep_variables) New function.
+       (struct mtf_file) Rename `in' to `in_name'.  Add `in_var'.
+       (cmd_match_files) Deal with in_var.  Use drop_variables(),
+       keep_variables().  When IN is specified, require BY.  Set master
+       variables after master dictionary is complete.  Add IN variables
+       after master dictionary is complete.
+       (mtf_free_file) Free `in_name'.
+       (mtf_delete_file_in_place) Set in_var value to 0.
+       (mtf_read_nonactive_records)  Rephrase.
+       (mtf_processing) Support IN.  Rephrase.  Fix bugs.
+       (mtf_merge_dictionary) Don't set master variables; we do that
+       later now.
+       (get_master) Don't insist that there's a master variable.
+       
+Mon Apr 25 22:55:22 2005  Ben Pfaff  <blp@gnu.org>
+
+       Kluge to make some variable renaming sort of work.
+       Needs real fix.
+
+       * dictionary.c: (dict_rename_var) Call dict_add_longvar_entry().
+
+Mon Apr 25 22:52:28 2005  Ben Pfaff  <blp@gnu.org>
+
+       Add functions for comparing sets of variables between cases.
+       Use the functions.
+
+       * case.c: (case_compare) New function.
+       (case_compare_2dict) New function.
+       
+       * aggregate.c: (struct agr_proc) Remove `prev_break' member.  Add
+       `break_case'.
+       (cmd_aggregate) Nullify break_case.  Don't call
+       initialize_aggregate_info().
+       (agr_destroy) Destroy break_case.
+       (aggregate_single_case) Rewrite.  Use case_compare().
+       (dump_aggregate_info) Copy from break_case into output.
+       (initialize_aggregate_info) Copy break_case from input.
+
+       * get.c: (mtf_compare_BY_values) Use case_compare_2dict().
+
+       * vfm.c: (equal_splits) Use case_compare().
+
+Sat Apr 23 17:01:04 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c vars-prs.c sfm-write.c: Fixed some memory leaks
+
+Sun Apr 17 23:08:15 2005  Ben Pfaff  <blp@gnu.org>
+
+       Start work on fixing MATCH FILES.
+
+       * get.c: (enum operation) Remove OP_MATCH.
+       (trim_dictionary) Change return value to bool.  Don't support
+       OP_MATCH.
+       (struct mtf_file) Remove `first', `last' members.
+       (struct mtf_proc) Add `first', `last' members.  Change mtf_case
+       from `struct ccase *' to `struct ccase'.  Remove `by' member.
+       (cmd_match_files) Essentially rewrite.
+       (mtf_free) Don't free `by' member.  Destroy `mtf_case' member.
+       (mtf_read_nonactive_records) mtf_ parameter is not unused.
+       (mtf_processing) Ditto.  Also rephrase some code.
+       (mtf_merge_dictionary) Rewrite for easy comprehension.  
+
+Sun Apr 17 23:06:00 2005  Ben Pfaff  <blp@gnu.org>
+
+       * matrix-data.c: (wr_output_data) [DEBUGGING] Fix compilation
+       error.
+
+       * q2c.c: (dump_token) [DEBUGGING] Fix compilation error.
+       
+Thu Apr 14 2005 John Darrington
+
+        * var-display.c: New file.
+
+       * format.h var.h sfm-read.c sfm-write.c dictionary.c :  Added 
+         display_width, measure and alignment parameters to variables.
+
+       * aggregate.c command.def compute.c count.c data-list.c descript.c
+         dictionary.c dictionary.h expr-prs.c file-type.c flip.c get.c 
+         lexer.c lexer.h loop.c modify-vars.c pfm-read.c recode.c repeat.c 
+         sfm-read.c sfm-write.c sfm-write.h sfmP.h val-labs.c val.h var.h 
+         vars-prs.c vector.c :  
+             - Replaced literal constants representing maximum variable name 
+               length with macro definitions. 
+             - Added support for long variable names.
+             - Changed lexer such that it no longer makes tokens upper
+               case, but relies upon case insensitive behaviour of commands.
+
+Mon Apr  4 22:27:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (parse_aggregate_functions) If dict_create_var()
+       fails, don't dereference the resulting null pointer (bug 12427).
+       Also, fix double free error.
+
+Sat Mar 19 23:06:02 2005  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (parse_aggregate_functions) Fix N_NO_VARS format.
+       (accumulate_aggregate_info) Set int1 to 1 for SUM.
+       (dump_aggregate_info) Only make SUM non-missing if there was at
+       least one variate.
+
+Sat Mar 19 14:48:19 2005  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (dump_aggregate_info) Properly test whether the
+       destination variable is numeric, when making the result
+       system-missing for columnwise missing values.
+
+Mon Mar 14 21:52:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * misc.h: Remove GCC specializations.
+
+Mon Mar 14 21:07:23 2005  Ben Pfaff  <blp@gnu.org>
+
+       Make sort stable (bug 12313).
+       
+       * sort.c: Don't need to include some headers anymore.
+       (static var min_buffers) New variable.
+       (static var max_buffers) New variable.
+       (static var allow_internal_sort) New variable.
+       (cmd_sort_cases) Add test mode.
+       (sort_execute) Rephrase.
+       (do_internal_sort) Don't try internal sorting if
+       allow_internal_sort is set.
+       (struct external_sort) Renamed `initial_runs' to `runs' and
+       updated all references.
+       (macro MIN_BUFFER_TOTAL_SIZE_RECS) Removed.
+       (macro MIN_BUFFER_SIZE_BYTES) Removed.
+       (macro MIN_BUFFER_SIZE_RECS) Removed.
+       (compare_initial_runs) Removed.
+       (struct record_run) Add member `idx'.
+       (write_initial_runs) Pass increasing values to process_case() as
+       index.
+       (process_case) Add `idx' parameter and use it to initialize new
+       `idx' member.
+       (allocate_cases) Limit allocated buffers to max_buffers.
+       (compare_record_run) Use new `idx' member for last resort
+       comparison, for stability.
+       (end_run) Call casefile_sleep() on irs->casefile, to prevent
+       running out of file descriptors.
+       (struct merge_state) Removed.
+       (merge) Don't need to allocate cases.  Always use MAX_MERGE_ORDER
+       unless we have fewer runs left.  Always merge consecutive runs,
+       for stability.  Return the final run.
+       (mod) Removed.
+       (choose_merge) New function.
+       (merge_once) Rewritten.
+
+Mon Mar 14 21:05:42 2005  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: (static var testing_mode) Move into
+       parse_command_line().
+       
+Mon Mar 14 21:05:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: (remove_range) New function.
+       (remove_element) New function.
+
+       * dictionary.c: (dict_delete_var) Use remove_element().
+
+       * flip.c: (cmd_flip) Ditto.
+
+Sun Mar 13 22:52:05 2005  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.q: (struct file_handle) `open_mode' should not be
+       const.
+       
+Sun Mar 13 22:40:54 2005  Ben Pfaff  <blp@gnu.org>
+
+       First phase of making SORT CASES stable (bug 12313).
+
+       * sort.c: (struct indexed_case) New structure.
+       (do_internal_sort) Rewrite to make internal sorting stable.
+       (compare_case_dblptrs) Removed.
+       (compare_indexed_cases) New function.
+
+Sun Mar 13 22:38:40 2005  Ben Pfaff  <blp@gnu.org>
+
+       Clean-ups.
+
+       * casefile.c: (casereader_read_xfer_assert) New function.
+
+       * dictionary.c: (dict_compact_case) New function.
+
+       * flip.c: (struct flip_pgm) New member idx_to_fv.
+       (cmd_flip) Initialize idx_to_fv member.
+       (destroy_flip_pgm) Free idx_to_fv member.
+       (flip_sink_write) Use struct flip_pgm member instead of case_sink
+       member.
+       (flip_sink_write) Ditto.
+
+       * vfm.c: (write_case) Use dict_compact_case() instead of
+       compact_case().
+       (compact_case) Removed.
+       (storage_source_create) Removed `dict' parameter.  All references
+       updated.
+
+       * vfm.h: (struct case_source) Removed `value_cnt' member.  All
+       references removed.
+       (struct case_sink) Removed `dict', `idx_to_fv' members.  All
+       references removed.
+
+Sun Mar 13 22:35:55 2005  Ben Pfaff  <blp@gnu.org>
+
+       More AGGREGATE fixes.
+
+       * aggregate.c: (accumulate_aggregate_info) Implement NMISS and
+       NUMISS for strings.  Fix FOUT, POUT, FGT, FLT, FIN, FOUT for
+       strings.
+       (initialize_aggregate_info) Fix initialization for MIN, MAX for
+       strings.
+
+Sat Mar 12 23:26:21 2005  Ben Pfaff  <blp@gnu.org>
+
+       Start work on testing and debugging AGGREGATE.
+
+       * aggregate.c: (cmd_aggregate) Use discrete bool variables instead
+       of a bit-map.  Require proper subcommand ordering.  Make OUTFILE
+       subcommand mandatory.
+       (parse_aggregate_functions) Check that PIN, POUT, FIN, FOUT
+       functions' arguments are in the correct order and swap them if
+       not.
+       (accumulate_aggregate_info) Make SUM include weights.  Add various
+       string functions.
+       (dump_aggregate_info) Add various string functions.
+       (initialize_aggregate_info) Initialize int1 for MIN, MAX.
+
+       * sort.c: (sort_parse_criteria) Add parameter for returning
+       whether any directions were specified.  All callers updated.
+
+Sun Mar 13 14:54:27 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q: Fixed erroneous logic in compare_group_binary.
+
+Sat Mar 12 13:29:21 2005  Ben Pfaff  <blp@gnu.org>
+
+       * split-file.c: (cmd_split_file) Ignore LAYERED and SEPARATE
+       keywords (bug 11628).
+
+Sat Mar 12 13:17:12 2005  Ben Pfaff  <blp@gnu.org>
+
+       * vfm.c: (procedure_with_splits) Fix bug 11492: end_func() must be
+       called *before* close_active_file().
+
+Sat Mar 12 12:20:57 2005  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.q: (struct file_handle) Change open_mode from
+       character pointer to 3-char array, for safety.  Updated all
+       references.
+
+Sat Mar 12 12:15:49 2005  Ben Pfaff  <blp@gnu.org>
+
+       Thanks to Ben Kujala <bkujala@oregonchildcare.org> for reporting
+       these bugs.
+       
+       * pfm-read.c: (read_header) Improve error message for many cases
+       in which the input is not actually a portable file.
+
+       * file-handle.q: (fh_open) When we give an error message, actually
+       return NULL.
+
+Fri Mar 11 11:50:30 2005  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (check_common_specifier) New function for checks
+       common to check_input_specifier() and check_output_specifier().
+       (check_input_specifier) Use check_common_specifier().
+       (check_output_specifier) Use check_common_specifier().
+       (check_string_specifier) Removed.
+       (check_specifier_type) New function.
+       (check_specifier_width) New function.
+       (get_format_var_width) Fix bug.
+
+       * formats.c: (internal_cmd_formats) Only accept numeric variables.
+
+       * lexer.c: (check_id) Rename lex_id_to_token(), make public,
+       update all references.  Make case-insensitive.
+
+       * pfm-read.c: Essentially rewrite the whole file.  Now much
+       cleaner.
+
+       * print.c: (check_string_width) New function.
+       (fixed_parse_compatible) Use check_string_width(),
+       check_specifier_type().
+       (dump_fmt_list) Ditto.
+
+       * str.c: (st_trim_copy) New function.
+       (st_uppercase) New function.
+
+       * vars-atr.c: (var_is_valid_name) New function.
+       
+       * expressions/parse.c: (type_coercion_core) Use
+       check_specifier_type().
+       
+Fri Mar 11 11:31:24 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/evaluate.c: (cmd_debug_evaluate) Fix memory leaks.
+
+       * expressions/parse.c: (no_match) Ditto.
+
+Wed Mar  9 09:54:27 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pspp_LDADD) Add libgsl-extras.a.
+
+       * expressions/helpers.c: (struct func_params) Removed.
+       (generalized_idf) Removed.
+       (cdf_beta) Removed.
+       (idf_beta) Removed.
+       (idf_fdist) Use gslextras_cdf_beta_Pinv() instead of idf_beta().
+
+       * expressions/operations.def: Implement IDF.BETA, CDF.BINOM,
+       CDF.GEOM, CDF.HYPER, CDF.NEGBIN, CDF.POISSON using gsl-extras.
+       Implement SIG.F, which I had overlooked previously.
+
+Tue Mar  8 12:47:53 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * command.c command.def glob.[ch] cmdline.c: Made DEBUG cmds
+       available only in testing mode.
+
+Sun Mar  6 23:25:40 2005  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: Use `bool' throughout, where relevant.
+
+Sun Mar  6 19:52:22 2005  Ben Pfaff  <blp@gnu.org>
+
+       DATA LIST with free-field formats should not have implied decimal
+       places (bug 12035).  Also clean up data-in.c a bit.
+
+       * data-in.h: (enum) Add DI_IMPLIED_DECIMALS.
+
+       * data-in.c: (apply_implied_decimals) New function.
+       (parse_numeric) Don't adjust exponent if DI_IMPLIED_DECIMALS not
+       set.  Also, get rid of gotos.
+       (parse_Z) Use apply_implied_decimals() if the field doesn't
+       contain a decimal point.
+       (parse_N) Use apply_implied_decimals().
+       (parse_IB) Ditto.
+       (parse_PIB) Ditto.
+       (parse_P) Ditto.
+       (parse_PK) Ditto.
+       (to_roman) Removed.
+       (parse_enum) New function.
+       (macro CHAR_IS_ROMAN) Removed.
+       (macro ROMAN_VALUE) Removed.
+       (parse_month) Use parse_enum().
+       (parse_weekday) Use parse_enum().
+       (parse_DATETIME) Use long for weekday.
+
+       * data-list.c: (read_from_data_list_fixed) Use
+       DI_IMPLIED_DECIMALS.
+
+Sun Mar  6 17:07:20 2005  Ben Pfaff  <blp@gnu.org>
+
+       When the lexer sees something like `-5' in the input, it has to
+       decide whether it's a negative numeric constant token or a '-'
+       token followed by a positive numeric constant token.  It always
+       decides on the former, and then the parser can call
+       lex_negative_to_dash() if it wants the latter.  However, this
+       doesn't work for the case of `-0', because negative zero is
+       (portably) indistinguishable from positive zero.  So now we divide
+       T_NUM into two tokens, T_POS_NUM and T_NEG_NUM, to make the
+       distinction clear.  This requires a little bit of extra effort,
+       because there were several references to T_NUM in the code base.
+       
+       * lexer.c: (lex_get) Use T_NEG_NUM and T_POS_NUM to distinguish
+       positive and negative numeric constants.
+       (lex_double_p) Renamed lex_is_number().  Changed return type to
+       bool.  Updated all relevant references to T_NUM to instead use
+       this function.
+       (lex_double) Renamed lex_number().  All references updated.
+       (lex_integer_p) Renamed lex_is_integer().  Changed return type to
+       bool.  All references updated.
+       (lex_token_representation) Understand T_NEG_NUM and T_POS_NUM.
+       (lex_negative_to_dash) Ditto.
+       (dump_token) Ditto.
+       
+       * lexer.h: (enum) Add T_POS_NUM, T_NEG_NUM.  Remove T_NUM.
+
+Sun Mar  6 22:09:20 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/operations.def: (NUMBER) Use DI_IMPLIED_DECIMALS.
+
+Sun Mar  6 19:33:24 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/operations.def: (VEC_ELEM_NUM) Treat user-missing
+       values as system-missing.
+
+       * expressions/parse.c: (parse_vector_element) Fix order of
+       arguments in call to expr_allocate_binary().
+
+Sun Mar  6 17:51:05 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/optimize.c: (optimize_tree) Fix optimization bug for
+       x**2.
+
+       * expressions/parse.c: (type_coercion_core) Set *node to NULL on
+       failure, as indicated by function comment.
+       (parse_binary_operators) Always return NULL on type_coercion()
+       failure.  Should have been doing this anyway, but bug in
+       type_coercion_core() filtered through.
+       (parse_add) Fix typo in user message.
+       (parse_primary) Understand T_NEG_NUM and T_POS_NUM.
+
+Sun Mar  6 10:47:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/operations.def: Add VALUE function.
+
+       * expressions/parse.c: (parse_function) Need an unary composite
+       node for variables in A TO B, not a variable node.  Use
+       allocate_unary_variable().
+       (parse_primary) Use allocate_unary_variable().
+       (allocate_unary_variable) New function.
+
+Thu Mar  3 23:53:32 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/PSPP_expressions.pm: Renamed it back to generate.pl
+       but fixed the real problem that was preventing the build from a
+       separate directory.  I liked it my way better ;-)
+       
+Thu Mar  3 23:17:51 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/parse.c: (expr_parse) Fix parameter type.  Thanks to
+       John Darrington <john@darrington.wattle.id.au> for reporting this
+       bug.
+
+Thu Mar  3 22:10:25 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * expressions/Makefile.am expressions/evaluate.h.pl
+         expressions/evaluate.inc.pl expressions/operations.h.pl
+         expressions/optimize.inc.pl expressions/parse.inc.p:
+
+         Renamed generate.pl to PSPP_expressions.pm and adjusted *.pl
+         to suit. 
+
+         Fixed everything so that it can be built from an arbitrary
+         directory.
+       
+Thu Mar  3 22:08:35 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * Makefile.am : Fixed up CLEANFILES target.
+
+Mon Feb 28 23:49:56 2005  Ben Pfaff  <blp@gnu.org>
+
+       * str.h: Changed `struct len_string' to `struct fixed_string', a
+       more accurate name.  Updated all references.
+
+Mon Feb 28 23:35:30 2005  Ben Pfaff  <blp@gnu.org>
+
+       Redo calendar support.  Should now be bug-for-bug compatible.
+       
+       * calendar.c: New file.
+
+       * calendar.h: New file.
+
+       * data-in.c: Use new calendar functions.
+       (parse_sign) Change sense of return value.
+       (calendar_error) New function.
+       (ymd_to_ofs) New function.
+       (ymd_to_date) New function.
+       (parse_DATE) Use new function.
+       (parse_ADATE) Ditto.
+       (parse_EDATE) Ditto.
+       (parse_SDATE) Ditto.
+       (parse_JDATE) Ditto.
+       (parse_QYR) Ditto.
+       (parse_MOYR) Ditto.
+       (parse_WKYR) Ditto.
+       (parse_TIME) Ditto.
+       (parse_DTIME) Ditto.
+       (parse_DATETIME) Ditto.
+
+       * data-out.c: (convert_date) Use new calendar functions.
+
+       * error.c: (err_vmsg) Changed interface to be more sensible.
+       Updated all callers.
+       (dump_message) Don't double new-lines (why did we do this
+       anyway?).
+
+Mon Feb 28 23:30:25 2005  Ben Pfaff  <blp@gnu.org>
+
+       * sfmP.h: (macro flt64) Moved here from pref.h.orig.
+       (macro FLT64_MAX) Moved here from pref.h.orig.
+
+Mon Feb 28 23:28:01 2005  Ben Pfaff  <blp@gnu.org>
+
+       * set.q: Support SET EPOCH.
+       (static var set_epoch) New var.
+       (aux_stc_custom_epoch) New function.
+       (stc_custom_epoch) New function.
+       (get_epoch) New function.
+       (stc_custom_pager) [USE_INTERNAL_PAGER] Fix bug.
+
+       * format.c: Make it possible just to check whether a specifier is
+       valid without emitting an error message.
+       (parse_format_specifier_name) Change interface, update all
+       callers.
+       (check_input_specifier) Ditto.
+       (check_output_specifier) Ditto.
+       (parse_format_specifier) Ditto.
+
+Mon Feb 28 23:24:08 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add DEBUG POOL.
+
+       * pool.c: (pool_destroy) Fix bug in deleting this pool from its
+       parent.
+       (pool_clear) Properly account for size of pool gizmo.
+       (pool_realloc) Ditto.
+       (pool_clone) New function.
+
+       * pool.h: Mark our allocation functions MALLOC_LIKE.
+
+Mon Feb 28 23:21:26 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Move many definitions into new top-level
+       Make.build.  Add expressions to SUBDIRS.  Add calendar.c,
+       calendar.h.  Remove expr-evl.c, expr-opt.c expr-prs.c, expr.h,
+       exprP.h, expr.def.
+
+       * case.c: (case_resize) New function.
+       (case_swap) New function.
+
+       * casefile.c: Include mkfile.h.
+
+Fri Feb 25 21:11:35 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * sfm-read.c: Fixed a buglet which caused a crash when trying
+       to read a non-existent file.
+
+Sun Feb 13 16:11:13 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 11955.
+
+       * aggregate.c: (parse_aggregate_functions) Code cleanup.
+       Important part: get rid of spurious copying of function->format to
+       destvar->print and destvar->write.
+
+Fri Feb 11 00:08:36 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug 11916, which was confusing a variable's `index' member
+       with the variable's position in a var_set.  Although these are
+       usually the same, they are not for array `var_set's.
+       
+       Took advantage of this bug as an opportunity to clean up and
+       rewrite parse_var_set_vars().
+
+       * vars-prs.c: (parse_vs_variable_idx) New function.
+       (parse_vs_variable) Reimplement in terms of
+       parse_vs_variable_idx().
+       (parse_var_idx_class) New function.
+       (add_variable) New function.
+       (add_variables) New function.
+       (parse_var_set_vars) Rewritten.
+       (struct var_set) Change `lookup_var' member that returns a
+       variable into `lookup_var_idx' member that returns an int.
+       Updated the var set implementations in obvious corresponding ways.
+       Used compare_var_ptr_names(), hash_var_ptr_name() just added.
+       
+Fri Feb 11 00:06:03 2005  Ben Pfaff  <blp@gnu.org>
+
+       Use our global variable compare & hash functions and give them
+       better names.  Add similar functions for dealing with double
+       pointers to variables.
+       
+       * vars-atr.c: (compare_variables) Renamed compare_var_names().
+       (hash_variable) Renamed hash_var_name().
+       (compare_var_ptr_names) New function.
+       (hash_var_ptr_name) New function.
+       
+       * t-test.q: (cmd_t_test) Use global compare_var_names(),
+       hash_var_name().
+       (compare_var_name) Removed.
+       (hash_var_name) Removed.
+
+Fri Feb 11 00:04:39 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fix dictionary bug.
+       
+       * dictionary.c: (compare_variable_dblptrs) Rename
+       compare_var_ptrs() and fix it to properly dereference the double
+       pointers.
+
+Mon Feb  7 09:58:15 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       crosstabs.q examine.q oneway.q q2c.c:  Added a q2c feature to 
+       declare subcommands as mandatory.  Closed bug #11843
+
+Sat Feb  5 20:35:10 WST 2005 John Darrington <john@darrington.wattle.id.au>
+       
+       * getline.c command.[ch] command.def:  Added (very rudimentary)
+       support for line  completion when in interactive mode.  Partially 
+       addresses bug #11693
+       
+Mon Jan 31 09:52:51 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q factor_stats.c oneway.q output.c pfm-read.c: Fixed some
+       problems revealed by valgrind.
+
+
+Wed Jan 26 11:44:11 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * set.q: Affixed a fix to the previous fix such that we'll be OK now
+       whether or not PAGER is set.
+
+Wed Jan 26 09:25:54 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * set.q: Copied the string produced by getenv("PAGER") thus avoiding
+       "invalid free" errors.  Hopefully fixes bug #11722
+
+       * compute.c expr-prs.c: Check that lvalues are populated before 
+       attempting to destroy them.  Closes bug #11676
+
+Tue Jan 25 21:01:43 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * aggregate.c: Initialised the complete agr_proc structure.
+       Closes bug #11675
+
+
+Sun Jan 23 23:02:21 2005  Ben Pfaff  <blp@gnu.org>
+
+       * print.c: (print_trns_free) Close the dfm writer if there is one,
+       fixing a memory leak.
+
+Mon Jan 24 12:24:36 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * glob.c oneway.q q2c.c t-test.q vfm.c: Still *more* memory leaks 
+       fixed.
+
+
+Fri Jan 21 19:54:14 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * linked-list.[ch] Added
+
+       * examine.q file-handle.[hq] font.h glob.c groff-font.c postscript.c 
+         set.q:    Yet more memory leaks
+
+Tue Jan 18 23:12:40 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q examine.q : More memory leaks fixed.
+
+Tue Jan 18 19:26:59 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q  factor_stats.[ch] get.c pfm-read.c: Plugged numerous
+       memory leaks.
+
+Mon Jan 10 14:43:45 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * ascii.c cartesian.c casefile.c chart.h devind.c 
+         examine.q frequencies.q
+         html.c output.h piechart.c plot-chart.c plot-hist.c
+
+         Integrated the chart rendering into the output stream
+         (currently only works for html).
+         
+         Removed gratuitous use of ifndef NO_CHARTS, and replaced with
+         dummy-chart.c for compiling without charts.
+
+       * mkfile.[ch] Created.  
+
+       * som.[ch] tab.[ch]: Changed name of som_table to som_entity
+       Added type element so we can tell if it's a chart or a table.
+
+       * chart.h examine.q piechart.c plot-chart.c plot-hist.c: changed the 
+       API of charts to be more like that of tables.
+
+Thu Jan 13 21:00:02 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c main.c: Moved the SIGINT handler from casefile.c to
+       main.c. Removed the handler for SIGQUIT.
+
+Mon Jan 10 14:43:45 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c: Added a signal handler to delete temp files on 
+       SIGINT and SIGQUIT
+
+       * permissions.c Inhibited the PERMISSIONS command when SAFER is on.
+
+       * command.def Added a lot more unimplemented commands.
+
+       * copyleft.[ch] cmdline.c Moved legal information to copyleft.c
+
+Sat Jan  8 23:58:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: (compare_initial_runs) Needed additional level of
+       dereferencing.
+       (merge_once) Fix plenty of stupid mistakes.
+
+Sat Jan  8 23:55:27 2005  Ben Pfaff  <blp@gnu.org>
+
+       * casefile.c: (casefile_sleep) Need to flush_buffer() after
+       calling casefile_to_disk() or we will lose the last block in the
+       file if the casefile started out as disk-based.
+       (casefile_get_reader) Initialize reader->destructive to 0.
+       (cmd_debug_casefile) Add new test pattern.
+       (test_casefile) Define new test pattern to make sure
+       casefile_sleep() works properly.
+
+Fri Jan  7 08:00:05 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * Makefile.am chart.[ch]  histogram.[ch] piechart.c (Modified);
+          plot-hist.c plot-chart.c (Added) Reorganised these files in an
+          attempt to seperate the creation and processing of charts from their
+          actuall renedering.
+
+        * examine.q frequencies.q generated charts conditional upon the NO_CHARTS
+          macro.
+
+Thu Jan  6 18:48:58 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * main.c Added a signal handler for SIGFPE
+
+       * sort.c Somewhat more robust fix to the previous entry.
+
+Wed Jan  5 21:23:31 2005  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: (merge) Fix assertion for proper Huffman merge pattern:
+       0 == 1 modulo 1.  See Knuth 5.4.9 (vol. 3, 2nd ed.,
+       pp. 361).  Thanks to John Darrington <john@cellform.com.au> for
+       reporting the bug.
+
+Wed Jan  5 22:42:26 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * case.h Fixed bug # 11307
+       
+Wed Jan  5 08:30:48 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * val-labs.c Fixed bug which caused a crash if VALUE LABELS had
+       a trailing slash.
+
+Mon Jan  3 17:44:37 2005  Ben Pfaff  <blp@gnu.org>
+
+       * pfm-read.c: (read_variables) Remove direct manipulation of
+       v->aux, which is no longer needed.  Fixes bug 11483.
+
+Sat Jan  1 19:01:16 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * data-list.c Fixed a bug in parsing delimiters.
+
+       * group.c vars-atr.c Fixed buglet in hash/compare functions for alpha
+       values.
+
+       * percentiles.c Properly handled calculation of Tukey hinges where
+       the number of data is small.
+
+       * oneway.q Used the generic value_to_string function for independent
+       variable instead of trying to do it ourselves.
+
+       * box-whisker.c Fixed a buglet which caused a crash if the number of
+       data was zero
+
+
+Fri Dec 31 16:47:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q box-whisker.c chart.h Implemented boxplots in EXAMINE
+
+       * percentiles.c Fixed some bugs when calculating percentiles when
+       there's a small number of cases.
+
+Wed Dec 29 08:18:08 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * percentiles.[ch] Added. Calculates percentiles and Tukey hinges
+
+       * examine.q factor_stats.[ch]  Added calculation of percentiles
+
+Fri Dec 24 15:09:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q Fixed bug #11227 Made t-test work when the independent
+       variable is alpha
+
+Sat Dec 11 11:43:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * factor_stats.c Fixed calculation of trimmed mean under various
+       special conditions.
+
+Sat Dec  4 17:14:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * histogram.c chart.[ch] factor_stats.c frequencies.q
+
+       Added code to calculate sensible histogram ranges and limits.
+
+Thu Dec  2 13:37:43 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * chart.h Updated to reflect many API changes.
+
+       * cartesian.c chart.c Moved the definitions of chart_write_{xy}scale from 
+       cartesian.c and into chart.c
+
+       * factorstats.[ch] Added the histogram calculations
+
+       * casefile.c Removed an unused variable.
+
+       * frequencies.q examine.q histogram.c  Reworked the API for 
+       histograms.
+
+       * piechart.c  Revised the API for piecharts.
+
+       * var.h  Moved the definitions of freq_tab and freq out of var.h
+       and into frequencies.q where they belong.
+       
+Tue Nov 30 21:10:20 2004  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: (flip_file) Check for off_t separately from fseeko(),
+       using AC_TYPE_OFF_T.
+
+Tue Nov 30 08:47:41 2004  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: (flip_file) If fseeko() is not available, use long int
+       for off_t.  Thanks to "Marshall DeBerry" <mdb@radix.net> for
+       reporting the problem.
+
+Mon Nov 29 12:20:59 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q factor_stats.[ch] Changed stderr to se_mean to avoid
+       conflict with stdio.
+
+Sun Nov 21 10:32:41 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * var-labs.c (var_to_string) Now returns null if the variable is null
+
+       * value-labels.c (value_to_string) Made it return null if either the 
+       value or the variable is null.
+
+       * hash.c (hsh_clear) Fixed a buglet.
+
+       * examine.q  factor_stats.[ch] Largely  rewrote, because I'd started 
+       with  the wrong model.
+
+       * casefile.[ch] Added a function to return the casereader.case_idx 
+       member
+
+       * examine.q  Implemented the extreme values results.
+
+John Darrington <john@darrington.wattle.id.au>
+
+       * settings.h set.c glob.[ch] frequencies.q q2c.c error.c lexer.[ch] 
+          output.[ch] getline.c 
+
+          Plugged some memory leaks
+
+Mon Nov 15 23:47:40 2004  Ben Pfaff  <blp@gnu.org>
+
+       Adopt GSL random number generators, paving the way for providing
+       the complete suite of random number generators on expressions.
+       
+       * Makefile.am: Remove random.c, random.h.
+
+       * random.c: Removed.
+
+       * random.h: Removed.
+
+       * algorithm.c: (algo_default_random) Use GSL functions.
+
+       * casefile.c: (test_casefile) Use GSL RNG functions.
+
+       * expr-evl.c: (expr_evaluate) Use GSL RNG functions for OP_NORMAL,
+       OP_UNIFORM.
+
+       * sample.c: (cmd_sample) Use GSL RNG functions.
+       (sample_trns_proc) Ditto.
+
+       * set.q: (static var set_seed) Removed.
+       (static var seed_flag) Removed.
+       (static var rng) New variable.
+       (aux_stc_custom_seed) No seed value anymore, don't print anything.
+       (stc_custom_seed) Use new seed functions.
+       (seed_is_set) Removed.
+       (get_rng) New function that composes the entire external
+       interface.
+       (set_rng) New function.
+       (random_seed) New function.
+
+Mon Nov 15 22:08:25 2004  Ben Pfaff  <blp@gnu.org>
+
+       * expr-evl.c: (expr_evaluate) Fix XDATE.JDAY formula.  Thanks to
+       John Darrington <john@darrington.wattle.id.au> for reporting this
+       bug.
+
+Tue Nov 16 13:19:18 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * permissions.c command.def Added the PERMISSIONS command
+
+Mon Nov 15 01:33:32 2004  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: (dump_header) Don't try to emit #includes at very top of
+       output file because that will precede #include <config.h>, which
+       is bad.
+       (main) Add needed headers to /* (header) */ code.
+
+Mon Nov 15 01:21:36 2004  Ben Pfaff  <blp@gnu.org>
+
+       Instead of making system or portable file readers responsible for
+       dropping and reordering variables, make them read full cases and
+       let the caller take care of any changes.
+
+       * get.c: New "case map" structure to handle this.  Use for GET,
+       IMPORT, MATCH FILES.  Essentially rewrite the whole file.
+
+       * pfm-read.c: (pfm_read_case) Read into provided case.  Signature
+       changed appropriately.
+
+       * sfm-read.c: (sfm_read_case) Ditto.
+
+Mon Nov 15 00:47:45 2004  Ben Pfaff  <blp@gnu.org>
+
+       Decided that case_serialize() and case_unserialize() were too
+       abstract.  Also we need a couple more functions to avoid excessive
+       copying for data in/out fast paths.
+
+       * case.c: (case_serial_size) Removed.
+       (case_serialize) Rename case_to_values() and make its argument
+       explicitly an array of union values.
+       (case_unserialize) Rename case_from_values() and make its argument
+       explicitly an array of union values.
+       (case_data_all) New function.
+       (case_data_all_rw) New function.
+
+       * casefile.c: (struct casefile) Change buffer from array of
+       unsigned char to array of union value for better accuracy.
+       Redefine buffer_used and buffer_size in terms of values, not
+       bytes.  Remove case_size because it is now redundant with
+       value_cnt.  Fix up all references to these members.
+
+Mon Nov 15 00:45:46 2004  Ben Pfaff  <blp@gnu.org>
+
+       * barchart.c: (struct subcat) Make `label' member const to silence
+       GCC warning with -Wwrite-strings.
+
+       * cartesian.c: (struct dataset) Ditto.
+
+       * case.c: Don't re-define NDEBUG if already defined.
+       Add lots of comments.
+
+       * str.c: Fix includes.
+
+       * crosstabs.q: Fix includes.
+
+       * examine.q: Fix includes.  Fix GCC warning about unused
+       variables.
+       
+       * frequencies.q: (stat macro) Removed and replaced where used by
+       its expansion.
+
+       * list.q: Fix includes.
+
+       * oneway.q: Fix includes.
+
+       * piechart.c: Fix includes.  Only define M_PI if not already
+       defined.
+
+       * sfm-read.c: (bswap) New function.
+       (bswap_int32) Write in terms of bswap.
+       (bswap_flt64) Ditto.
+
+       * str.c: (ds_data) Add external definition here, needed because
+       str.h has only an `extern inline' version.
+
+       * value-labels.c: Fix includes.
+
+Mon Nov 15 00:40:55 2004  Ben Pfaff  <blp@gnu.org>
+
+       Instead of providing a system or portable file writer with a raw
+       case in the format needed for output, provide it with a regular
+       case.  The writer takes care of any needed translation.
+
+       * aggregate.c: Adopt new scheme for AGGREGATE.
+       (struct agr_proc) sfm_agr_case member removed.
+       (write_case_to_sfm) Removed because the new interface is easier to
+       use.
+
+       * get.c: Adopt new scheme for SAVE, XSAVE, EXPORT.
+
+       * pfm-write.c: Implement new scheme.
+
+       * sfm-write.c: Ditto.
+
+Mon Nov 15 00:32:24 2004  Ben Pfaff  <blp@gnu.org>
+
+       Instead of treating `struct file_handle' as a class to subclass
+       into data files, system files, and portable files, instead use it
+       as a helper that coordinates access.  Now it is opaque, too.
+
+       This means that most references to a struct file_handle are now
+       changed into references to one of struct dfm_reader, struct
+       dfm_writer, struct sfm_reader, struct sfm_writer, struct
+       pfm_reader, or struct pfm_writer, according to what's being read
+       or written.
+
+       Most related changes are only worth summarizing briefly.
+
+       * dictionary.c: (dict_clear) Destroy aux data in deleted
+       variables.
+       (dict_clear_aux) New function.
+       (dict_create_var) Initialize aux, aux_dtor.
+       (dict_delete_var) Destroy aux data in deleted variable.
+
+       * file-handle.h: (struct fh_ext_class) Removed.
+       (struct file_handle) Removed.
+       (fh_init_files) Removed.
+
+       * file-handle.q: Changed references to a handle's `private' member
+       to direct references.
+       (struct private_file_handle) Renamed file_handle.
+       Add next, open_cnt, type, open_mode, aux members.
+       (struct file_handle_list) Removed.
+       (extern var inline_file) Removed.
+       (static var file_handles) Changed from file_handle_list * to
+       file_handle *.
+       (create_file_handle) Initialize new members.
+       (fh_close_handle) Removed.
+       (mode_name) New function.
+       (fh_open) New function.
+       (fh_close) New function.
+       (fh_parse_file_handle) Renamed fh_parse().
+
+       * glob.c: (init_glob) Remove fh_init_files() call.
+       
+       * aggregate.c: use sfm_writer.
+       (create_sysfile) Removed because the new interface is simpler.
+       
+       * apply-dict.c: Use sfm_reader.
+
+       * data-list.c: Use dfm_reader.
+
+       * file-type.c: Use dfm_reader.
+
+       * get.c: Use sfm_reader, sfm_writer, pfm_reader, pfm_writer.
+
+       * inpt-pgm.c: Use dfm_reader.
+
+       * print.c: Use dfm_writer.
+
+       * sysfile-info: Use sfm_reader.
+
+       * dfm-read.c: Adopt new file handle infrastructure.
+
+       * dfm-write.c: Ditto.
+
+       * pfm-read.c: Ditto.
+       
+       * pfm-write.c: Ditto.
+
+       * sfm-read.c: Ditto.
+
+       * sfm-write.c: Ditto.
+       
+Mon Nov 15 00:31:44 2004  Ben Pfaff  <blp@gnu.org>
+
+       Break dictionary functions into separate header file.
+
+       * dictionary.h: New file.
+
+       * var.h: Moved dict_*() functions to dictionary.h.
+
+Mon Nov 15 00:30:33 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of procedure-specific union in struct variable, using
+       instead a void * pointer and a destructor function.
+
+       Most related changes are only worth brief summaries.
+
+       * crosstabs.q: Fix includes.  Use new struct var_range in lieu of
+       old p.crs member in struct variable.
+       
+       * frequencies.q: Fix includes.  Use new struct var_freqs in lieu
+       of old p.frq member in struct variable.
+
+       * histogram.c: (draw_histogram) Takes new freq_tab arg because
+       it's no longer possible to grab this from var->p.frq.
+
+       * piechart.c: (draw_piechart) Ditto.
+
+       * group.c: (group_proc_get) New function.
+
+       * levene.c: Use group_proc_get() in lieu of old p.grp_data member
+       in struct variable.
+
+       * oneway.q: Ditto.
+
+       * t-test.q: Ditto.
+
+       * main.c: (execute_command) Clear aux data in default_dict after
+       each command.  (It's debatable whether this should be done.)
+
+       * matrix-data.c: Use new struct mxd_var in lieu of old p.mxd
+       member in struct variable.
+
+       * means.q: Get rid of integer mode, which is not included in
+       recent SPSS and was the only code that wanted per-variable private
+       data.
+
+       * var.h: (struct crosstab_proc) Removed.
+       (struct frequencies_proc) Removed.
+       (struct list_proc) Removed.
+       (struct get_proc) Removed.
+       (struct means_proc) Removed.
+       (struct matrix_data_proc) Removed.
+       (struct match_files_proc) Removed.
+       (lots of enums) Removed.
+       (struct variable) Removed members `p', `get'.  Add member
+       `aux_dtor'.
+
+       * vars-atr.c: (var_attach_aux) New function.
+       (var_detach_aux) New function.
+       (var_clear_aux) New function.
+       (var_dtor_free) New function.
+       (discard_variables) Use NULL instead of inline_file.
+
+Fri Nov 12 10:07:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * value-labs.c  Fixed the implmentation of value_to_string, so 
+       that it properly handles alpha values.
+
+       * oneway.q  Changed instances where labels were being probed manually, 
+       to use the canonical {var,value}_to_string functions
+
+Thu Nov 11 21:01:31 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q cartesian.c chart.[ch]   Added normal and detrended normal
+       plots.  Changed the API of the cartesian plot to be a much lower level
+       thing.
+
+Sun Nov  7 17:25:04 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q Added some of the parametric calculations
+
+       * factor_stats.[ch]  Created
+       
+Sat Nov  6 21:24:31 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q  Changed the definition of factors to be a composite, and
+       dealt with the consequences.
+
+Sat Nov  6 20:40:38 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q Fixed problem where examine wasn't dealing properly with 
+       splits
+
+Sat Nov  6 14:49:47 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * oneway.q Fixed problem where oneway wasn't dealing properly with 
+       splits
+
+Thu Nov  4 11:09:01 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * q2c.c examine.q  Fixed a bug (feature?) whereby arrays in the
+       command which had settings didn't get the appropriate code
+       generated.
+
+       * val.h value-labels.[ch] var-labs.c Added v*to_string functions
+       to convert variables/values to strings.
+
+       * examine.q  Added framework for the EXAMINE command.
+
+Mon Nov  1 12:46:17 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * q2c.c frequencies.q set.q t-test.q  Fixed the q2c parsing of DBL 
+       subcommand types.  Changed frequencies.q to use it rather then the 
+       custom parser.  Dealt with the consequences.  Added a test for NTILES
+       subcommand of frequencies.
+
+Sat Oct 30 09:16:29 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * oneway.q   Fixed up the behaviour when given missing values
+
+       * levene.c oneway.q Fixed a buglet with the levene statistic and
+       incorporated the levene test into the oneway command.
+
+        * group.h  t-test.q  Moved the CMP_EQ and CMP_LE symbols out of 
+       global scope, since they're only relevant to T-TEST
+
+Fri Oct 29 17:39:03 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+        * group.c group.h group_proc.h levene.c oneway.q t-test.q
+
+       Made the t-test more consistent
+       with the way it handles groups.  That is, it now uses a hash instead
+       of an array of 2.  Also, made the levene.c file independent of the 
+       implementation of the t-test.  So now levene should be fine for both
+       t-test and anova.
+
+       * Added an oneway.q file for one way anova
+
+Wed Jun  2 22:08:02 2004  Ben Pfaff  <blp@gnu.org>
+
+       * descript.c: (cmd_descriptives) Remove harmless but bogus test in
+       STATISTICS parsing.
+
+Mon May 31 20:45:24 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fix memory leaks.
+
+       * data-list.c: (cmd_data_list) Free dls->delims on lossage.
+       (data_list_trns_free) Free dls->delims.
+
+       * t-test.q: (tts_custom_pairs) Free vars.
+       (ssbox_one_sample_init) Fix tab_vline() argument.
+       (ssbox_independent_samples_init) Ditto.
+       (trbox_paired_init) Ditto.
+       (trbox_one_sample_init) Ditto.
+
+Mon May 31 17:19:27 2004  Ben Pfaff  <blp@gnu.org>
+
+       Generalize casefiles to the extent that we can use them for
+       sorting and other kinds of data transformations.  Change cases to
+       be copy-on-write to improve memory efficiency in common cases.
+       Every access to a member of a `struct ccase' was changed to be a
+       call to a case_*() function, especially case_data(), case_num(),
+       case_str(), or case_data_rw().  Many instances of a local variable
+       named "case_num" were changed to "case_idx" as a consequence.
+       Many `struct ccase *' were changed to actual `struct ccase'
+       because of copying semantics of cases.  In several places there
+       was a choice between updating debug code to work with the new ADTs
+       or just deleting it because it was useless; I chose to delete it.
+       * Makefile.am: (pspp_SOURCES) Add case.c, case.h.
+
+       * case.c: New file.
+
+       * case.h: New file.
+
+       * aggregate.c: (struct agr_proc) Change type of `sort' to
+       sort_criteria *.  Add `break_vars', `break_var_cnt' members.
+       Rename `vars' to `agr_vars', all references updated.  Change
+       `agr_case' to type `struct ccase'.
+       (cmd_aggregate) Deal with new members.  Use case_create(),
+       sort_active_file_in_place(), sort_active_file_to_casefile().
+       (agr_destroy) Deal with new members.
+       (aggregate_single_case) Ditto.
+       (dump_aggregate_info) Ditto.
+       (initialize_aggregate_info) Ditto.
+       (agr_to_active_file) Ditto.
+       (presorted_agr_to_sysfile) Ditto.
+       (sort_agr_to_sysfile) Removed.
+
+       * alloc.c: (out_of_memory) Make non-static.
+
+       * alloc.h: Prototype out_of_memory().
+
+       * casefile.c: Switched from a linked list in-memory representation
+       to a two-level array-style representation.  The linked list was
+       appropriate when we could stick a header onto cases, but that's no
+       longer the case.  Also, the two-level array will allow for random
+       in-memory access in case that's ever wanted.  Also added the
+       concept of a `destructive casereader', one that destroys cases in
+       the underlying casefile as they are read out.
+       (macro CASES_PER_BLOCK) New macro.
+       (struct casefile) New members `value_cnt', `case_list_size',
+       `case_acct_size', `being_destroyed', `cases'.  Removed `head',
+       `tail'.
+       (struct casereader) Removed `cur'.  Added `destructive', `c'.
+       (global var casefiles) Made static.
+       (static var case_bytes) New var.
+       (casefile_create) Takes a value count, not a case size in bytes,
+       to conform to the case interface.  All callers updated.  Deal with
+       new and removed members.
+       (casefile_destroy) Deal with new and removed members.
+       (casefile_sleep) New function.
+       (casefile_get_case_size) Removed.
+       (casefile_get_value_cnt) New function.
+       (casefile_append) Rewritten to deal with new and removed members.
+       (casefile_append_xfer) New function.
+       (write_case_to_disk) Use case_serialize().
+       (call_posix_fadvise) Removed because posix_fadvise64 segfaults.
+       Couldn't figure out why.
+       (casefile_to_disk) Don't call call_posix_fadvise.  Rewritten to
+       deal with new and removed members.
+       (merge) Removed.
+       (merge_sort) Removed.
+       (casefile_sort) Removed.
+       (casefile_get_reader) Deal with new and removed members.
+       (casefile_get_destructive_reader) New function.
+       (reader_open_file) Make code more readable.  Create case for
+       reader.
+       (casereader_get_casefile) New function.
+       (casereader_read) Deal with new and removed members.  Now returns
+       a copy of the case, so that the caller is responsible for
+       destroying the returned case.
+       (casereader_read_xfer) New function.
+       (casereader_destroy) Destroy reader's case.
+       (test_casefile) Second arg is now a value count, all callers
+       updated.  Now tests destructive readers too.
+       (get_random_case) Deal with new case ADT.
+       (write_random_case) Ditto.
+       (read_and_verify_random_case) Ditto.
+
+       * crosstabs.q: Remove debug code.
+
+       * descript.q: (calc_descriptives) Deal with new case, casefile
+       ADTs.
+
+       * dfm.c: (cmd_begin_data) There's no storage_source_class anymore.
+
+       * do-if.c: Remove unneeded header inclusion.
+
+       * expr-prs.c: Remove debug code.
+
+       * exprP.h: Remove debug code.
+
+       * flip.c: (flip_file) Use fseeko() if available.
+
+       * formats.c: Remove debug code.
+
+       * get.c: Remove debug code.
+       (struct mtf_file) Change `input' from `union value *' to `struct
+       ccase', all references updated.
+
+       * levene.c: (levene) Deal with new case, casefile ADTs.
+
+       * list.q: Remove debug code.
+
+       * loop.c: Remove debug code.
+       
+       * matrix-data.c: Remove debug code.
+
+       * means.q: Remove debug code.
+
+       * mis-val.c: Remove debug code.
+
+       * pfm-read.c: Remove debug code.
+       (pfm_read_code) Change second arg from `union value *' to `struct
+       ccase *', all references updated.
+
+       * recode.c: (string_to_long) Make first arg const.
+       (convert_to_double) Ditto.
+
+       * repeat.c: Remove debug code.
+
+       * sample.c: Remove debug code.
+
+       * sfm-read.c: Remove debug code.
+       (sfm_read_case) Change second arg from `union value *' to `struct
+       ccase *'.
+
+       * sort.c: Redone in terms of casefiles.
+       (enum sort_direction) Moved here from sort.h.
+       (struct sort_criterion) New structure.
+       (struct sort_criteria) New structure.
+       (cmd_sort_cases) Rewritten.
+       (prepare_to_sort_active_file) New function.
+       (sort_active_file_in_place) New function.
+       (sort_active_file_to_casefile) New function.
+       (parse_sort) Renamed sort_parse_criteria(), rewritten & interface
+       changed, all callers updated.
+       (destroy_sort_cases_pgm) Renamed sort_destroy_criteria(),
+       rewritten & interface changed, all callers updated.
+       (sort_cases) Renamed sort_execute(), rewritten & interface
+       changed, all callers updated.
+       (struct internal_sort) Removed.
+       (do_internal_sort) Rewritten, interface changed.
+       (destroy_internal_sort) Removed.
+       (compare_case_dblptrs) Use sort_criteria instead of sort_case_pgm.
+       (struct initial_run) Removed; an initial run is now just a
+       casefile.
+       (compare_initial_runs) Rewritten.
+       (struct external_sort) Changed almost completely.
+       (do_external_sort) Rewritten, interface changed.
+       (destroy_external_sort) Rewritten.
+       [HAVE_MKDTEMP] (make_temp_dir) Removed.
+       [!HAVE_MKDTEMP] (do_mkdir) Removed.
+       [!HAVE_MKDTEMP] (make_temp_dir) Removed.
+       (init_external_sort) Removed.
+       (simulate_error) Removed.
+       (rmdir_temp_dir) Removed.
+       (get_temp_file_name) Removed.
+       (open_temp_file) Removed.
+       (close_temp_file) Removed.
+       (remove_temp_file) Removed.
+       (write_temp_file) Removed.
+       (read_temp_file) Removed.
+       (struct record_run) Change `record' from `struct case_lit *' to
+       `struct ccase'.
+       (struct initial_run_state) Remove `idx_to_fv', `free_list',
+       `file_idx', `output_file'.  Add `run', casefile'.  Change
+       `last_output' from `struct case_list *' to `struct ccase'.
+       (write_initial_runs) Change interface, rewrite.
+       (sort_sink_write) Renamed process_case(), changed interfaced,
+       rewrote.
+       (destroy_initial_run_state) Rewritten.
+       (allocate_cases) Rewritten.
+       (compare_record) Interface changed, rewritten.
+       (start_run) Rewritten.
+       (end_run) Rewritten.
+       (output_record) Rewritten.
+       (grab_case) Removed.
+       (release_case) Removed.
+       (struct merge_case) Change `cases' from double pointer to single
+       pointer.
+       (merge) Deal with new case and casefile ADTs.
+       (struct run) Removed.
+       (merge_once) Rewritten, interface changed.
+       (fill_run_buffer) Removed.
+       (sort_sink_make_source) Removed.
+       (sort_sink_class) Removed.
+       (struct sort_source_aux) Removed.
+       (sort_source_read_helper) Removed.
+       (sort_source_read) Removed.
+       (read_sort_output) Removed.
+       (read_internal_sort_output) Removed.
+       (read_external_sort_output) Removed.
+       (sort_source_destroy) Removed.
+       (sort_source_class) Removed.
+
+       * sort.h: (struct sort_cases_pgm) Removed.
+       (enum sort_direction) Moved to sort.c.
+
+       * t-test.q: (calculate) Deal with new case, casefile ADTs.
+
+       * tab.c: Remove debug code.
+
+       * var-labs.c: Remove debug code.
+
+       * var.h: (struct ccase) Removed.
+       (struct case_list) Removed.
+
+       * vars-atr.c: (discard_variables) Use free_case_source().
+
+       * vars-prs.c: (parse_vs_variable) Make arg const.
+       (parse_dict_variable) Ditto.
+       (parse_variables) Make struct dictionary * arg const.
+       (parse_var_set_vars) Make struct var_set * arg const.
+       (struct var_set) Add const to some of the function pointers' args.
+       (var_set_get_cnt) Make arg const.
+       (var_set_get_var) Make first arg const.
+       (var_set_lookup_var) Make first arg const.
+       (dict_var_set_get_cnt) Make arg const.
+       (dict_var_set_get_var) Make first arg const.
+       (dict_var_set_lookup_var) Make first arg const.
+       (var_set_create_from_dict) Make arg const.  Add cast to aux
+       assignment.
+       (struct array_var_set) Add const to var member.
+       (array_var_set_get_cnt) Make arg const.
+       (array_var_set_get_var) Make first arg const.
+       (array_var_set_lookup_var) Make first arg const.
+       (var_set_create_from_array) Make first arg const.  Insert cast.
+
+       * vfm.c: (struct write_case_data) Change trns_case, sink_case
+       members from `struct ccase *' to `struct ccase'.
+       (static var lag_queue) Change from double to single pointer.
+       (procedure) Optimize trivial case.
+       (internal_procedure) Deal with changed case, case_source ADTs.
+       (create_trns_case) Changed interface, rewrote.
+       (open_active_interface) Initialize modified lag queue.
+       (write_case) Deal with changed case ADT.
+       (lag_case) Deal with modified lag queue.
+       (close_active_file) Destroy modified lag queue.
+       Deal with changed case_source, case_sink ADTs.
+       (destroy_storage_stream_info) Make null arg into no-op.
+       (storage_sink_make_source) Set aux in created source.
+       (storage_source_read) Deal with changed case, casefile ADTs.
+       (storage_source_create) New function.
+       (lagged_case) Rewrite.
+       (free_case_source) New function.
+       (free_case_sink) Rewrite.
+       (struct split_aux_data) Changed prev_case from `struct ccase *' to
+       `struct ccase'.
+       (procedure_with_splits) Deal with changed prev_case.
+       (procedure_with_splits_callback) Ditto.
+       (multipass_split_aux_data) Changed prev_case from `struct ccase *' to
+       `struct ccase'.
+       (multipass_procedure_with_splits) Deal with changed prev_case.
+       (multipass_split_callback) Ditto.
+       
+       
+Mon May 31 17:19:06 2004  Ben Pfaff  <blp@gnu.org>
+
+       The workspace idea didn't work out.
+
+       * Makefile.am: (pspp_SOURCES) Remove workspace.c, workspace.h.
+       
+       * workspace.c: Removed.
+
+       * workspace.h: Removed.
+
+Sun May 30 18:35:19 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fully implement arbitrary delimiters on DATA LIST, extending the
+       half implementation that was already there.
+
+       * data-list.c: (struct data_list_pgm) Remove `delim', add
+       `delims', `delim_cnt'.
+       (cmd_data_list) Initialize new members.  Parse delimiters and
+       clean up code a bit.
+       (cut_field) Extract fields with arbitrary delimiters.  Also, fix
+       handling of leading commas.
+       (read_from_data_list_fixed) Expand tabs.  Adapt to new DFM
+       interfaces.
+       (read_from_data_list_free) Adapt to new DFM interfaces.
+       (read_from_data_list_list) Ditto.
+       (repeating_data_trns_proc) Ditto.
+
+       * dfm.c: Split up reader and writer into separate code, because
+       they do different things.  Use struct string instead of explicit
+       allocation code, for clarity.
+       (enum dfm_reader_flags) New enum.
+       (struct dfm_fhuser_ext) Removed.
+       (struct dfm_reader_ext) New.
+       (get_reader) New function, used by just about all the reader
+       functions.
+       (dfm_close) Removed.
+       (close_reader) New function.
+       (dfm_open_for_reading) Rewrite initialization of dfm_fhuser_ext.
+       (dfm_open_for_writing) Ditto.
+       (macro force_line_buffer_expansion) Removed.
+       (count_tabs) Removed.
+       (tabs_to_spaces) Removed.
+       (read_record) Deal with new dfm_reader_ext.  Use struct string
+       functions.  Don't convert tabs to spaces.
+       (dfm_eof) New function.
+       (dfm_get_record) Changed interface, rewrote.
+       (dfm_expand_tabs) New function.
+       (dfm_fwd_record) Renamed dfm_forward_record(), updated to new
+       dfm_reader_ext, rewritten.
+       (dfm_bkwd_record) Renamed dfm_reread_record(), updated to new
+       dfm_reader_ext, rewritten.
+       (dfm_set_record) Removed in favor of dfm_forward_columns().
+       (dfm_forward_columns) New function.
+       (dfm_get_cur_col) Renamed dfm_column_start, updated to new
+       dfm_reader_ext, rewritten.
+       (static var dfm_r_class) Use close_reader for the destructor.
+       (struct dfm_writer_ext) New.
+       (dfm_put_record) Updated to new dfm_writer_ext, rewritten.  Uses
+       bounce buffer now instead of local allocation.
+       (close_writer) New function.
+       (static var dfm_writer_ext) Use close_writer for destructor.
+       (cmd_begin_data) Adapt to new dfm_reader_ext.
+
+       * file-handle.q: Add support for per-file tab width.
+       (struct private_file_handle) Add tab_width member.
+       (q2c specifications) Add tabwidth subcommand.
+       (cmd_file_handle) Put parsed tab width into private_file_handle.
+       (create_file_handle) Set default tab width.
+       (handle_get_tab_width) New function.
+
+       * file-type.c: (file_type_source_read) Adapt to new DFM interface.
+
+       * inpt-pgm.c: (reread_trns_proc) Ditto.
+
+       * matrix-data.c: (context) Ditto.
+       (another_token) Ditto.
+       (mget_token) Ditto.
+       (force_eol) Ditto.
+
+Sun May 30 18:33:59 2004  Ben Pfaff  <blp@gnu.org>
+
+       * casefile.c: (casefile_destroy) Fix memory leak by freeing
+       cf->filename.
+       (casereader_destroy) Don't close file descriptor -1.
+
+       * recode.c: (cmd_recode) Fix memory leak.
+
+       * set.q: (q2c specifications) Fix typo in user message.
+
+       * str.c: (st_bare_pad_len_copy) Change memcpy to memmove to avoid
+       undefined behavior for overlapping arguments.
+
+Sun May 30 18:31:48 2004  Ben Pfaff  <blp@gnu.org>
+
+       * casefile.c: valgrind doesn't implement posix_fadvise() yet, so
+       don't call it when we're running under valgrind.
+       (call_posix_fadvise) New function.
+       (casefile_to_disk) Use call_posix_fadvise().
+       (reader_open_file) Ditto.
+       
+Sun May 30 18:20:12 2004  Ben Pfaff  <blp@gnu.org>
+
+       Update our string ADTs, struct string and struct len_string.  Get
+       rid of pool support, which was largely unused.  Rename lots of
+       functions to have more obvious or consistent names.
+       
+       * ascii.c: Get rid of ascii_pool.  It was only used for string
+       allocations.
+       (ascii_open_global) Don't create ascii_pool.
+       (ascii_close_driver) Don't destroy ascii_pool.
+       (ascii_postopen_driver) Don't use pool.
+       (ascii_close_driver) Destroy strings manually.
+
+       * str.c: (ds_create) Remove pool argument, all references updated.
+       (ds_init) Ditto.
+       (ds_replace) Remove pool support, make more efficient when we
+       don't need to reallocate.
+       (ds_destroy) Remove pool support.
+       (ds_rpad) New function.
+       (ds_size) Renamed ds_capacity(), all references updated.
+       (ds_value) Renamed ds_c_str(), all references updated.
+       (ds_concat) Renamed ds_puts(), all references updated.
+       (ds_concat_buffer) Renamed ds_concat(), all references updated.
+       (ds_putchar) Renamed ds_putc(), all references updated.
+       (ds_getline) Renamed ds_gets(), all references updated.
+       (ls_create) Remove pool argument, all references updated.
+       (ls_create_buffer) Ditto.
+       (ls_destroy) Removed pool support.
+       (ls_value) Renamed ls_c_str(), all references updated.
+
+       * str.h: (ls_length) [__GNUC__] Add inline version.
+       (ls_c_str) [__GNUC__] Add inline version.
+       (ls_end) [__GNUC__] Add inline version.
+       (struct string) Remove pool member.  Rename `size' to `capacity',
+       all references updated.
+
+       * tab.c: (text_format) Instead of using pool argument to
+       ls_create_buffer(), call pool_register() on allocated data.
+
+Mon Apr 26 22:40:07 2004  Ben Pfaff  <blp@gnu.org>
+
+       We're abusing the current ASCII driver by telling it to allocate a
+       9999-line, 9999-character page in the tests.  This causes some
+       systems to curl up and die because it allocates 20 MB of
+       contiguous RAM.  This change alleviates at least part of the
+       problem.  It is mostly a stop-gap until the new output system is
+       ready.
+       
+       * ascii.c: (struct line) New structure.
+       (struct ascii_driver_ext) Remove `page', `page_size', `line_len',
+       `line_len_size', `n_output' members.  Add `lines', `lines_cap'.
+       (ascii_preopen_driver) Initialize new members, not old ones.
+       (ascii_close_driver) Destroy new members, not old ones.
+       (ascii_open_page) Allocate new members, not old ones.
+       (expand_line) Allocate room in line.
+       (draw_line) Use new members.
+       (ascii_line_horz) Ditto.
+       (ascii_line_vert) Ditto.
+       (ascii_line_intersection) Ditto.
+       (text_draw) Ditto.
+       (output_lines) Ditto.
+       (ascii_close_page) Ditto.
+
+Sun Apr 25 23:40:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       * matrix.c: Dead code.  Removed.
+
+       * matrix.h: Dead code.  Removed.
+
+Fri Apr 16 23:59:51 2004  Ben Pfaff  <blp@gnu.org>
+
+       Contrary to what I'd always understood, there is an efficient
+       algorithm for deletion from a hash table populated via linear
+       probing.  This change implements it.
+       
+       * hash.c: (hsh_rehash) Probe in increasing order.
+       (hsh_probe) Ditto.
+       (locate_matching_entry) Ditto.
+       (hsh_delete) Use Knuth's Algorithm 6.4R for deletion.
+
+Tue Apr 13 19:24:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       * moments.c (calc_moments): Adjust calculation of kurtosis to
+       avoid subtracting huge numbers from huge numbers, on Michael
+       Kiefte's advice.
+
+Sun Apr 11 14:22:12 2004  Ben Pfaff  <blp@gnu.org>
+
+       Rework moments routines for improved numerical stability based on
+       Michael Kiefte's advice.  Any bugs or remaining numerical problems
+       are still mine though.
+
+       There is now a struct moments1 for use with one-pass moments.  It
+       uses a provisional means algorithm as an attempt to improve
+       accuracy of higher moments.  The older struct moments now only
+       handles two-pass moments.
+       
+       * aggregate.c: Use moments1 instead moments.
+
+       * descript.c: Revert previous change, which is no longer needed
+       due to the moments revision.
+
+       * moments.c: (calc_moments) New function for calculating variance,
+       skewness, kurtosis.
+       (moments_pass_one) Only accumulate weights bigger than zero.
+       (moments_calculate) Allow calculating the mean on pass one, others
+       require pass two.  Implement in terms of calc_moments().
+       (struct moments1) New structure.
+       (init_moments1) New function.
+       (moments1_clear) Ditto.
+       (moments1_create) Ditto.
+       (moments1_add) Ditto.
+       (moments1_calculate) Ditto.
+       (moments1_destroy) Ditto.
+       (cmd_debug_moments) Deal with `struct moments' or `struct
+       moments1' as requested by user.
+
+Sun Apr 11 14:21:55 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am (pspp_SOURCES): Remove debug.c.
+
+       * debug.c: Removed.  It was empty anyway.
+
+Fri Apr  9 20:04:49 2004  Ben Pfaff  <blp@gnu.org>
+
+       * descript.c (calc_descriptives): Fix assert failure when only
+       MOMENT_MEAN is needed.
+
+2004-04-09  Michael Kiefte  <mkiefte@dal.ca>
+
+       * descript.c: 
+
+       fixed problem with parsing in match_statistic() causing
+       "DESCRIPTIVE STAT=MEAN." to barf.
+
+       "MEAN" is now default if "SORT" given without specification.
+
+       Fixed infinite loop with "DESCRIPT GIBBERISH=ALL."  Parsing is
+       generally less forgiving of syntax errors: better to have it do
+       nothing and type it in again then to not know what it actually did
+       instead.  
+
+       z-score transformation now checks score for user-missing values
+       and checks std_dev for SYSMIS.
+
+2004-04-06  Michael Kiefte  <mkiefte@dal.ca>
+
+       * aggregate.c, crosstabs.q, descript.c, dictionary.c, frequencies.q, levene.c, t-test.q, var.h: 
+       Changed dict_get_case_weight() to accept an additional int * flag
+       to complain about system-missing, user-missing, zero, or negative
+       weights and updated existing functions to pass int * to
+       dict_get_case_weight().
+
+2004-04-05  jmd  <jmd@gnu.org>
+
+       * main.c: Fixed configuration problems with gsl
+
+       * t-test.q: Fixed some problems encountered when compiling under Cygwin
+
+2004-04-03  blp  <blp@gnu.org>
+
+       * lexer.c, ChangeLog:
+       Fix infinite loop on comment at end of file, add test.
+
+2004-04-03  jmd  <jmd@gnu.org>
+
+       * settings.h, var.h, ChangeLog, Makefile.am, cmdline.c, command.c, command.h, error.h, filename.c, frequencies.q, lexer.h, main.c, q2c.c, set.q:
+       Fixed the calculation of percentiles and added --syntax and --algorithm options
+
+Sat Apr  3 11:43:37 2004  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (lex_skip_comment) Handle end-of-file correctly (I
+       hope).
+
+Sat Apr  3 15:00:18 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+        * frequencies.q:  Fixed the calculation of percentiles
+
+       * Makefile.am:  Added the --ansi flag and dealt with the
+       consequences.  Added some entries to PSPP_sources so that
+       make distcheck would pass
+
+       * cmdline.c:   Added the --syntax and --algorithm options
+
+       * q2c.c:  Added an implicit /ALGORITHM subcommand to everything.
+
+Fri Apr  2 11:25:22 WAST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q, levene.c, levene.h  Converted t-test (incl levene) to 
+       use the new multipass_split_... mechanism.
+
+Wed Mar 31 22:36:22 2004  Ben Pfaff  <blp@gnu.org>
+
+       * frequencies.q: (calc_stats) Use moments data structure and
+       calc_seskew(), calc_sekurt() functions.
+
+       * set.q main.c settings.h Added support for --syntax and --algorithm 
+       options
+
+Tue Mar 30 22:04:19 2004  Ben Pfaff  <blp@gnu.org>
+
+       * vfm.c: Had to get last call to multipass_split_output() inside
+       open_active_file()/close_active_file() pairing, so introduce new
+       function.
+       (internal_procedure) Move procedure() code here, except for calls
+       to open_active_file() and close_active_file().
+       (procedure) Wrap open_active_file() and close_active_file() around
+       internal_procedure().
+       (multipass_procedure_with_splits) Wrap open_active_file() and
+       close_active_file() around internal_procedure().
+
+Tue Mar 30 22:01:57 2004  Ben Pfaff  <blp@gnu.org>
+
+       * descript.c: (cmd_descriptives) Free `vars' to avoid memory leak.
+
+Mon Mar 29 16:26:40 2004  Ben Pfaff  <blp@gnu.org>
+
+       * debug.c: Removed.  Moved cmd_debug_evaluate() into expr-evl.c.
+
+       * expr-evl.c: (cmd_debug_evaluate) Moved here from debug.c.
+
+Mon Mar 29 16:03:08 2004  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: By default turn off some of the more expensive
+       assertions.
+       (expensive_assert) New macro which expands to assert if
+       EXTRA_CHECKS is defined, to nothing otherwise.
+       (unique) Use expensive_assert().
+       (binary_search) Ditto.
+       (push_heap) Ditto.
+       (pop_heap) Ditto.
+       (make_heap) Ditto.
+       (sort_heap) Ditto.
+
+       * command.c: (conflicting_3char_prefixes) Words that are the same
+       don't cause conflicts when they are abbreviated to the first three
+       letters.
+
+       * expr-evl.c: (CONCAT_func) Fix memory leak by incrementing struct
+       nonterm_node's n earlier.
+       (generic_str_func) Ditto.
+       
+Mon Mar 29 15:32:17 2004  Ben Pfaff  <blp@gnu.org>
+
+       Add support for multipass procedures.  Rewrite DESCRIPTIVES to
+       test multipass support, take advantage of new moments
+       calculation, and to not be such crappy code.  Get rid of q2c
+       processing for DESCRIPTIVES.
+
+       * vfm.c: (struct multipass_split_aux_data) New structure.
+       (multipass_procedure_with_splits) New function.
+       (multipass_split_callback) New function.
+       (multipass_split_output) New function.
+       * descript.q: Removed.
+
+       * descript.c: New file.
+
+       * var.h: Removed descriptives enums.
+       (struct descriptives_proc) Removed.
+       (struct variable) Removed p.dsc.
+
+       * Makefile.am: (q_sources_c) Remove descript.c.
+       (q_sources_q) Removed descript.q.
+       
+Mon Mar 29 15:31:55 2004  Ben Pfaff  <blp@gnu.org>
+
+       New manager for keeping track of used workspace.
+       
+       * workspace.c: New file.
+
+       * workspace.h: New file.
+
+       * Makefile.am: (pspp_SOURCES) Add workspace.c, workspace.h.
+
+       * sort.c: (do_internal_sort) Use workspace_malloc().
+       (destroy_internal_sort) Use workspace_free().
+
+Mon Mar 29 15:31:08 2004  Ben Pfaff  <blp@gnu.org>
+
+       New `struct casefile' for managing sets of cases.
+
+       * casefile.c: New file.
+
+       * casefile.h: New file.
+
+       * command.def: Add DEBUG CASEFILE command.
+
+       * Makefile.am: (pspp_SOURCES) Add casefile.c, casefile.h.
+
+       * sort.c: (sort_cases) Move logic for sending storage file to disk
+       into do_external_sort().
+       (struct internal_sort) Use an array of ccase pointers instead of a
+       case_list.
+       (do_internal_sort) Rewrite to handle casefiles.
+       (compare_case_list) Removed.
+       (compare_cases) New function.
+       (compare_case_dblptrs) New function.
+       (read_internal_sort_output) Deal with new struct internal_sort.
+
+       * vfm.c: (static var workspace_overflow) Removed.
+       (struct storage_stream_info) Removed all the members.  Added
+       struct casefile * member.
+       (storage_sink_open) Use casefile.
+       (open_storage_file) Removed.
+       (write_storage_file) Removed.
+       (storage_to_disk) Removed.
+       (destroy_storage_stream_info) Use casefile.
+       (storage_sink_write) Use casefile.
+       (storage_sink_make_source) Use casefile.
+       (storage_source_count) Use casefile.
+       (storage_source_read) Use casefile.
+       (storage_source_on_disk) Removed.
+       (storage_source_get_cases) Removed.
+       (storage_source_set_cases) Removed.
+       (storage_source_get_casefile) New function.
+       
+Mon Mar 29 15:30:09 2004  Ben Pfaff  <blp@gnu.org>
+
+       New `struct moments' for calculating moments.
+
+       * stats.c: Removed.
+
+       * stats.h: Removed.
+
+       * moments.c: New file.
+
+       * moments.h: New file.
+
+       * command.def: Add DEBUG MOMENTS command.
+
+       * Makefile.am: (pspp_SOURCES) Add moments.c, moments.h.  Remove
+       stats.c, stats.h.
+
+       * aggregate.c: Modify AGGREGATE to use the new moments
+       calculation, even if not in such a great way.
+       (struct agr_var) Add `moments' member.
+       (parse_aggregate_functions) Set `moments' member to null.
+       (agr_destroy) Destroy `moments' member.
+       (accumulate_aggregate_info) Use `moments' for standard deviation.
+       (dump_aggregate_info) Ditto.
+       (initialize_aggregate_info) Create or clear `moments'.
+
+       * misc.h: Add pow2(), pow3(), pow4() functions in place of sqr(),
+       cube(), pow4() that were in stats.h.  All references updated.
+
+       * crosstabs.q: stats.h had chi-square significance functions.  Use
+       GSL instead.
+       (display_chisq) Use gsl_cdf_chisq_Q() instead of chisq_sig().
+
+       * expr-evl.c: (expr_evaluate) Use moments_of_values() for
+       OP_CFVAR, OP_MEAN, OP_SD, OP_VARIANCE.
+               
+Fri Mar 26 14:21:23 2004  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c: (dict_compact_values) Compacted values need to
+       start off from 0.
+
+Fri Mar 26 00:54:57 2004  Ben Pfaff  <blp@gnu.org>
+
+       * var-labs.c: (cmd_variable_labels) For compatibility, don't allow
+       `/' at start.  Check return value of parse_variables() for error
+       return.
+
+Fri Mar 26 00:19:27 2004  Ben Pfaff  <blp@gnu.org>
+
+       Revamp expressions: make the code a little nicer, and fix bugs
+       found in testing.
+       
+       * expr-evl.c: (expr_evaluate) Make expression argument const.
+       Support OP_ADD, OP_SUB, OP_MUL, OP_DIV instead of OP_PLUS, OP_MUL.
+       OP_POW is missing for arg 2 <= 0.  OP_LOG is natural log, not
+       base-10 log.  Fix OP_ANY, OP_ANY_STRING, OP_RANGE, OP_RANGE_STRING
+       off-by-ones.  Add OP_MAX_STRING, OP_MIN_STRING.  Fix OP_TIME_HMS,
+       OP_DATE_WKYR boundary conditions.  Add OP_CTIME_DAYS,
+       OP_CTIME_HOURS, OP_CTIME_MINUTES, OP_CTIME_DAYS, OP_CTIME_SECONDS.
+       Support OP_INDEX_2, OP_INDEX_3, OP_RINDEX_2, OP_RINDEX_3 instead
+       of OP_INDEX, OP_INDEX_OPT, OP_RINDEX, OP_RINDEX_OPT.  Merge
+       OP_LPAD_OPT into OP_LPAD, OP_RPAD_OPT into OP_RPAD, OP_LTRIM_OPT
+       into OP_LTRIM, OP_RTRIM_OPT into OP_RTRIM, OP_NUMBER_OPT into
+       OP_NUMBER.  Fix OP_RTRIM fragility.  Support OP_SUBSTR_2,
+       OP_SUBSTR_3 instead of OP_SUBSTR, OP_SUBSTR_OPT.  Remove OP_INV.
+       Simplify OP_SYSMIS.  Remove OP_STR_MIS.
+
+       * expr-opt.c: (optimize_expression) Rewrite.
+       (macro n0) Removed.
+       (macro n1) Removed.
+       (macro n2) Removed.
+       (macro s0) Removed.
+       (macro s0l) Removed.
+       (macro s1) Removed.
+       (macro s1l) Removed.
+       (macro s2) Removed.
+       (macro s2l) Removed.
+       (macro s) Removed.
+       (macro sl) Removed.
+       (eq_num_con) New function.
+       (optimize_tree) New function.
+       (macro rnc) Removed.
+       (macro frnc) Removed.
+       (str_search) Add const to string params.
+       (str_rsearch) Ditto.
+       (evaluate_tree_no_missing) Renamed from evaluate_tree.  Add num[],
+       str[], str_len[] locals to substitute for most of removed macros.
+       Support OP_ADD, OP_SUB, OP_MUL, OP_DIV instead of OP_PLUS, OP_MUL.
+       Removed support for missing values because we're never called with
+       missing values.  Use set_number() or set_number_errno() instead of
+       rnc or frnc.  Removed any stuff that caused trouble in testing.
+       We can re-add it later if it really slows anything.  Fix some
+       random problems.
+       (evaluate_tree_with_missing) Not yet supported.  To be added later
+       if it's important.
+       (repl_num_con) Removed.
+       (collapse_node) New function.
+       (force_repl_num_con) Removed.
+       (set_number) New function.
+       (set_number_errno) New function.
+       (repl_str_con) Removed.
+       (set_string) New function.
+       (yrmoda) Tighten boundary conditions.  Adopt 2030 cut-off for
+       2-digit years.
+       (dump_node) No special case for OP_AND, OP_OR.
+
+       * expr-prs.c: (expr_prs) Honor EXPR_NO_OPTIMIZE bit.  Rewrite.
+       (expr_get_type) New function.
+       (type_check) Rewrite.
+       (type_coercion) New function.
+       (struct operator) New structure.
+       (match_operator New function.
+       (parse_binary_operators) New function.
+       (parse_inverting_unary_operator) New function.
+       (parse_or) Rewritten.
+       (parse_and) Rewritten.
+       (parse_not) Rewritten.
+       (parse_rel) Rewritten.
+       (parse_add) Rewritten.
+       (parse_mul) Rewritten.
+       (parse_neg) Rewritten.
+       (parse_exp) Rewritten.
+       (parse_sysvar) Add $TRUE, $FALSE system variables.
+       Get $LENGTH, $WIDTH from get_viewlength(), get_viewwidth().
+       (parse_primary) Use allocate_var_node(), allocate_num_con(),
+       allocate_str_con().
+       (struct function) Remove desc, change `func' prototype.
+       (unary_func) Remove special cases.
+       (MISSING_func) Reduce to unary_func() that just returns a boolean.
+       (SYSMIS_func) Handle SYSMIS((x)) like SYSMIS(x).
+       (VALUE_func) Use allocate_var_node().
+       (nary_num_func) Allow MIN and MAX for strings.
+       Use allocate_var_node().  Properly clean up.
+       Fix return type.
+       (generic_str_func) Use local table instead of removed `desc'
+       member.  Mostly rewrite.
+       (get_num_args) Revise error message.
+       (parse_function) Return EXPR_ERROR, not 0 on error.
+       (macro op) Removed.
+       (macro varies) Removed.
+       (ops[]) Use expr.def.
+       (free_node) Do nothing if node is null.
+       (allocate_num_con) New function.
+       (allocate_str_con) New function.
+       (allocate_var_node) New function.
+       (allocate_binary_nonterminal) New function.
+       (append_nonterminal_arg) Removed.
+       (static var func_tab[]) Revised.
+       (expr_debug_print_postfix) Make parameter const.
+       Use printf() instead of debug_printf().
+
+       * expr.def: New file.
+       
+       * expr.h: Change PXP_* to EXPR_*, all references updated.  Also
+       use named enum instead of unnamed, all references updated.  Add
+       EXPR_ANY, EXPR_NO_OPTIMIZE.
+
+       * exprP.h: Remove EX_*.  Add DEFINE_OPERATOR.  Use expr.def
+       instead of defining OP_* directly.
+       (macro IS_TERMINAL) New macro.
+       (macro IS_NONTERMINAL) New macro.
+       (enum OP_NO_FLAGS) New.
+       
+Fri Mar 26 00:18:01 2004  Ben Pfaff  <blp@gnu.org>
+
+       * error.c: (err_assert_fail) msg variable needs to be non-const.
+
+Fri Mar 26 00:17:24 2004  Ben Pfaff  <blp@gnu.org>
+
+       * debug.c: (cmd_debug_evaluate) Rewrite.
+
+Fri Mar 26 00:15:13 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fix some CROSSTABS bit rot stupidity.
+
+       * crosstabs.q: Reorder the CELLS subcommands for compatibility.
+       (internal_cmd_crosstabs) Initializes cells[] correctly.
+       (float_M_suffix) Rename format_cell_entry(), change prototype,
+       rewrite.
+       (display_crosstabulation) Fix cell formatting.
+
+Fri Mar 26 00:14:09 2004  Ben Pfaff  <blp@gnu.org>
+
+       Make lex_rest_of_line(), lex_entire_end() not discard lines.  Have
+       to call lex_discard_line() to do that.
+
+       * command.c: (run_command) Call lex_discard_line() after
+       lex_rest_of_line().
+
+       * lexer.c: (lex_entire_end) Change behavior.
+       (lex_rest_of_line) Change behavior.  Return const char *.
+       (lex_discard_line) Don't clear getl_buf, don't emit message.
+
+       * main.c: (handle_error) Emit message here.
+
+       * repeat.c: (internal_cmd_do_repeat) Use lex_discard_line()
+       instead of lex_entire_line().
+
+       * str.c: (mm_find_reverse) Make length params size_t.  Rewrite.
+
+       * title.c: (get_title) Call lex_discard_line() after
+       lex_rest_of_line().
+       (cmd_file_label) Ditto.
+       (cmd_document) Deal with const char * return value.
+
+Fri Mar 26 00:10:16 2004  Ben Pfaff  <blp@gnu.org>
+
+       Removed REMARK command.
+
+       * command.c: (extract_prefix) Removed.
+       (output_line) Removed.
+       (cmd_remark) Removed.
+
+       * command.def: Remove REMARK.
+
+Fri Mar 26 00:08:38 2004  Ben Pfaff  <blp@gnu.org>
+
+       Added abort() after lots of assert(0) invocations to avoid some
+       compiler warnings.  We really need a NOT_REACHED macro.
+
+Tue Mar 23 08:00:42 WAST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * sort.c: Added missing call to temp_file_close.  Changed error 
+       messages to warnings.
+
+       * set.q: Improved setting of set_view{length,width} to be more tolerant
+       of buggy OSes.
+
+Sun Mar 21 10:11:14 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+        * val-labs.c: Fixed a bug where PSPP would crash, if VALUE LABELS was
+       used with incorrect syntax.
+
+       * error.c, error.h et al:  Overridden definition of assert for a
+       custom one.
+
+       * test-q.c: Fixed a buglet where it would crash if no /VARIABLES
+       subcommand was given when it ought to have been.
+
+Sat Mar 20 22:19:08 2004  Ben Pfaff  <blp@gnu.org>
+
+       * tab.c: (tab_vline) Fix assertions to respect row_ofs and
+       col_ofs.
+       (tab_hline) Ditto.
+       (tab_box) Ditto.
+       (tab_joint_text) Ditto.
+
+Sat Mar 20 17:57:23 2004  Ben Pfaff  <blp@gnu.org>
+
+       * levene.c: Add #include.
+
+       * set.q: (set_viewport) Add `int' argument to make its prototype
+       correct for signal().
+
+Sat Mar 20 15:35:17 2004  Ben Pfaff  <blp@gnu.org>
+
+       * expr-evl.c: (expr_evaluate) Assert that `c' is nonzero before
+       using it.
+
+Sat Mar 20 15:18:16 2004  Ben Pfaff  <blp@gnu.org>
+
+       Changed DFM from open-at-first-access to explicit-open.  Before,
+       calling dfm_get_record() or dfm_put_record() would automatically
+       open the file.  Now, you have to call dfm_open_for_reading() or
+       dfm_open_for_writing() explicitly.  This makes it possible to
+       check permissions, file existence, etc. earlier.
+
+       Also made struct file_handle more opaque, and clean up in general.
+
+       * data-list.c: (cmd_data_list) Open handle for reading.
+
+       * dfm.c: (struct dfm_fhuser_ext) Add `where', `saw_begin_data'
+       members.
+       (open_file_r) Renamed dfm_open_for_reading(), rewrote.
+       (open_file_w) Renamed dfm_open_for_writing(), rewrote.
+       (open_inline_file) Removed.
+       (read_record) For inline_file, if we haven't seen BEGIN DATA, read
+       it.  Deal with line_number in extension record instead of file
+       handle.
+       (dfm_get_record) Rewrote.
+       (dfm_put_record) Rewrote.
+       (dfm_push) Assert file is open and one of ours.  Deal with
+       line_number in extension record instead of file handle.
+       (dfm_pop) Assert file is open and one of ours.  Deal with
+       line_number in extension record instead of file handle.
+       (cmd_begin_data) Use dfm_open_for_reading().  Mark that we saw
+       BEGIN DATA.     
+
+       * file-handle.h: (enum constants RH_RF_*) Removed.
+       (enum constants FH_MD_*) Removed.
+       (struct file_handle) Removed `name', `norm_fn', `fn', `where',
+       `recform', `lrecl', `mode' members.  Public references to
+       `recform' changed to use handle_get_mode(), references to `lrecl'
+       changed to use handle_get_record_width().  Added `private' member.
+       (enum file_handle_mode) New.
+
+       * file-handle.q: (struct private_file_handle) New structure.
+       (struct file_handle_list) New structure.
+       (static var files) New.
+       (static var file_handles) Removed.
+       (init_file_handle) Removed.
+       (create_file_handle) Removed.
+       (get_handle_with_name) New function.
+       (get_handle_for_filename) New function.
+       (cmd_file_handle) Rewritten.
+       (hash_file_handle) Removed.
+       (cmp_file_handle) Removed.
+       (fh_init_files) Rewritten.
+       (fh_parse_file_handle) Rewritten.  Allows identifiers as
+       filenames.
+       (fh_get_handle_by_name) Renamed handle_get_name(), all references
+       updated.  Rewritten.
+       (fh_get_handle_by_filename) Renamed handle_get_filename(), all
+       references updated.  Rewritten.
+       (fh_record_width) Renamed handle_get_record_width(), all
+       references updated.  Rewritten.
+       (handle_get_mode) New function.
+
+       * file-type.c: (cmd_file_type) Open handle for reading.
+
+       * filename.c: [unix] (struct file_identity) New structure.
+       [unix] (fn_get_identity) New function.
+       [unix] (fn_free_identity) New function.
+       [unix] (fn_compare_file_identities) New function.
+       [!unix] (struct file_identity) New structure.
+       [!unix] (fn_get_identity) New function.
+       [!unix] (fn_free_identity) New function.
+       [!unix] (fn_compare_file_identities) New function.
+
+       * lexer.c: (static var put) Renamed put_token, all references
+       updated.
+       (static var put_tokstr) New.
+       (static var put_tokval) New.
+       (lex_init) Initialize put_tokstr().
+       (restore_token) New function.
+       (save_token) New function.
+       (lex_get) Use restore_token().
+       (lex_put_back) Use save_token().
+       (lex_put_back_id) New function.
+       (lex_put_forward) Removed.
+       (lex_preprocess_line) Set put_token instead of using
+       lex_put_forward().
+       (lex_negative_to_dash) Use save_token(), set put_token directly.
+       (dump_token) Use stderr instead of stdout.
+
+       * main.c: (main) Remove call to cmd_init().
+       
+       * matrix-data.c: (cmd_matrix_data) Open file for reading.
+
+       * pfm-read.c: Use handle_get_filename() instead of trying to use
+       h->fn directly, all over.
+
+       * pfm-write.c: Ditto.
+
+       * print.c: (internal_cmd_print) Open handle for writing.
+       (dump_table) Use handle_get_filename().
+       (print_trns_proc) Use handle_get_mode().
+       (cmd_print_space) Use fh_parse_file_handle().
+       Open handle for writing.
+       [0] (debug_print) Removed.
+
+       * sfm-read.c: Use handle_get_filename() instead of trying to use
+       h->fn directly, all over.
+
+       * sfm-write.c: Ditto.
+
+Sat Mar 20 14:35:48 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fix memory leaks.
+       
+       * autorecode.c: (arc_free) Free arc->src_values.
+
+       * error.c: (msg) Free buf.
+
+       * val-labs.c: (do_value_labels) Always free vars.
+
+       * vfm.c: (close_active_file) If sink has no make_source then call
+       its destroy function.
+
+Sat Mar 20 14:00:24 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fixed cmd_parse() so that it always skips past a full command
+       name.  A few special commands for which this would be bad get
+       special treatment.  This lets us drop code for skipping past the
+       end of a command name in most cmd_*() functions.  It's not worth
+       listing all the commands affected.
+
+       * command.c: (struct command) Remove `cmd' member, replace by
+       `name' member, all references updated.  Remove `word', `next',
+       `skip_entire_name' members.
+       (macro DEFCMD) Deal with revised `struct command'.
+       (macro UNIMPL) Ditto.
+       (macro SPCCMD) New macro for commands whose last word shouldn't be
+       skipped.
+       (static array cmd_table[]) Make const, rename `commands', remove
+       sentinel element.
+       (macro COMMAND_CNT) New macro.
+       (split_words) Removed.
+       (cmd_init) Removed.
+       (FILE_TYPE_okay) Make parameter const.
+       (cmd_parse) Improve error messages.
+       (match_strings) New function.
+       (next_word) New function.
+       (enum command_match) New enum.
+       (conflicting_3char_prefixes) New function.
+       (conflicting_3char_prefix_command) New function.
+       (cmd_match_words) New function.
+       (count_matching_commands) New function.
+       (get_command_name) New function.
+       (free_words) New function.
+       (unknown_command_error) New function.
+       (figure_out_command) Renamed parse_command_name(), rewritten.
+
+       * command.def: Removed @ command.  Marked BEGIN DATA, DOCUMENT,
+       FILE LABEL, REMARK, SUBTITLE, TITLE as special.  Renamed EVALUATE
+       to DEBUG EVALUATE.  Added N alias for N OF CASES, SORT alias for
+       SORT CASES.
+
+       * command.h: (macro SPCCMD) New.
+
+       * include.c: (cmd_include_at) Removed.
+       (cmd_include) Allow identifier to be used as filename.
+
+       * inpt-pgm.c: (cmd_reread) Use fh_parse_file_handle().
+
+       * t-test.q: (cmd_t_test) Command name is now parsed for us.
+       
+
+Sat Mar 20 13:56:00 2004  Ben Pfaff  <blp@gnu.org>
+
+       Start work on better test framework.
+       
+       * Makefile.am: (pspp_sources) Add debug.c.
+       
+       * debug.c: New file.
+
+       * compute.c: (cmd_evaluate) Moved to debug.c, renamed
+       cmd_debug_evaluate().
+
+       * expr-prs.c: (expr_parse) Remove PXP_DUMP support.
+
+       * expr.h: (enum constant PXP_DUMP) Removed.
+
+Sat Mar 20 00:05:42 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * set.q:  Implemented the SHOW command, and synced it to the existing 
+       SET cmd.
+
+       Added a handler for SIGWINCH so that viewlength and viewwidth follow
+       changes as the window size is changed.
+
+       Added fallback to set viewlength and viewwidth from LINES and COLUMS
+       environment variables if other methods are not available.
+
+       glob.c: Removed a lot of global variables from glob.c and encapsulated 
+       them in set.q
+
+       random.c: Tidied up the way the random seed is set.
+
+       str.c: Added a ds_vprintf function.
+
+       error.c: Extended dump_message so that messages are always broken at
+       '\n' characters.
+       
+Thu Mar 18 11:07:14 2004  Ben Pfaff  <blp@gnu.org>
+
+       * pfm-write.c: (bufwrite) Write out the correct element for string
+       variables.  From Andreas Streichardt <streichardt@globalpark.de>.
+
+Mon Mar 15 20:48:03 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static and global (!) vars in matrix-data.c.
+
+       * matrix-data.c: (static var nr_data) Removed.
+       (static var nr_factor_values) Removed.
+       (static var max_cell_index) Removed.
+       (static var split_values) Removed.
+       (struct nr_aux_data) New structure.
+       (read_matrices_without_rowtype) Use a local struct nr_aux_data in
+       place of static vars, pass to create_case_source() and procedure()
+       as aux data.
+       (nr_read_data_lines) Use struct nr_aux_data * parameter instead of
+       struct matrix_data_pgm *.
+       (nr_read_splits) Ditto.
+       (nr_read_factors) Ditto.
+       (nr_output_data) Ditto.
+       (static var wr_content) Removed.
+       (global var wr_data) Removed.
+       (global var wr_current) Removed.
+       (struct wr_aux_data) New structure.
+       (read_matrices_with_rowtype) Use a local struct wr_aux_data in
+       place of static vars, pass to create_case_source() and procedure()
+       as aux data.
+       (matrix_data_read_with_rowtype) Use struct wr_aux_data * parameter
+       instead of matrix_data_pgm *.
+       (wr_read_splits) Ditto.
+       (wr_output_data) Ditto.
+       (wr_read_rowtype) Ditto.
+       (wr_read_factors) Ditto.
+       (wr_read_indeps) Ditto.
+       
+Mon Mar 15 20:07:29 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static vars in autorecode.c.
+
+       * autorecode.c: (struct autorecode_trns) Rename `arc' to `specs',
+       `n_arc' to `spec_cnt'.  All references updated.
+       (static var v_src) Removed.
+       (static var v_dest) Removed.
+       (static var h_trns) Removed.
+       (static var nv_src) Removed.
+       (static var descend) Removed.
+       (static var print) Removed.
+       (enum direction) New enum.
+       (struct autorecode_pgm) New structure.
+       (cmd_autorecode) Use struct autorecode_pgm instead of static vars.
+       Move n_dest local var into struct autorecode_pgm for ease of
+       clean-up.  Use arc_free().
+       (arc_free) New function.
+       (recode) Modify to take struct autorecode_pgm * parameter instead
+       of using statics.  Let the caller clean up.
+       (autorecode_proc_func) Use struct autorecode_pgm * auxiliary data
+       instead of statics.  Rearrange code a little.
+
+Mon Mar 15 00:25:02 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static, global vars in recode.c.  Remove debug code.
+
+       * recode.c: (static var head) Removed.
+       (global var v) Removed.
+       (global var nv) Removed.
+       (cmd_recode) New local variables head, v, nv.  Initialize and free
+       v.  Don't call debug_print().
+       [DEBUGGING] (dump_dest) Removed.
+       [DEBUGGING] (debug_print) Removed.
+
+Mon Mar 15 00:14:49 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static vars in expr-opt.c.
+
+       * expr-opt.c: (static var e) Removed.
+       (static var nop) Removed.
+       (static var mop) Removed.
+       (static var ndbl) Removed.
+       (static var mdbl) Removed.
+       (static var nstr) Removed.
+       (static var mstr) Removed.
+       (static var nvars) Removed.
+       (static var mvars) Removed.
+       (struct expr_dump_state) New structure.
+       (dump_expression) Use new struct expr_dump_state instead of static
+       vars and pass to functions we call.
+       (dump_node) Use struct expr_dump_state * parameter.
+       (emit) Ditto.
+       (emit_num_con) Ditto.
+       (emit_str_con) Ditto.
+       (emit_var) Ditto.
+       
+Mon Mar 15 00:03:51 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static var in COUNT.
+
+       * count.c: (static var head) Move into cmd_count().
+       (cmd_count) [DEBUGGING] Don't call debug_print.
+       [DEBUGGING] (debug_print) Removed.
+
+Sun Mar 14 23:56:09 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static vars in VALUE LABELS, ADD VALUE LABELS.
+
+       * val-labs.c: (static var v) Removed.
+       (static var nv) Removed.
+       [DEBUGGING] (debug_print) Removed.
+       (verify_val_labs) Add struct variable **, int parameters.
+       (get_label) Ditto.  Improve error messages, streamline.
+       (erase_labels) New function for erasing value labels, taking over
+       part of verify_val_labs()'s function.
+       (init) Removed.
+       (done) Removed.
+       (cmd_value_labels) No need to call init() or done() anymore.
+       (cmd_add_value_labels) Ditto.
+       (do_value_labels) Add vars, var_cnt local variables.  Clean up
+       after them internally.  Call erase_labels() if we should.  Don't
+       call debug_print().
+
+Sun Mar 14 23:33:53 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of static vars in MATCH FILES.
+       
+       * get.c: (static var mtf_head) Removed.
+       (static var mtf_tail) Removed.
+       (static var mtf_by) Removed.
+       (static var mtf_n_by) Removed.
+       (static var mtf_master) Removed.
+       (static var mtf_seq_num) Removed.
+       (static var mtf_seq_nums) Removed.
+       (static var mtf_sink) Removed.
+       (static var mtf_case) Removed.
+       (struct mtf_proc) New structure.
+       (cmd_match_files) Use struct mtf_proc instead of static vars.
+       (mtf_processing_finish) Ditto.
+       (mtf_free) Ditto.
+       (mtf_delete_file_in_place) Ditto.
+       (mtf_read_nonactive_records) Ditto.
+       (mtf_compare_BY_values) Ditto.
+       (mtf_processing) Ditto.
+       (mtf_merge_dictionary) Ditto.
+
+Sun Mar 14 22:48:12 2004  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add CASESTOVARS, VARSTOCASES unimplemented commands.
+
+       * dictionary.c: (dict_rename_var) Add assertion.
+       (dict_contains_var) Check by index instead of name.
+
+Sun Mar 14 22:01:02 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of compaction_necessary, compaction_nval, compaction_case.
+       Redo VFM interface.  Replace disk_sink and memory_sink by
+       storage_sink, disk_source and memory_source by storage_source.
+
+       * vfm.h: (struct case_sink) Add `dict', `idx_to_fv', `value_cnt'
+       members.
+
+       * vfm.c: 
+       (struct write_case_data) Remove `begin_func', `end_func',
+       `func_aux' members.  Add `aux', `trns_case', `sink_case',
+       `cases_written', `cases_analyzed' members.
+       (global var compaction_necessary) Make static.
+       (global var compaction_nval) Removed.
+       (global var compaction_case) Removed.
+       (static var case_count) Removed.
+       (struct procedure_aux_data) Removed.
+       (struct split_aux_data) Removed.
+       (procedure) Remove begin_func, end_func parameters.  Rewrite.
+       (static var not_canceled) Removed.
+       (process_active_file) Removed.
+       (process_active_file_write_case) Removed.
+       (process_active_file_output_case) Removed.
+       (prepare_for_writing) Moved into open_active_file().
+       (arrange_compaction) Ditto.
+       (setup_lag) Ditto.
+       (open_active_file) Rewrote.
+       (write_case) New function.
+       [DEBUGGING] (index_to_varname) Removed.
+       (execute_transformations) New function.
+       (exclude_this_case) Renamed filter_case(), changed interface.
+       (clear_case) Added struct ccase * parameter to interface.
+       (close_active_file) Added struct write_case_data * parameter,
+       rewrote.
+       (disk_sink_create) Removed.
+       (disk_sink_destroy) Removed.
+       (disk_sink_make_source) Removed.
+       (disk_sink_write) Removed.
+       (disk_source_count) Removed.
+       (disk_source_destroy) Removed.
+       (disk_source_read) Removed.
+       (global var disk_sink_class) Removed.
+       (global var disk_source_class) Removed.
+       (global var memory_sink_class) Removed.
+       (global var memory_source_class) Removed.
+       (memory_sink_create) Removed.
+       (memory_sink_destroy) Removed.
+       (memory_sink_make_source) Removed.
+       (memory_sink_write) Removed.
+       (memory_source_count) Removed.
+       (memory_source_destroy) Removed.
+       (memory_source_get_cases) Removed.
+       (memory_source_read) Removed.
+       (memory_source_set_cases) Removed.
+       (struct disk_stream_info) Removed.
+       (struct memory_sink_info) Removed.
+       (struct memory_source_info) Removed.
+       (write_active_file_to_disk) Removed.
+       (destroy_storage_stream_info) New function.
+       (global var null_sink_class) New var.
+       (global var storage_sink_class) New var.
+       (global var storage_source_class) New var.
+       (open_storage_file) New function.
+       (storage_sink_destroy) New function.
+       (storage_sink_make_source) New function.
+       (storage_sink_open) New function.
+       (storage_sink_write) New function.
+       (storage_source_count) New function.
+       (storage_source_destroy) New function.
+       (storage_source_get_cases) New function.
+       (storage_source_on_disk) New function.
+       (storage_source_read) New function.
+       (storage_source_set_cases) New function.
+       (storage_source_to_disk) New function.
+       (storage_to_disk) New function.
+       (struct storage_stream_info) New structure.
+       (write_storage_file) New function.
+       (procedure_write_case) Removed.
+       (create_case_source) Add `struct dictionary *' parameter, all
+       references updated.
+       (create_case_sink) Ditto.
+       (free_case_sink) New function.
+       (struct split_aux_data) New structure.
+       (procedure_with_splits) New function implementing what procedure()
+       used to.
+       (SPLIT_FILE_proc_func) Removed.
+       (procedure_with_splits_callback) New function.
+       (equal_splits) New function.
+       
+       * aggregate.c: Pass around a struct instead of using statics.
+       (static var outfile) Remove.
+       (enum type) Give it tag `missing_treatment'.
+       (static var missing) Remove.
+       (static var sort) Remove.
+       (static var agr_first) Remove.
+       (static var agr_next) Remove.
+       (static var case_count) Remove.
+       (static var prev_case) Remove.
+       (static var buf64_1xx) Remove.
+       (static var buf_1xx) Remove.
+       (struct agr_proc) New structure incorporating the above.
+       (cmd_aggregate) Use new struct.  Clean up error handling using
+       agr_destroy().  Completely rewrite actual implementation of
+       aggregation.
+       (create_sysfile) Add struct agr_proc * parameter, modify
+       accordingly.
+       (parse_aggregate_functions) Ditto.
+       (free_aggregate_functions) Ditto.  Rename agr_destroy().
+       (aggregate_single_case) Add struct agr_proc * parameter, modify
+       accordingly.
+       (accumulate_aggregate_info) Ditto.
+       (dump_aggregate_info) Ditto.
+       (initialize_aggregate_info) Ditto.
+       (agr_00x_trns_proc) Removed.
+       (agr_00x_end_func) Removed.
+       (agr_10x_trns_proc) Removed.
+       (agr_10x_trns_free) Removed.
+       (agr_10x_end_func) Removed.
+       (agr_11x_read) Removed.
+       (agr_11x_finish) Removed.
+       [DEBUGGING] (debug_print) Removed.
+       (write_case_to_sfm) Add struct agr_proc * parameter, modify
+       accordingly.
+       (agr_to_active_file) New function.
+       (presorted_agr_to_sysfile) New function.
+       (sort_agr_to_sysfile) New function.
+
+       * autorecode.c: (cmd_autorecode) Use procedure_with_splits().
+
+       * crosstabs.q: (internal_cmd_crosstabs) Ditto.
+
+       * descript.q: (cmd_descriptives) Ditto.
+
+       * dfm.c: (cmd_begin_data) Check for storage_source_class.  Adapt
+       to new procedure() interface.
+
+       * command.c: (cmd_execute) Adapt to new procedure() interface.
+
+       * dictionary.c: (dict_compact_values) Also delete scratch
+       variables.
+       (dict_get_compacted_value_cnt) New function.
+       (dict_get_compacted_idx_to_fv) New function.
+
+       * flip.c: (cmd_flip) Warn about and cancel TEMPORARY.
+       (cmd_flip) Adapt to new procedure() interface.
+       (flip_sink_write) Use sink->idx_to_fv.
+
+       * frequencies.q: (internal_cmd_frequencies) Use
+       procedure_with_splits().
+
+       * get.c: (cmd_save_internal) Adapt to new procedure() interface.
+       (static var mtf_sink) New static var.
+       (static var mtf_case) New static var.
+       (cmd_match_files) Warn about and cancel TEMPORARY.  Redo the way
+       we actually implement the matching.
+       (mtf_delete_file_in_place) Use mtf_case.
+       (mtf_processing) Use mtf_case and mtf_sink.
+       (cmd_export) Adapt to new procedure() interface.
+
+       * levene.c: (levene) Use procedure_with_splits().
+
+       * list.q: (cmd_list) Use procedure_with_splits().
+
+       * matrix-data.c: (read_matrices_without_rowtype) Adapt to new
+       procedure() interface.
+       (read_matrices_with_rowtype) Ditto.
+
+       * modify-vars.c; (cmd_modify_vars) Warn about and cancel
+       TEMPORARY.  Adapt to new procedure() interface.
+
+       * rename-vars.c: Warn about and cancel TEMPORARY.
+
+       * sort.c: (cmd_sort_cases) Warn about TEMPORARY.
+       (sort_cases) Use dict_get_compacted_value_cnt() instead of
+       compaction_nval.  Adapt to new procedure() interface.  Use
+       storage_source_to_disk().
+       (do_internal_sort) Don't try to dump the cases to memory.
+       (compare_case_lists) Pass null idx_to_fv.
+       (struct initial_run_state) Add `idx_to_fv' member.  Remove
+       `case_size' member.
+       (write_initial_runs) Don't initialize irs->case_size.  Adapt to
+       new procedure() interface.  Reset irs->idx_to_fv after calling
+       procedure().
+       (sort_sink_write) Set irs->idx_to_fv.  Use case_size from struct
+       sort_cases_pgm.  Pass irs, not struct sort_cases_pgm to
+       push_heap().
+       (destroy_initial_run_state) Don't dereference irs after freeing
+       it.
+       (allocate_cases) Don't calculate case_size locally.
+       (compare_record) Add idx_to_fv parameter.
+       (compare_record_run) Change parameter from struct sort_cases_pgm *
+       to struct initial_run_state *.  Pass irs->idx_to_fv to
+       compare_record().
+       (compare_record_run) Third parameter now a struct
+       initial_run_state *.
+       (output_record) No need for out_case anymore.  Pass irs, not
+       struct sort_cases_pgm to pop_heap().  Use case_size from struct
+       sort_cases_pgm.
+       (merge) Use case_size from struct sort_cases_pgm.
+       (merge_once) Use case_size from struct sort_cases_pgm.
+       Pass null pointer to compare_record() as idx_to_fv.
+       (global var sort_sink_class) Make static.
+
+       * t-test.q: (cmd_t_test) Use procedure_with_splits().
+
+       * temporary.c: Remove debugging crap.
+
+Sat Mar 13 14:19:52 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q, levene.c: Fixed up the handling of MISSING values
+       int the T-TEST
+
+Fri Mar 12 16:23:35 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q, levene.c: Added support for T-TEST /GROUP where only 
+       one value is given.
+
+Wed Mar 10 23:25:13 2004  Ben Pfaff  <blp@gnu.org>
+
+       Change explicit variable name checks into use of
+       dict_class_from_id().
+
+       * dictionary.c: (dict_create_var)  Change explicit variable name
+       check into use of dict_class_from_id().
+
+       * get.c: (trim_dictionary) Ditto.
+
+       * sel-if.c: (cmd_filter) Ditto.
+
+       * sysfile-info.c: (cmd_display) Ditto.
+
+       * vars-prs.c: (parse_DATA_LIST_vars) Ditto.
+
+       * vfm.c: (arrange_compaction) Ditto.
+
+       * weight.c: (cmd_weight) Ditto.
+
+Wed Mar 10 21:16:34 2004  Ben Pfaff  <blp@gnu.org>
+
+       * temporary.c: (cmd_temporary) When TEMPORARY was the first
+       transformation following the input program, if any, for some
+       reason we special-cased f_trns.  That's just wrong.  It should
+       always be set to n_trns.
+
+Tue Mar  9 23:44:40 2004  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (parse_format_specifier_name) Fix brown-bag bug
+       introduced in last check-in.
+
+Tue Mar  9 23:10:41 2004  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (global array translate_fmt[]) Removed.
+       (translate_fmt) New function as replacement.
+       (parse_format_specifier_name) Rewrite.
+
+       * pfm-read.c: (convert_format) Use translate_fmt() instead of
+       translate_fmt[].
+
+       * sfm-read.c: (parse_format_spec) Ditto.
+
+       * postscript.c: (text) Fix handling of fonts with missing
+       ligatures.
+
+       * sort.c: (struct external_sort) Add temp_name member.
+       (destroy_external_sort) Free temp_dir, temp_name members.
+       (init_external_sort) Allocate temp_name.
+       (get_temp_file_name) Change prototype.
+       (open_temp_file) Deal with change to get_temp_file_name().
+       (close_temp_file) Ditto.
+       (remove_temp_file) Ditto.
+       (write_temp_file) Ditto.
+       (read_temp_file) Ditto.
+       (sort_sink_destroy) Removed.
+       (sort_sink_class) Change destroy member to null.
+
+Tue Mar  9 22:36:34 2004  Ben Pfaff  <blp@gnu.org>
+
+       Eliminate temp_case.
+
+       * aggregate.c: (cmd_aggregate) No need to save/restore temp_case
+       anymore.  Use agr_11x_finish().
+       (aggregate_single_case) Make first param const.
+       (accumulate_aggregate_info) Ditto.
+       (agr_00x_end_func) Use compaction_case, not temp_case.
+       (agr_11x_func) Break into agr_11x_read(), agr_11x_finish().
+
+       * data-list.c: (struct data_list_pgm) Add `case_size' member.
+       (cmd_data_list) Initialize case_size.
+       (read_from_data_list_fixed) Add struct ccase * param, use instead
+       of temp_case.
+       (read_from_data_list_free) Ditto.
+       (read_from_data_list_list) Ditto.
+       (read_one_case) Rename data_list_trns_proc(), all references
+       updated.  Add argument in calling above functions.  Use c
+       argument instead of temp_case.
+       (destroy_dls) Rename data_list_trns_free(), all references
+       updated.
+
+       * expr-evl.c: (expr_evaluate) Make second parameter const.
+
+       * file-type.c: (struct file_type_pgm) Add `case_size' member.
+       (cmd_end_file_type) Initialize `case_size'.
+       (file_type_source_read) Add struct ccase * parameter.  Use instead
+       of temp_case.
+
+       * flip.c: Rewritten.
+
+       * get.c: (struct get_pgm) New structure to keep track of
+       case_size.
+       (cmd_get) Initialize case_size.
+       (cmd_import) Ditto.
+       (get_source) Deal with struct get_pgm.
+       (get_source_read) Add struct ccase * parameter, use instead of
+       temp_case.
+       (import_source_read) Ditto.
+
+       * get.c: Use a null pointer instead of temp_case to represent the
+       "current case" in a struct mtf_file's input member.
+       (mtf_processing_finish) Pass null to mtf_processing(), not
+       temp_case.
+       (mtf_read_nonactive_records) Don't set iter->input to temp_case.
+       (mtf_compare_BY_values) Add extra arg, use instead of null input
+       members.
+       (mtf_processing) Use c parameter instead of temp_case.  Pass
+       compaction_case to process_active_file_output_case().
+       
+       * glob.c: (global variable temp_case) Removed.
+
+       * inpt-pgm.c: (struct input_program_pgm) Add `case_size' member.
+       (cmd_input_program) Initialize case_size.  Set
+       vfm_source->value_cnt.
+       (init_case) Add struct ccase * parameter, use instead of
+       temp_case.
+       (clear_case) Ditto.
+       (input_program_source_read) Ditto.
+
+       * matrix-data.c: (matrix_data_read_without_rowtype) Ditto.
+       (dump_cell_content) Ditto.
+       (nr_output_data) Ditto.
+       (read_matrices_without_rowtype) Ditto.
+       (matrix_data_read_with_rowtype) Ditto.
+       (wr_read_splits) Ditto.
+       (wr_output_data) Ditto.
+
+       * sort.h: (struct sort_cases_pgm) New member `case_size'.
+       
+       * sort.c: (sort_cases) Initialize scp->case_size.
+       (struct external_sort) Remove `case_size' member.
+       (write_initial_runs) Only call vfm_sink->class_destroy if
+       non-null.
+       (struct sort_source_aux) New structure.
+       (sort_source_read_helper) New function.
+       (sort_source_read) Use sort_source_read_helper().
+       (read_sort_output) Change interface to be more reasonable.
+       (read_internal_sort_output) Ditto.
+       (read_external_sort_output) Ditto.
+
+       * vars-prs.c: (dict_class_to_name) Pass return value through
+       gettext.
+
+       * vfm.c: (struct procedure_aux_data) Add `trns_case' member.
+       (procedure) Initialize trns_case.
+       (procedure) Pass trns_case to vfm_source->class->read().
+       Free trns_case.
+       (process_active_file) Start using struct procedure_aux_data.
+       (process_active_file_write_case) Pass trns_case to
+       transformations, lag_case(), clear_case().
+       (process_active_file_output_case) Add struct ccase * parameter.
+       (create_trns_case) New function.
+       (make_temp_case) Removed.
+       (vector_initialization) Removed.
+       (close_active_file) Only call make_source if non-null, otherwise
+       set vfm_source to null pointer.  Don't free temp_case.
+       (disk_source_read) Add struct ccase * parameter, use instead of
+       temp_case.
+       (memory_source_read) Ditto.
+       (lag_case) Add const struct ccase * member.
+       (procedure_write_case) Use trns_case instead of temp_case.
+       (clear_case) Add struct ccase * member, use instead of temp_case.
+       (exclude_this_case) Ditto.
+       (create_case_source) Add struct dictionary * parameter, use to
+       initialize source->value_cnt.
+
+       * vfm.h: (struct case_source) Add `value_cnt' member.
+       (struct case_source_class) Add struct ccase * parameter to `read'
+       member function pointer.
+       (struct case_sink_class) Make struct ccase * parameter const in
+       `write' member function pointer.
+       
+Wed Mar  3 20:44:37 2004  Ben Pfaff  <blp@gnu.org>
+
+       Fix a lot of "possibly uninitialized variable" warnings.  Some of
+       them are even real bugs.  A few of them make me wonder how the
+       code ever worked.
+
+       * aggregate.c: (parse_aggregate_functions) Initialize `function.
+
+       * ascii.c: (output_lines) Add default case to switch.
+
+       * crosstabs.q: Remove static variable `expected' and all
+       references to it.
+       (display_crosstabulation) Always calculate expected value.
+       (calc_chisq) Ditto.
+       (output_pivot_table) Initialize `cmp'.
+       (display_crosstabulation) New variable `last_row', which is
+       initialized.
+
+       * data-in.c: (parse_numeric) Always initialize sign.  How did this
+       work at all?!
+
+       * data-list.c: (repeating_data_trns_proc) Always initialize code.
+       Always set info.ofs.  (How did this work?!)
+
+       * expr-opt.c: (optimize_tree) Always initialize `m'.
+       (evaluate_tree) Always initialize `c'.  (How did this work?)
+
+       * frequencies.q: (frq_custom_variables) Always initialize min,
+       max.
+       (frq_custom_grouped) Always initialize `dl'.
+
+       * groff-font.c: (groff_read_font) Always initialize char_set.
+
+       * matrix-data.c: (nr_output_data) Initialize `split'.
+       (wr_read_splits) Remove shadowing split_cnt declaration.
+       (wr_output_data) Initialize `split'.
+
+       * output.c: (tokener) Skip add character on syntax error.
+
+       * pool.c: (pool_strndup) Always set `copy'.  (How did this work?!)
+
+       * postscript.c: (read_ps_encodings) Use line.string instead of
+       uninitialized `bp'.
+       (write_text) Add default case to switch.
+       (text) Always initialize multiple variables.  Fix bug with
+       ligatures.
+
+       * print.c: (fixed_parse_fortran) Initialize head.
+       (alloc_line) Add default case to switch.
+
+       * recode.c: (parse_dest_spec) Handle case where nothing matches.
+       (recode_trns_proc) Move variable declaration inward.  Add default
+       case to switch.
+
+       * sfm-read.c: (read_header) Initialize skip_amt.
+
+       * sysfile-info.c: (display_variables) Always initialize pc.
+
+       * vars-prs.c: Initialized `included'.
+
+Wed Mar  3 09:30:09 2004  Ben Pfaff  <blp@gnu.org>
+
+       * main.c: (main) sigaction()'s sa_flags member was uninitialized.
+       Just use signal() instead.
+
+Wed Mar  3 09:26:30 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of vfm_sink_info and vfm_source_info.
+       
+       * aggregate.c: (agr_00x_end_func) Don't increment
+       sfm_sink_info.ncases.
+
+       * sort.c: (do_internal_sort) Get case count from
+       vfm_source->class->count().
+       (struct external_sort) Add `case_size' member.
+       (do_external_sort) Initialize case_size.
+       (struct initial_run_state) Add `case_size' member.
+       (write_initial_runs) Initialize case_size.
+       (sort_sink_write) Use case_size.
+       (read_external_sort_output) Use case_size.  Get case_cnt from
+       initial_runs.
+
+       * vfm.c: (struct write_case_data) Add underscores to existing arg
+       names, all references updated.  Renamed `aux' as `func_aux', all
+       references updated.  Added new `aux' member.
+       (global var vfm_source_info) Removed.
+       (global var vfm_sink_info) Removed.
+       (struct procedure_aux_data) New.
+       (struct split_aux_data) New.
+       (procedure) Use `aux' fields for procedure_aux_data,
+       split_aux_data.
+       (process_active_file_write_case) Pass case_count + 1 to
+       transformation procedures, exclude_this_case().
+       (process_active_file_output_case) Don't increment
+       vfm_sink_info.ncases.
+       (prepare_for_writing) Don't initialize vfm_sink_info.  Don't try
+       to send data to disk early.
+       (make_temp_case) Don't use vfm_sink_info.case_size.
+       (close_active_file) Don't initialize vfm_source_info.
+       (struct disk_stream_info) New, to allow for case_cnt and case_size fields.
+       (disk_sink_create) Initialize and/or update disk_stream_info.
+       (disk_sink_write) Ditto.
+       (disk_sink_destroy) Ditto.
+       (disk_sink_make_source) Ditto.
+       (disk_source_read) Ditto.
+       (disk_source_destroy) Ditto.
+       (global var disk_source_class) Add disk_source_count().
+       (disk_source_count) New function.
+       (struct memory_sink_info) Add `case_cnt', `case_size' members.
+       (struct memory_source_info) Ditto.
+       (memory_sink_create) Deal with case_cnt, case_size.
+       (memory_sink_write) Ditto.
+       (memory_sink_make_source) Ditto.
+       (memory_source_read) Ditto.
+       (memory_source_count) New function.
+       (memory_source_class) Add memory_source_count().
+       (procedure_write_case) Don't use vfm_sink_info.ncases.  Do use
+       proc_aux->cases_written, and pass it to transformation procedures
+       and exclude_this_case ().
+       (exclude_this_case) Add case_num parameter.  Pass it to
+       expr_evaluate().
+       (SPLIT_FILE_procfunc) Use split_aux->prev_case instead of static
+       variable.
+
+       * vfm.h: (struct case_source_class) Add `count' member.
+
+       * vfmP.h: (struct stream_info) Removed.
+       (global variable vfm_source_info) Removed.
+       (global variable vfm_sink_info) Removed.
+       
+Tue Mar  2 23:38:17 2004  Ben Pfaff  <blp@gnu.org>
+
+       * var.h: (typedef trns_proc_func) New typedef.
+       (trns_free_func) New typedef.
+       (struct trns_header) Change `proc' to type trns_proc_func, `free'
+       to type trns_free_func.  This only changes the actual type of
+       trns_proc_func, adding a `case_num' parameter.  Updated all
+       implementations to use the typedefs instead.
+
+       * compute.c: (compute_num) Pass case_num to expr_evaluate().
+       (compute_num_vec) Ditto.
+       (compute_str) Ditto.
+       (compute_str_vec) Ditto.
+
+       * do-if.c: (do_if_trns_proc) Ditto.
+
+       * expr-evl.c: (expr_evaluate) Add new case_num parameter, use for
+       OP_CASENUM.
+
+       * inpt-pgm.c: (input_program_source_read) Maintain case count,
+       pass to transformation functions.
+       (reread_trns_proc) Pass case_num arg to expr_evaluate().
+
+       * loop.c: (loop_1_trns_proc) Ditto.
+       (loop_2_trns_proc) Ditto.
+       (loop_3_trns_proc) Ditto.
+
+       * print.c: (print_space_trns_proc) Ditto.
+
+       * sel-if.c: (select_if_proc) Ditto.
+
+Tue Mar  2 11:36:52 2004  Ben Pfaff  <blp@gnu.org>
+
+       * frequencies.q: (cleanup_freq_tab) Avoid memory leak by
+       destroying hash table.
+
+       * glob.c: (read_active_file) Variable not referenced, removed.
+       (cancel_input_pgm) Ditto.
+
+       * levene.c: Add #include <stdlib.h> needed to call free().
+
+       * aggregate.c: (parse_aggregate_functions) Make `function'
+       variable const.
+
+Tue Mar  2 11:30:56 2004  Ben Pfaff  <blp@gnu.org>
+
+       Start working to eliminate VFM dependence on static variables.
+
+       * command.c: (cmd_parse) Use case_source_is_class().
+
+       * data-list.c: Rewrite to eliminate use of static variables.
+
+       * dfm.c: (cmd_begin_data) Use case_source_is_class().
+
+       * file-handle.q: (fh_handle_name) Make parameter const.
+
+       * file-type.c: Rewrite to eliminate use of static variables.
+
+       * flip.c: Rewrite to eliminate use of static variables.
+
+       * format.c: (get_format_var_width) New function.
+
+       * get.c: Eliminate use of static variables.
+
+       * inpt-pgm.c: Eliminate use of static variables.
+
+       * matrix-data.c: Eliminate use of static variables.
+
+       * set.q: (set_max_workspace) New variable.
+       (cmd_set) Use SET WORKSPACE to modify set_max_workspace.
+
+       * var.h: (struct case_list) Move here from vfmP.h.
+
+       * vars-atr.c: (discard_variables) Handle new vfm_source type.
+
+       * vfm.c: (vfm_source) Change type from struct case_stream to
+       struct case_source.
+       (vfm_sink) Change type from struct case_stream to struct
+       case_sink.
+       (static var paging) Rename workspace_overflow, all references
+       updated.
+       (procedure) Use new class structures.
+       (process_active_file) Ditto.
+       (process_active_file_write_case) Ditto.
+       (prepare_for_writing) Use set_max_workspace.  Use new class
+       structures.
+       (close_active_file) Use new class structures.  Free old sink.
+       (global var disk_source_file) Removed.
+       (global var disk_sink_file) Removed.
+       (disk_stream_init) Removed.
+       (disk_stream_read) Removed.
+       (disk_stream_write) Removed.
+       (disk_stream_mode) Removed.
+       (disk_stream_destroy_source) Removed.
+       (disk_stream_destroy_sink) Removed.
+       (global var vfm_disk_stream) Removed.
+       (disk_sink_create) New function.
+       (disk_sink_write) New function.
+       (disk_sink_destroy) New function.
+       (disk_sink_make_source) New function.
+       (disk_sink_class) New static var.
+       (disk_source_read) New function.
+       (disk_source_destroy) New function.
+       (global var vfm_source_class) New var.
+       (global var memory_source_cases) Removed.
+       (global var memory_sink_cases) Removed.
+       (global var memory_sink_max_cases) Removed.
+       (struct memory_sink_info) New struct.
+       (memory_stream_init) Removed.
+       (memory_stream_read) Removed.
+       (memory_stream_write) Removed.
+       (memory_stream_mode) Removed.
+       (memory_stream_destroy_source) Removed.
+       (memory_stream_destroy_sink) Removed.
+       (global var vfm_memory_stream) Removed.
+       (page_to_disk) Renamed write_active_file_to_disk().
+       (memory_sink_create) New function.
+       (memory_sink_write) New function.
+       (memory_sink_destroy) New function.
+       (memory_sink_make_source) New function.
+       (memory_sink_class) New static var.
+       (memory_source_read) New function.
+       (memory_source_destroy) New function.
+       (memory_source_get_cases) New function.
+       (memory_source_set_cases) New function.
+       (global var vfm_source_class) New var.
+       (procedure_write_case) Use new class structures.
+       (create_case_source) New function.
+       (case_source_is_complex) New function.
+       (case_source_is_class) New function.
+       (create_case_sink) New function.
+
+       * vfm.h: (global variable reinit_sysmis) Not used, removed.
+       (global variable reinit_blanks) Not used, removed.
+       (global variable init_zero) Not used, removed.
+       (global variable init_blanks) Not used, removed.
+       (struct case_source) New struct.
+       (struct case_source_class) New struct.
+       (struct case_sink) New struct.
+       (struct case_sink_class) New struct.
+       (struct case_stream) Removed.
+
+       * vfmP.h: (struct case_list) Moved to var.h.
+
+Tue Mar  2 11:28:30 2004  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: (count_equal) New function.
+       (count_if) New function.
+       (unique) Add assertions.
+       (partition) Add assertions.
+       (is_partitioned) New function.
+       (copy_if) Add assertions.
+       (remove_equal) Add assertions.
+       (lexicographical_compare) Rename lexicographical_compare_3way.
+       (sort) Add assertions.  Rephrase some code.
+       (is_sorted) New function.
+
+Sun Feb 29 23:24:57 2004  Ben Pfaff  <blp@gnu.org>
+
+       Rewrite SORT CASES.
+
+       * sort.c: Completely rewrite.
+
+       * sort.h: Expose interface via struct sort_cases_pgm, not via
+       global variables.
+
+       * aggregate.c: (sort) New static var.
+       (cmd_aggregate) Use sort.
+       (create_sysfile) Ditto.
+       (aggregate_single_case) Ditto.
+       (dump_aggregate_info) Ditto.
+       (agr_00x_end_func) Ditto.
+       (debug_print) Ditto.
+
+       * var.h: (enum SRT_ASCEND) Removed.
+       (enum SRT_DESCEND) Removed.
+       (struct sort_cases_proc) Removed.
+       (struct variable) Remove p.srt member.
+
+Sun Feb 29 23:22:45 2004  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of the old, crappy heap structure and replace it by a new,
+       shiny, C++ STL-like heap structure.
+       
+       * Makefile.am: (pspp_SOURCES) Remove heap.c, heap.h.
+
+       * algorithm.c: (push_heap) New function.
+       (heapify) Ditto.
+       (pop_heap) Ditto.
+       (make_heap) Ditto.
+       (sort_heap) Ditto.
+       (is_heap) Ditto.
+       
+       * heap.c: Removed.
+
+       * heap.h: Removed.
+
+Sun Feb 29 23:21:53 2004  Ben Pfaff  <blp@gnu.org>
+
+       Increase warning level.
+       
+       * Makefile.am: (AM_CFLAGS) Remove -Wnouninitialized.
+
+Sat Feb 21 17:38:58 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+        * main.c: Added a signal handler for SIGSEGV requesting a bug report.
+        
+Fri Feb 20 23:22:14 2004  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c: (dict_create_var) Fix root cause of bug worked
+       around by previous change log entry.
+       
+       * compute.c: (lvalue_finalize) Remove workaround from previous
+       change log entry.
+
+Fri Feb 20 14:37:41 WAST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * compute.c: Fixed a bug where the Format was not getting set for 
+         computed variables (thus causing a crash when SAVEing).
+
+       * Added a test to stop this bug ever coming back
+
+Wed Feb 18 22:21:35 2004  Ben Pfaff  <blp@gnu.org>
+
+       Got rid of approx.h.  In general, replaced all references to
+       approx_eq() by ==, approx_lt() by <, etc.  Other types of changes
+       noted below.
+
+       * Makefile.am: (pspp_SOURCES) Removed approx.h.
+
+       * data-out.c: (try_F) Replaced test for approx_eq(number, 0.0) by
+       test for mag < EPSILON.
+
+       * misc.h: Add definition of EPSILON.
+
+Wed Feb 18 21:32:44 2004  Ben Pfaff  <blp@gnu.org>
+
+       * vfm.c: (procedure) Add check to prevent recursive call.
+
+Wed Feb 18 21:48:54 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * Moved the declarations relating to values to their own header file
+         (val.h)
+
+       * Added levene.c and levene.h
+
+       * vars-atr.c: Changed the signature of compare_values to 
+       take const * arguments.
+               
+       * t-test.q: Changed the structure of struct t_test_proc 
+       variables now contain their own group statistics information.
+       Eventually, t_test_proc might get renamed, because it'd be 
+       applicable to other commands too.
+
+Mon Feb 16 23:15:51 2004  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c: Clean up.  Changed interface of convert_*() to take
+       either a `double' or a `const char *' instead of a `const union
+       value *'.  Update all implementations of those interfaces.
+       (data_out) Use switch statements instead of a table.
+       (convert_AHEX) Rewrite.
+
+       * format.h: Update comment.
+
+Mon Feb 16 22:14:36 2004  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: (dump_header) Add an Emacs header line to output files
+       that makes generated .c files read-only by default, to make it
+       difficult to accidentally change generated files.
+
+Mon Feb 16 22:12:07 2004  Ben Pfaff  <blp@gnu.org>
+
+       * frequencies.q: (compare_freq_numeric_a) Compare by frequency,
+       not bogus a->v.c <=> b->v.c pointer compare.
+       (compare_freq_alpha_a) Ditto.
+       (compare_freq_numeric_d) Ditto.
+       (compare_freq_alpha_d) Ditto.
+       
+Mon Feb 16 22:00:53 2004  Ben Pfaff  <blp@gnu.org>
+
+       Changed data_out() to store string data directly into a `union
+       value''s s member, not indirectly into c.
+
+       * crosstabs.q: (output_pivot_table) Use format_short() instead of
+       data_out().
+       (table_value_missing) Ditto.
+       (float_M_suffix) Ditto.
+       (format_short) New function.
+
+       * data-in.h: (data_in_finite_line) Remove inline definition.
+
+       * data-list.c: (destroy_dls_var_spec) New function.
+       (destroy_dls) Rewrite in terms of destroy_dls_var_spec().
+       (data_list_source_destroy_source) Avoid cast.
+       (struct repeating_data_trns) New field `id_value'.  Update
+       comments.
+       (cmd_repeating_data) Initialize id_value.  Use new
+       repeating_data_trns_free() for freeing REPEATING DATA
+       transformations.
+       (rpd_parse_record) Rewrite support for record ID to be less bogus.
+       (repeating_data_trns_free) New function.
+
+       * data-out.c: (data_out) Change return type to `void' by replacing
+       error returns by writing a message into the output buffer.
+       (convert_A) Read from v->s instead of v->c.
+       (convert_AHEX) Ditto.
+
+       * expr-evl.c: Update comment.
+       (expr_evaluate) Add assertion in OP_STRING case.
+
+       * format.h: (macro MAX_FORMATTED_LEN) New macro.
+
+       * list.q: (list_cases) Update for new data_out() semantics.
+
+       * print.c: (print_trns_proc) Ditto.
+
+       * tab.c: (tab_value) Ditto.
+       (tab_float) Avoid stupid cast.
+
+       * var.h: Update comments.
+       (macro MAX_STRING) New macro.
+       (macro MAX_ELEMS_PER_VALUE) New macro.
+
+       * vars-atr.c: (compare_values) New function.
+
+       * vfm.c: (dump_splits) Update for new data_out() semantics.
+
+Mon Feb 16 21:45:47 2004  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (struct table_entry) Rename v[] to values[].  All
+       references updated.
+       (struct crosstab) Rename v[] to vars[].  All references updated.
+       (hash_table_entry) Replace the hash algorithm and fix a bug at the
+       same time, which caused the hash value to depend only on a single
+       value, not all of the variables' values.
+       
+Mon Feb 16 12:49:53 2004  Ben Pfaff  <blp@gnu.org>
+
+       Clean up struct dictionary's value_cnt usage.
+
+       * dictionary.c: Add a function comment to each function.
+       (struct dictionary) Rename value_cnt to next_value_idx, which more
+       accurately reflects its meaning.  All references updated.
+       (dict_rename_vars) Add assertion.
+       (dict_get_value_cnt) Rename dict_get_next_value_idx().  All
+       references updated.
+       (dict_get_case_size) New function.
+
+       * aggregate.c: (create_sysfile) Use dict_get_case_size().
+
+       * get.c: (mtf_read_nonactive_records) Ditto.
+
+       * sort.c: (allocate_cases) Ditto.
+       (write_initial_runs) Ditto.
+       (merge) Ditto.
+       (merge_once) Ditto.
+
+       * vfm.c: (prepare_for_writing) Ditto.
+       (setup_lag) Ditto.
+       (lag_case) Ditto.
+
+Mon Feb 16 00:17:55 2004  Ben Pfaff  <blp@gnu.org>
+
+       Make vfm.c slightly less grotesque.
+
+       * vfm.c: (filter_var) Removed.
+       (filter_index) Removed.
+       (FILTERED macro) Removed.
+       (exclude_this_case) New function.
+       (process_active_file_write_case) Use exclude_this_case() instead
+       of FILTERED and inline tests.
+       (procedure_write_case) Ditto.
+       (setup_filter) Removed.
+       (open_active_file) Don't call setup_filter().
+       (close_active_file) Call dict_get_filter() instead of checking
+       filter_var.
+
+Mon Feb 16 00:01:53 2004  Ben Pfaff  <blp@gnu.org>
+
+       * var.h: (struct variable) Update comments.
+
+Sun Feb 15 23:14:59 2004  Ben Pfaff  <blp@gnu.org>
+
+       New functions dict_create_var_assert(), dict_lookup_var_assert().
+       Converted several dict_*_var()/assert pairs into a single
+       dict_*_var_assert().
+
+       * dictionary.c: (dict_create_var_assert) New function.
+       (dict_lookup_var_assert) New function.
+
+Sun Feb 15 23:06:08 2004  Ben Pfaff  <blp@gnu.org>
+
+       Got rid of "struct long_vec", envector(), devector(), etc.  Added
+       two members `init', `reinit' to struct variable as a substitute.
+       
+       * Makefile.am: (pspp_SOURCES) Removed cases.c, cases.h.
+       
+       * cases.c: Removed.
+
+       * cases.h: Removed.
+
+       * aggregate.c: (parse_aggregate_functions) destvar doesn't need
+       init.
+
+       * autorecode.c: (cmd_autorecode) destvars don't need init.
+
+       * compute.c: (lvalue_finalize) Set reinit.
+
+       * data-list.c: (fixed_parse_compatible) Don't need init usually.
+       (dump_fmt_list) Ditto.
+       (parse_free) Ditto.
+
+       * descript.q: (run_z_pass) Don't need init for z-scores.
+
+       * dictionary.c: (dict_create_var) Initialize `init', `reinit'
+       members.
+       (dict_clone_var) Copy `reinit' member, initialize `init' member.
+
+       * glob.c: (init_glob) Remove vec_init() calls.
+
+       * inpt-pgm.c: (cmd_end_input_program) Use `reinit', not `left'.
+       
+       * loop.c: (internal_cmd_loop) Don't need to call envector().
+
+       * numeric.c: (cmd_numeric) Ditto.
+       (cmd_string) Ditto.
+       (cmd_leave) Ditto.  Set `init', `reinit' members.
+
+       * recode.c: (cmd_recode) Don't need to call envector().
+
+       * repeat.c: (internal_cmd_do_repeat) Ditto.
+
+       * var.h: (struct variable) Remove `left'.  Add `init', `reinit'.
+       (force_create_variable) Removed prototype.
+       (force_dup_variable) Ditto.
+
+       * vector.c: (cmd_vector) Don't need to call envector().
+
+       * vfm.c: (reinit_sysmis) Removed.
+       (reinit_blanks) Removed.
+       (init_zero) Removed.
+       (init_blanks) Removed.
+       (process_active_file_write_case) No need to deal with vectors.
+       Call clear_temp_case().
+       (vector_initialization) Rewrite to use `init', `reinit'.
+       (close_active_file) No need to call vec_clear().
+       (procedure_write_case) Call clear_temp_case().
+       (clear_temp_case) New function.
+
+Sun Feb 15 20:50:36 2004  Ben Pfaff  <blp@gnu.org>
+
+       * pfm-write.c: (bufwrite) Get rid of nasty cast that also invoked
+       undefined behavior.
+
+Thu Feb 12 23:35:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       Add auxiliary argument to procedure() interface.  Associated small
+       clean-ups of vfm interface.
+       
+       * Updated every caller of procedure() and process_active_file() to
+       reflect modified interface.  Simple, ordinary changes not listed
+       otherwise below.
+
+       * Updated every function that implements struct case_stream's
+       `read' function to take a write_case_func and a write_case_data.
+       Also updated every caller of write_case() to instead call them
+       through these arguments.  In some cases this meant that the extra
+       args had to be threaded through a couple of extra levels.  This
+       wasn't difficult or interesting so the details won't be given.
+
+       * data-list.c: (struct repeating_data_trns) Add members
+       `write_case', `wc_data' as kluge.
+       (read_one_set_of_repetitions) Rename repeating_data_trns_proc and
+       make non-static.
+       (repeating_data_set_write_case) New function.
+
+       * data-list.h: New file to declare repeating_data_trns_proc() and
+       repeating_data_set_write_case().
+
+       * inpt-pgm.c: (input_program_source_read) Call
+       repeating_data_set_write_case() for all the REPEATING DATA
+       transformations, so that they know where to send their cases.
+       It's a big kluge.  Also kluge in END CASE.
+       (end_case_trns_proc) Never called anymore, but we still need it,
+       so just assert(0).
+
+       * sort.c: (read_sort_output) Update to match struct case_stream
+       `read' member.
+
+       * vfm.c: (struct write_case_data) New structure.
+       (proc_func) Removed.
+       (virt_proc_func) Removed.
+       (begin_func) Removed.
+       (virt_begin_func) Removed.
+       (end_func) Removed.
+       (write_case) Removed.
+       (procedure) Added an auxiliary parameter to each function pointer
+       argument's prototype.  Added an auxiliary data parameter.
+       Rewrote.
+       (process_active_file) Ditto.
+       (process_active_file_write_case) Pass aux data along.
+       (close_active_file) Ditto.
+       (procedure_write_case) Ditto.
+       (SPLIT_FILE_procfunc) Ditto.
+
+       * vfm.h: (typedef write_case_data) New.
+       (typedef write_case_func) New.
+       (struct case_stream) Add parameters to `read' member prototype.
+       
+Thu Feb 12 19:24:53 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q:  Added calculations for independent samples. (But no Levene
+       test yet!)
+
+       * Makefile.am: Moved q_sources_c into own variable 
+
+Wed Feb 11 23:56:51 2004  Ben Pfaff  <blp@gnu.org>
+
+       Miscellaneous cleanups.
+       
+       * Change unused to UNUSED in many source files to reflect modified
+       pref.h.  Change use of __WIN32__, __MSDOS, __DJGPP__,
+       __CYGWIN32__, __unix__, and unix not to assume that they're
+       defined to a nonzero value.  Change use of __attribute__ to use
+       NO_RETURN or PRINTF_FORMAT instead.
+       
+       * alloc.h: Move definitions for local_alloc(), local_free() here
+       from ../pref.h.orig and simplify.
+
+       * expr-evl.c: Instead of working differently based on PAGED_STACK,
+       use a pool allocator unconditionally.
+       (CHECK_STRING_SPACE) Removed.
+       (ALLOC_STRING_SPACE) Removed.
+       (expr_evaluate) Use e->pool instead of CHECK_STRING_SPACE and
+       ALLOC_STRING_SPACE.
+
+       * expr-opt.c: (dump_expression) Allocate string pool.
+
+       * expr-prs.c: (expr_free) Free string pool.
+
+       * pool.c: (pool_destroy) This pool must be removed from its
+       parent's list of gizmos, not from its own.  Use free_all_gizmos().
+       (pool_clear) New function.
+       (free_all_gizmos) New function.
+       (pool_alloc) Use space in empty block after this one if any.
+       (pool_release) Only empty out blocks, don't actually free() them.
+
+       * print.c: Get rid of PAGED_STACK special case by always
+       dynamically allocating line buffers.
+       (struct print_trns) Always include the `line' member.
+       (internal_cmd_print) Always initialize the `line' member.
+       (alloc_line) Always allocate memory for `line'.
+       (print_trns_proc) Always initialize buf from `line' member.
+       (print_trns_free) Always free `line' memory.
+
+       * sort.c: (allocate_file_handles) Special-case MS-DOS for mkdir()
+       call.
+       
+Wed Feb 11 20:33:18 2004  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: Fixed crash from FLIP when a numeric variable is
+         specified on NEWNAMES and a large value is used, and a couple of
+         other minor bugs besides.
+         (struct varname) Make name a 9-character fixed-size array
+         instead of a 1-character variable size array.
+         (make_new_var) Allow digits in variable names.
+         (flip_stream_write) Limit numeric values to 8 characters and
+         format system missing and very large and small values more
+         appropriately.
+
+Thu Feb  5 13:19:06 WAST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * command.c: Fixed test on command return status for the correct 
+          value,  which had been causing a crash under certain invalid input.
+
+Wed Feb  4 15:34:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q: Added calculations for the one sample variant of the T-TEST
+
+Tue Feb  3 20:09:54 2004  Ben Pfaff  <blp@gnu.org>
+
+       * tab.c: (render_strip) Fix bug that sometimes caused joined text
+         in joined cells to be rendered outside box boundaries.
+
+Tue Feb  3 18:56:45 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * random.c (rng_create): Fixed seeding so that it gets reseeded after
+       SET seed=xx has been called.
+
+Mon Jan 19 14:08:09 2004  Ben Pfaff  <blp@gnu.org> 
+
+       * random.c (rng_get_double): Fix always-returning-zero bug in my
+       preferred way, and at the same time make sure rounding doesn't
+       bite us.
+
+Thu Jan  1 23:16:41 2004  Ben Pfaff  <blp@gnu.org>
+
+       * html.c: (change_attributes) Dead code, removed.
+       (escape_string) Eliminate code to call change_attributes() that
+       never actually called it.
+       (output_tab_table) Get rid of dependence on tab_hit
+       and struct tab_joined_cell's hit member, which are abominations.
+
+       * tab.c: (tab_output_text) Don't call
+       d->class->text_set_font_by_name if it's a null pointer.
+       (macro UNROLL_LOOP) Eliminate.
+       (macro UNROLL_3_LOOPS) Eliminate.
+       (tabi_render) Rewrite not to use the above macros.
+
+Thu Jan  1 23:09:07 2004  Ben Pfaff  <blp@gnu.org>
+
+       Start working on a new output driver system, one that doesn't suck
+       so much, by adding a "device-independent" output driver.  The idea
+       is to write out only a single output stream, then use separate
+       processes to translate them into whatever formats we want.  This
+       is similar to how "groff" works with its various output drivers
+       (grops, grotty, grodvi, ...).
+       
+       * Makefile.am: (pspp_SOURCES) Add devind.c, devind.h.
+
+       * list.q: (write_all_headers) Stub out devind class.
+       (clean_up) Ditto.
+       (determine_layout) Ditto.
+       (list_cases) Ditto.
+
+       * output.c: (outp_init) Add devind class.
+
+       * devind.c: New file.
+
+       * devind.h: New file.
+
+Thu Jan  1 23:08:14 2004  Ben Pfaff  <blp@gnu.org>
+
+       * frequencies.q: (hash_value_alpha) Fixed up the previous change
+       to use the proper string length.
+
+Wed Dec 31 16:27:33 WAST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * Fixed bug where FREQ would crash on alpha values
+
+Tue Dec 30 22:42:57 2003  Ben Pfaff  <blp@gnu.org>
+
+       * Removed bletcherous alloca() workarounds for AIX from top of
+       many files.  AIX can use the alternative alloca() implementation
+       instead.
+
+Tue Dec 30 22:35:16 2003  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_option) Fix implementation of headers option.
+
+Tue Dec 30 22:32:53 2003  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: Add a "squeeze" option to the ASCII driver to squeeze
+       multiple blank lines into one.
+       (struct ascii_driver_ext) Add squeeze_blank_lines option.
+       (ascii_preopen_driver) Initialize squeeze_blank_lines.
+       (static var option_tab) Add squeeze entry.
+       (ascii_option) Set squeeze_blank_lines.
+       (output_lines) Implement squeezing blank lines.
+
+Wed Dec 31 07:19:46 WST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * Removed redundant code from output.h
+
+Sat Dec 27 22:17:52 2003  Ben Pfaff  <blp@gnu.org>
+
+       Dictionary classes: each variable is "ordinary", "system", or
+       "scratch".
+
+       * var.h: (enum dict_class) New enum.
+
+       * vars-prs.c: (dict_class_from_id) New function.
+       (dict_class_to_name) New function.
+
+Sat Dec 27 22:16:06 2003  Ben Pfaff  <blp@gnu.org>
+
+       * var.h: (struct freq_tab_set) Removed (not used).
+
+Sat Dec 27 22:15:21 2003  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c: (val_labs_destroy) vls needs to be freed too.
+
+Sat Dec 27 22:10:49 2003  Ben Pfaff  <blp@gnu.org>
+
+       * stats.c: (hypercube) Rename pow4().  All references updated.
+
+Sat Dec 27 22:05:49 2003  Ben Pfaff  <blp@gnu.org>
+
+       * rename-vars.c: (cmd_rename_variables) Rewritten.
+       (compare_name) Removed.
+
+Sat Dec 27 22:03:51 2003  Ben Pfaff  <blp@gnu.org>
+
+       var_set feature, and code taking advantage of it.
+       
+       * crosstabs.q: (static var var_dict) Removed.
+       (static var variables) New variable.
+       (static var variables_cnt) New variable.
+       (cmd_crosstabs) Free variables instead of var_dict.
+       (internal_cmd_crosstabs) Initialize and use variables,
+       variables_cnt instead of var_dict.
+       (free_var_dict) Removed.
+       (crs_custom_tables) Use var_set instead of a copied dictionary.
+       (crs_custom_variables) Set up variables, variables_cnt instead of
+       var_dict.
+       [DEBUGGING] (debug_print) Ditto.
+
+       * means.q: (mns_custom_tables) Use var_set instead of a copied
+       dictionary.
+
+       * vars-prs.c: (parse_vs_variable) New function.
+       (parse_dict_variable) Rewritten.
+       (parse_variable) Rewritten.
+       (parse_variables) Renamed parse_var_set_vars(), rewritten.
+       (parse_variables) New function in terms of parse_var_set_vars().
+       Now requires its first argument to be non-null.  All references
+       that passed a null pointer updated to pass default_dict instead.
+       (macro id_dict) Removed.
+       (parse_DATA_LIST_vars) Add assertions.
+       (parse_mixed_vars) Ditto.
+       (struct var_set) New structure.
+       (var_set_get_cnt) New function.
+       (var_set_get_var) New function.
+       (var_set_lookup_var) New function.
+       (var_set_destroy) New function.
+       (dict_var_set_get_cnt) New function.
+       (dict_var_set_get_var) New function.
+       (dict_var_set_lookup_var) New function.
+       (dict_var_set_destroy) New function.
+       (var_set_create_from_dict) New function.
+       (struct array_var_set) New structure.
+       (array_var_set_get_cnt) New function.
+       (array_var_set_get_var) New function.
+       (array_var_set_lookup_var) New function.
+       (array_var_set_destroy) New function.
+       (var_set_create_from_array) New function.
+
+       * q2c.c: (dump_parser) Use parse_variables(default_dict, ...)
+       instead of parse_variables(NULL, ...) in output code.
+
+Sat Dec 27 21:38:53 2003  Ben Pfaff  <blp@gnu.org>
+
+       Change inp_init from a 2-bit vector to an ordinary array.
+       Initialize it all in cmd_end_input_program() instead of in
+       create_variable().
+
+       * inpt-pgm.c: (enum value_init_type) New enum.
+       (global var inp_init) Change to `enum value_init_type *', make
+       static.
+       (inp_init_size) Removed.
+       (inp_nval) Change to `size_t', make static.
+       (cmd_input_program) Don't initialize inp_init or inp_init_size.
+       (cmd_end_input_program) Initialize inp_init, inp_nval.
+       (init_case) Rewrite.
+       (clear_case) Rewrite.
+
+       * inpt-pgm.h: Removed.
+
+Sat Dec 27 21:36:38 2003  Ben Pfaff  <blp@gnu.org>
+
+       * hash.c: (hsh_hash_bytes) Use Fowler-Noll-Vo hash instead of
+       Colin Plumb hash.  It is simpler and should better resist
+       collisions.
+       (hsh_hash_string) Ditto.
+
+Sat Dec 27 21:34:57 2003  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (export_write_case_func) Remove debug printing code.
+
+Sat Dec 27 21:11:09 2003  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_save_internal) Rename parameter.  Use &t->h instead
+       of cast.
+       (save_write_case_func) Use &trns->h instead of cast.
+       (cmd_export) Use &t->h instead of cast.
+
+Sat Dec 27 20:57:42 2003  Ben Pfaff  <blp@gnu.org>
+
+       Moved vectors into the dictionary.
+
+       * var.h: (struct vector) Moved here from vector.h.  `index' member
+       renamed `idx', `v' renamed `var', `nv' renamed `cnt'.  All
+       references updated.
+       
+       * vector.h: Removed.
+
+       * vector.c: (global var vec) Removed.
+       (global var nvec) Removed.
+       (cmd_vector) Rewritten.
+       (find_vector) Removed.
+
+       * dictionary.c: (dict_create_vector) New function.
+       (dict_get_vector) New function, replaces reading global vec[]
+       array.
+       (dict_get_vector_cnt) New function, replaces reading global nvec
+       variable.
+       (dict_lookup_vector) New function, replaces find_vector().
+       (dict_clear_vectors) New function.
+
+Sat Dec 27 20:54:01 2003  Ben Pfaff  <blp@gnu.org>
+
+       Start to move away from `struct variable' p `union' member to void
+       * aux member.
+
+       * var.h: (struct variable) Add `aux' member.
+
+Sat Dec 27 20:36:25 2003  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of struct variable `foo' member.
+
+       * frequencies.q: (internal_cmd_frequencies) Use p.frq.used instead
+       of foo.
+       (frq_custom_variables) Ditto.
+       (frq_custom_grouped) Ditto.
+
+       * get.c: (struct save_trns) Change `var' member from `int *' to
+       `struct variable **'.
+       (cmd_save_internal) Use aux instead of foo.
+       (save_trns_proc) Use revised `var' member.
+       (static var mtf_seq_no) Renamed mtf_seq_num.
+       (static var mtf_seq_nums) New static var.
+       (cmd_match_files) Initialize mtf_seq_nums.
+       (mtf_free) Free mtf_seq_nums.
+       (mtf_processing) Use mtf_seq_nums instead of foo.
+       (mtf_merge_dictionary) No need to initialize mv->foo.
+       (cmd_export) Use aux instead of foo.  Use revised `var' member.
+       (mns_custom_tables) Don't use foo to check for duplicates, that's
+       what PV_NO_DUPLICATE is for.
+
+       * var.h: (struct variable) Remove `foo' member.
+       (struct frequencies_proc) New member.
+       
+Sat Dec 27 19:46:13 2003  Ben Pfaff  <blp@gnu.org>
+
+       Clean up COMPUTE and IF.
+
+       * compute.c: More or less rewrite the darn thing.
+       (struct compute_trns) Rename and reorder and add and delete
+       members.
+       (cmd_compute) Rewrite.
+       (compute_num) Make conditional on test expression.  Now used for
+       both COMPUTE and IF.
+       (compute_num_vec) Ditto.
+       (compute_str) Ditto.
+       (compute_str_vec) Ditto.
+       (cmd_if) Rewrite.
+       (if_num) Removed.
+       (if_num_vec) Removed.
+       (if_str) Removed.
+       (if_str_vec) Removed.
+       (parse_target_expression) Renamed parse_rvalue_expression(),
+       rewritten.
+       (new_trns) Renamed compute_trns_create(), rewritten.
+       (delete_trns) Removed.
+       (free_trns) Renamed compute_trns_free(), rewritten.
+       (struct lvalue) New structure.
+       (parse_var_or_vec) Renamed lvalue_parse(), rewritten.
+       (lvalue_get_type) New function.
+       (lvalue_is_vector) New function.
+       (lvalue_finalize) New function.
+       (lvalue_destroy) New function.
+       
+Sat Dec 27 19:44:14 2003  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Disallow MODIFY VARS in input mode, so that
+       variables can't get dropped and confuse cmd_end_input_program()'s
+       attempt to fill inp_init[].
+       
+       * modify-vars.c: (static var forward_positional_ordering) New
+       variable.
+       (struct var_modification) Entirely changed.
+       (rearrange_dict) Interface changed, rewritten.
+       (cmd_modify_vars) Deal with modified struct var_modification, much
+       rewritten.
+       (struct var_renaming) New structure.
+       (compare_var_renaming_by_new_name) New function.
+       (validate_var_modification) New function.
+
+       * var.h: (struct modify_vars_proc) Removed.
+       (struct variable) Removed member p.mfv.
+
+Sat Dec 27 19:40:26 2003  Ben Pfaff  <blp@gnu.org>
+
+       Make EVALUATE a valid command whether we're debugging or not, so
+       that `make check' can succeed regardless of whether debugging is
+       turned on.
+       
+       * command.def: [GLOBAL_DEBUGGING] Drop the #if.
+
+       * compute.c: [GLOBAL_DEBUGGING] (cmd_evaluate) Drop the #if.
+
+Sat Dec 27 19:34:40 2003  Ben Pfaff  <blp@gnu.org>
+
+       * apply-dict.c: (cmd_apply_dictionary) Replace a ghastly switch
+       statement by a simple if test.
+
+       * dfm.c: (dfm_get_record) Add assertion.
+
+Sat Dec 27 17:51:26 2003  Ben Pfaff  <blp@gnu.org>
+
+       For each file x.c, move #include "x.h" to the very top of the
+       include list, to catch x.h failing to include the proper headers.
+
+Sat Dec 27 17:50:19 2003  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: (find) New function.
+       (remove_equal) New function.
+       (set_difference) New function.
+       (adjacent_find_equal) New function.
+       [TEST_UNIQUE] Removed test case.
+       (copy_if) Find end test.
+
+Sat Dec 27 17:42:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c: (dict_get_case_weight) New convenience function.
+
+       * aggregate.c: (accumulate_aggregate_info) Use
+       dict_get_case_weight().
+
+       * frequencies.q: (calc_general) Ditto.
+       (calc_integer) Ditto.
+       (calc) Ditto.
+
+       * t-test.q: (groups_calc) Ditto.
+       (z_calc) Ditto.
+
+Sat Dec 27 17:29:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * glob.c: (global var default_dict) Change from `struct
+       dictionary' to `struct dictionary *'.  All references changed.
+       (init_glob) Initialize default_dict with dict_create().
+
+Sat Dec 27 17:06:06 2003  Ben Pfaff  <blp@gnu.org>
+
+       struct dictionary now made opaque.  All related functions:
+
+       * get.c: (rename_variables) Removed.
+       (dict_delete_run) Removed.
+       
+       * temporary.c: (copy_variable) Removed.
+       (new_dictionary) Removed.
+       (save_dictionary) Removed.
+       (restore_dictionary) Removed.
+       (free_dictionary) Removed.
+
+       * vars-atr.c: (clear_default_dict) Removed.
+       (find_variable) Removed.
+       (find_dict_variable) Removed.
+       (create_variable) Removed.
+       (delete_variable) Removed.
+       (common_init_stuff) Removed.
+       (init_variable) Removed.  Updating of inp_init moved into
+       cmd_end_input_program().
+       (replace_variable) Removed.
+       (rename_variable) Removed.
+       (clear_variable) Removed.
+       (dup_variable) Removed.
+
+       * vars-prs.c: (is_varname) Removed.
+       (is_dict_varname) Removed.
+       (fill_all_vars) Removed.
+
+       * vector.c: (find_vector) Removed.
+
+       * weight.c: (stop_weighting) Removed.
+
+       * dictionary.c: New file.
+       (dict_create) New, replaces new_dictionary().
+       (dict_clone) New, replaces save_dictionary() and
+       restore_dictionary().
+       (dict_clear) New, replaces clear_default_dict().
+       (dict_destroy) New, replaces free_dictionary().
+       (dict_get_var_cnt) New function, replaces references to
+       dict->nvar.
+       (dict_get_var) New function, replaces references to dict->var[i].
+       (dict_get_vars) New function, replaces fill_all_vars().
+       (dict_create_var) New, replaces create_variable().  Interface
+       drops `type' parameter, using a zero `width' to designate numeric.
+       (dict_clone_var) New, replaces dup_variable().
+       (dict_rename_var) New, replaces rename_variable().
+       (dict_lookup_var) New, replaces find_variable(),
+       find_dict_variable(), is_varname().
+       (dict_contains_var) New function.
+       (compare_variable_dblptrs) New function.
+       (dict_delete_var) New function, replaces clear_variable().
+       (dict_delete_vars) New function, replaces dict_delete_run().
+       (dict_reorder_vars) New function.
+       (dict_rename_vars) New function, replaces rename_variables().
+       (dict_get_weight) New function, replaces reading dict->weight_var.
+       (dict_set_weight) New function, replaces writing dict->weight_var
+       or calling stop_weight(dict).
+       (dict_get_filter) New function, replaces reading dict->filter_var.
+       (dict_set_filter) New function, replaces writing dict->filter_var.
+       (dict_get_case_limit) New function, replaces reading dict->N.
+       (dict_set_case_limit) New function, replaces writing dict->N.
+       (dict_get_value_cnt) New function, replaces reading dict->nval.
+       (dict_compact_values) New function, replaces a loop that was
+       replicated in several places.
+       (dict_get_split_vars) New function, replaces reading dict->splits.
+       (dict_get_split_cnt) New function, replaces reading
+       dict->n_splits.
+       (dict_set_split_vars) New function, replaces writing dict->splits.
+       (dict_get_label) New function, replaces reading dict->label.
+       (dict_set_label) New function, replaces writing dict->label.
+       (dict_get_documents) New function, replaces reading
+       dict->documents.
+       (dict_set_documents) New function, replaces writing
+       dict->documents.
+       
+       All references to above functions updated.
+       
+       * aggregate.c: (cmd_aggregate) Copy file label and documents from
+       old dictionary to new by hand, because dict_create() can't do it
+       itself.  Use dict_set_documents(), dict_set_split_vars().
+
+       * temporary.c: (cancel_temporary) Also set temp_dict to NULL after
+       calling dict_destroy().
+
+       * data-list.c: (dls_var_spec) Remove `type' member, replace by
+       `width'.
+       (fixed_parse_compatible) Some slightly nontrivial changes for
+       dict_create_var().
+       (dump_fmt_list) Ditto.
+       (parse_free) Ditto.
+
+       * file-type.c: (create_col_var) Ditto.
+
+       * get.c: (cmd_get) Use dict_compact_values() instead of a loop.
+       (trim_dictionary) Use dict_delete_vars(), dict_reorder_vars().
+       (rename_variables) Use dict_rename_vars().
+       (mtf_merge_dictionary) Use dict_get_documents(),
+       dict_set_documents(), dict_compact_values().
+
+       * pfm-read.c: (read_variables) Deal with changes to weighting.
+
+       * q2c.c: (dump_parser) Use dict_lookup_var() instead of
+       is_varname() in output code.
+
+       * sfm-read.c: (read_header) Use dict_create(), dict_set_label(),
+       other dictionary functions.
+
+       * title.c: (add_document_line) Use dict_get_documents(),
+       dict_set_documents().
+
+       * vars-atr.c: (discard_variables) Use dict_clear(default_dict),
+       reset default_handle by hand.  dict_clear() will clear vectors so
+       there's no need for that by hand.
+
+       * vfm.c: (close_active_file) Move call to finish_compaction()
+       earlier, so that we can do the compaction as a single step using
+       dict_compact_values().  Use dict_clear_vectors().
+       (finish_compaction) Use dict_delete_var(), dict_compact_values().
+               
+       Some functions don't have replacements:
+
+       * vars-atr.c: (force_create_variable) Removed.  All references
+       updated to dict_create_var() followed by an assertion.
+       (force_dup_variable) Removed.  All references updated to
+       dict_clone_var() followed by an assertion.
+       
+       * weight.c: (update_weighting) Removed.  No longer necessary, so
+       all references removed.
+
+Sat Dec 27 16:43:01 2003  Ben Pfaff  <blp@gnu.org>
+
+       Clean up AGGREGATE.
+       
+       * aggregate.c: Eliminate separation of weighted and unweighted
+       case.  It made the code too obscure and I doubt it was actually
+       faster.  Instead, all code uses the "weighted" code, because
+       that's a generalization of the "unweighted" code.
+       (FWEIGHT) Removed.
+       (FOPTIONS) Ditto.
+       (parse_aggregate_functions) No need to set FWEIGHT.
+       (accumulate_aggregate_info) Get rid of FWEIGHT cases.
+       (dump_aggregate_info) Ditto.
+       (initialize_aggregate_info) No need for special plain_function
+       that gets rid of FWEIGHT option.
+
+       * aggregate.c: Get rid of approximations.
+       (accumulate_aggregate_info) Don't use approx_gt(), approx_lt(),
+       approx_in_range().
+       (aggregate_single_case) Don't use approx_ne().
+
+Sat Dec 27 16:19:36 2003  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c (ascii_line_width): Dead code, removed.
+
+       * postscript.c (ps_line_width): Ditto.
+
+       * q2c.c (xrealloc): Ditto.
+
+       * count.c (internal_cmd_count): Ditto.
+
+       * means.q (validate_dependent_endpoint): Ditto.
+
+       * set.q: (cmd_gset) Ditto.
+
+       * weight.c: [0] (weight_trns_proc) Ditto.
+
+Sat Dec 27 16:18:16 2003  Ben Pfaff  <blp@gnu.org>
+
+       Make the code -Wmissing-prototypes clean.
+
+       * Makefile.am (version.c): Add #include "version.h".
+       
+       * ascii.c: (ascii_open_global) Make static.
+       (ascii_close_page) Ditto.
+       (ascii_font_sizes) Ditto.
+       (ascii_postopen_driver) Ditto.
+       (ascii_close_driver) Ditto.
+       (ascii_option) Ditto.
+       (ascii_open_page) Ditto.
+       (ascii_line_horz) Ditto.
+       (ascii_line_vert) Ditto.
+       (ascii_line_intersection) Ditto.
+       (ascii_box) Ditto.
+       (ascii_polyline_begin) Ditto.
+       (ascii_polyline_point) Ditto.
+       (ascii_polyline_end) Ditto.
+       (ascii_text_set_font_by_name) Ditto.
+       (ascii_text_set_font_by_position) Ditto.
+       (ascii_text_set_font_by_family) Ditto.
+       (ascii_text_get_font_name) Ditto.
+       (ascii_text_get_font_family) Ditto.
+       (ascii_text_set_size) Ditto.
+       (ascii_text_get_size) Ditto.
+       (ascii_text_metrics) Ditto.
+       (ascii_text_draw) Ditto.
+       (ascii_close_page) Ditto.
+
+       * cmdline.h: New header for parse_command_line().  Used where
+       needed.
+
+       * command.c: Move prototypes for cmd_*() functions to command.h.
+
+       * command.h: Prototypes for cmd_*() functions moved here from
+       command.c.
+
+       * crosstabs.q: (gamma_int) Ditto.
+
+       * file-handle.h: Add fh_init_files() prototype.
+       
+       * getline.c: (welcome) Ditto.
+
+       * glob.h: New header for init_glob().  Used where appropriate.
+
+       * hash.c: (comparison_helper) Ditto.
+
+       * html.c: (html_open_global) Ditto.
+       (html_close_global) Ditto.
+       (html_preopen_driver) Ditto.
+       (html_postopen_driver) Ditto.
+       (html_close_driver) Ditto.
+       (html_option) Ditto.
+       (html_open_page) Ditto.
+       (html_close_page) Ditto.
+       (html_submit) Ditto.
+
+       * inpt-pgm.c: (input_program_source_read) Ditto.
+
+       * output.c: (find_defn_value) Ditto.
+       (destroy_list) Ditto.
+
+       * pfm-read.c: (read_int) Ditto.
+
+       * postscript.c: (ps_open_global) Ditto.
+       (ps_close_global) Ditto.
+       (ps_font_sizes) Ditto.
+       (ps_preopen_driver) Ditto.
+       (ps_postopen_driver) Ditto.
+       (ps_close_driver) Ditto.
+       (ps_option) Ditto.
+       (ps_open_page) Ditto.
+       (ps_close_page) Ditto.
+       (ps_line_horz) Ditto.
+       (ps_line_vert) Ditto.
+       (ps_line_intersection) Ditto.
+       (ps_box) Ditto.
+       (ps_polyline_begin) Ditto.
+       (ps_polyline_point) Ditto.
+       (ps_polyline_end) Ditto.
+       (ps_text_set_font_by_name) Ditto.
+       (ps_text_set_font_by_position) Ditto.
+       (ps_text_set_font_family) Ditto.
+       (ps_text_get_font_name) Ditto.
+       (ps_text_get_font_family) Ditto.
+       (ps_text_set_size) Ditto.
+       (ps_text_get_size) Ditto.
+       (ps_text_metrics) Ditto.
+       (ps_text_draw) Ditto.
+
+       * q2c.c: (finish_up) Ditto.
+       (xmalloc) Ditto.
+       (xstrdup) Ditto.
+       (get_buffer) Ditto.
+       (st_lower) Ditto.
+       (st_upper) Ditto.
+       (skip_ws) Ditto.
+       (get_line) Ditto.
+       (add_symbol) Ditto.
+       (find_symbol) Ditto.
+       (lex_get) Ditto.
+       (force_id) Ditto.
+       (force_string) Ditto.
+       (match_id) Ditto.
+       (match_token) Ditto.
+       (skip_token) Ditto.
+       (parse) Ditto.
+       (parse_setting) Ditto.
+       (parse_specifier) Ditto.
+       (parse_specifiers) Ditto.
+       (parse_subcommand) Ditto.
+       (dump_specifier_vars) Ditto.
+       (is_keyword) Ditto.
+       (make_identifier) Ditto.
+       (dump_declarations) Ditto.
+       (dump_specifier_init) Ditto.
+       (dump_vars_init) Ditto.
+       (make_match) Ditto.
+       (dump_specifier_parse) Ditto.
+       (dump_subcommand) Ditto.
+       (dump_parser) Ditto.
+       (dump_header) Ditto.
+       (dump_free) Ditto.
+       (recognize_directive) Ditto.
+
+       * recode.c: (string_to_long) Ditto.
+
+       * repeat.c: (find_DO_REPEAT_substitution) Ditto.
+
+       * repeat.h: New header for perform_DO_REPEAT_substitutions, used
+       where appropriate.
+
+       * sort.c: (sort_stream_read) Ditto.
+       (sort_stream_mode) Ditto.
+       
+Fri Dec 19 23:35:04 2003  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c (binary_search): Fix comparison.
+
+Fri Dec 19 23:27:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * algorithm.c: (binary_search) Fix assertion.
+
+Fri Dec 19 21:31:48 2003  Ben Pfaff  <blp@gnu.org>
+
+       * sysfile-info.c: (compare_vectors_by_name) Rewrite.
+
+Fri Dec 19 21:30:24 2003  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: (compare_case_lists) Rewrite.
+
+Fri Dec 19 16:44:22 2003  Ben Pfaff  <blp@gnu.org>
+
+       * quicksort.c: Removed (not used).
+
+       * quicksort.h: Removed (not used).
+
+       * sort.c: Removed blp_quicksort() prototype.
+
+Fri Dec 19 16:42:13 2003  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: (int_2_compare) Rewrite.
+       (compare_line) Rewrite.
+
+Fri Dec 19 16:38:35 2003  Ben Pfaff  <blp@gnu.org>
+
+       * matrix-data.c (compare_factors) Use lexicographical_compare()
+       algorithm.
+       (compare_doubles) New function.
+       
+       * algorithm.c: (lexicographical_compare) New algorithm.
+
+Fri Dec 19 16:23:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * matrix-data.c (compare_variables_by_mxd_vartype): Rewrite.
+
+Fri Dec 19 15:54:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * expr-prs.c: (cmp_func) Removed.
+       (parse_function) Use binary_search() algorithm.
+       (compare_functions) New function.
+       (init_func_tab) Use sort() algorithm.
+
+       * algorithm.c: (binary_search) New algorithm.
+
+Fri Dec 19 15:50:45 2003  Ben Pfaff  <blp@gnu.org>
+
+       * descript.q: (display) Use sort() algorithm instead of qsort().
+       (compare_func) Removed.
+       (descriptives_compare_variables) New function.
+
+Fri Dec 19 15:08:38 2003  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of AVL trees.  Hashes are more appropriate for everything
+       PSPP does.
+
+       * Makefile.am: (pspp_SOURCES) Remove avl.c, avl.h.
+       
+       * avl.c: Removed.
+
+       * avl.h: Removed.
+
+Fri Dec 19 14:33:31 2003  Ben Pfaff  <blp@gnu.org>
+
+       Much code can be clarified by using C++ STL-like algorithms.  Not
+       all uses of these algorithms are listed below, only the ones where
+       the change to an algorithm was the only change of interest.
+       
+       * Makefile.am: (pspp_SOURCES) Add algorithm.c, algorithm.h.
+       
+       * algorithm.c: New file.
+
+       * algorithm.h: New file.
+
+       * modify-vars.c: (static var forward) Removed.
+       (static var positional) Removed.
+       (compare_variables) Removed.
+       (struct ordering) New.
+       (cmd_modify_vars) Use sort() algorithm.
+       (compare_variables_given_ordering) New function.
+       (rearrange_dict) Use sort() algorithm.
+
+       * sysfile-info.c: (cmd_display) Use sort() algorithm.
+       (cmp_var_by_name) Removed.
+
+Fri Dec 19 14:26:17 2003  Ben Pfaff  <blp@gnu.org>
+
+       Make file handles use a hash table.
+       
+       * file-handle.q: (files) Change to hash table, make static.
+       (cmd_file_handle) Use hash table functions.
+       (fh_get_handle_by_filename) Ditto.
+       (fh_get_handle_by_name) Ditto.
+       (hash_file_handle) New function.
+       (cmp_file_handle) Rewrite.
+       (fh_init_files) Use hash table functions.
+
+Fri Dec 19 14:24:38 2003  Ben Pfaff  <blp@gnu.org>
+
+       Clean up FREQUENCIES.
+       
+       * Makefile.am: (pspp_SOURCES) Remove frequencies.g.
+
+       * frequencies.q: Remove a lot of old #if'd out code at the end.
+       (internal_cmd_frequencies) Use calc() instead of calc_no_weight()
+       or calc_weight().  Initialize percentile_values.
+       (calc) New function based on calc_weight() from frequencies.g.
+       (precalc) Use hash functions.
+       (static var comparison_func) Removed.
+       (static var comparison_param) Removed.
+       (comparison_helper) Removed.
+       (get_freq_comparator) New function.
+       (not_missing) New function.
+       (add_freq) Removed.
+       (postprocess_freq_tab) Use hash table functions, algorithms,
+       get_freq_comparator().  Rewrite.
+       (cleanup_freq_tab) Rephrase.
+       (add_percentile) Clean up spacing.
+       (hash_value_numeric) New function.
+       (hash_value_alpha) New function.
+       (compare_value_numeric_a) Rewrite.
+       (compare_value_alpha_a) Rewrite.
+       (compare_value_numeric_d) Rewrite.
+       (compare_value_alpha_d) Rewrite.
+       (compare_freq_numeric_a) Rewrite.
+       (compare_freq_alpha_a) Rewrite.
+       (compare_freq_numeric_d) Rewrite.
+       (compare_freq_alpha_d) Rewrite.
+       (calc_stats) Clean up mode, percentiles, max.
+       (dump_statistics) Clean up spacing.
+       
+       * frequencies.g: Removed.
+
+       * var.h: (struct freq_tab) Change `data' to hash table.
+
+Fri Dec 19 14:15:46 2003  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.h: Remove declaration of global variable `files',
+       which wasn't used anywhere.
+
+       * postscript.c: (add_encoding) Remove superfluous cast.
+       (line) Ditto.
+
+       * sfm-read.c: [linux] (bswap_int32) Drop ntohl() non-portable
+       version.
+
+       * temporary.c: [0] (display_tree) Removed.
+
+Fri Dec 19 14:13:04 2003  Ben Pfaff  <blp@gnu.org>
+
+       Implement a new random number generator based on the alleged RC4
+       algorithm.
+
+       * expr-evl.c: (expr_evaluate) Use rng_get_double_normal() instead
+       of rand_normal().
+
+       * random.c: [!HAVE_GOOD_RANDOM] (real_rand) Removed.
+       [!HAVE_GOOD_RANDOM] (real_srand) Removed.
+       (macro k) Removed.
+       (static var V[]) Removed.
+       (static var Y) Removed.
+       (static var X2) Removed.
+       (setup_randomize) Removed.
+       (shuffle) Removed.
+       (rand_uniform) Removed.
+       (rand_normal) Removed.
+       (struct rng) New structure.
+       (rng_create) New function.
+       (rng_destroy) New function.
+       (swap_byte) New static function.
+       (rng_seed) New function.
+       (rng_get_bytes) New function.
+       (rng_get_int) New function.
+       (rng_get_unsigned) New function.
+       (rng_get_double) New function.
+       (rng_get_double_normal) New function.
+       (pspp_rng) New function.
+
+       * random.h: Sync up to random.c.
+
+       * sample.c: (struct sample_trns) Make `frac' unsigned and a
+       fraction of UINT_MAX, not 65536.
+       (cmd_sample) Use rng_get_unsigned(), rng_get_double(), UINT_MAX
+       fraction.
+
+       * vfm.c: (open_active_file) No need to call setup_randomize() any
+       longer.
+
+Fri Dec 19 12:05:56 2003  Ben Pfaff  <blp@gnu.org>
+
+       Change dictionary name indexes to use hash tables instead of AVL
+       trees.
+
+       * crosstabs.q: (free_var_dict) Use hash tables.
+       (crs_custom_tables) Ditto.
+       (calc_general) Ditto.
+       (compare_table_entry) Rewrite.
+       (enum_var_values) Reorder parameters.  All references updated.
+       Rewrite.
+
+       * get.c: (rename_variable) Use hash tables.
+       (mtf_merge_dictionary) Ditto.
+
+       * glob.c: (init_glob) Use hash tables.
+       (cmp_variable) Removed.
+
+       * means.q: (mns_custom_tables) Use hash tables.
+
+       * modify-vars.c: (rearrange_dict) Use hash tables.
+
+       * rename-vars.c: (cmd_rename_variables) Use hash tables.
+
+       * sfm-read.c: (read_header) Use hash tables.
+       (read_variables) Ditto.
+
+       * temporary.c: (new_dictionary) Use hash tables.
+       (save_dictionary) Ditto.
+       (restore_dictionary) Ditto.
+
+       * var.h: (struct dictionary) Change AVL tree `var_by_name' into
+       hash table `name_tab'.
+
+       * vars-atr.c: [DEBUGGING] (dump_one_var_node) Removed.
+       [DEBUGGING] (dump_var_tree) Removed.
+       (find_variable) Use hash tables.
+       (find_dict_variable) Ditto.
+       (common_init_stuff) Ditto.
+       (rename_variable) Ditto.
+       (clear_variable) Ditto.  Also, remove debug code.
+       (dup_variable) Use hash tables.
+
+       * vars-prs.c: (fill_all_vars) Use hash tables.
+       (is_dict_varname) Ditto.
+       (parse_dict_variable) Ditto.
+       
+Fri Dec 19 11:46:23 2003  Ben Pfaff  <blp@gnu.org>
+
+       Change value labels to use hash tables instead of AVL trees, and
+       change value labels into an ADT.
+
+       * Makefile.am: (pspp_SOURCES) Add value-labels.c, value-labels.h.
+       
+       * value-labels.c: New file.
+
+       * value-labels.h: New file.
+
+       * apply-dict.c: (cmd_apply_dictionary) Use value label ADT.
+       Get rid of a stupid use of goto.
+
+       * autorecode.c: (compare_alpha_value) Rewrite.
+       (hash_alpha_value) Ditto.
+       (compare_numeric_value) Rewrite.
+       (hash_numeric_value) Ditto.
+
+       * frequencies.q: (dump_full) Use value label ADT.
+
+       * pfm-read.c: (read_value_label) Use value label ADT.
+
+       * pfm-write.c: (write_value_labels) Use value label ADT.
+
+       * sfm-read.c: (read_variables) Use value label ADT.
+       (read_value_labels) Rewrite.
+
+       * sfm-write.c: (write_value_labels) Rewrite.
+
+       * sysfile-info.c: (cmd_sysfile_info) Use value label ADT.
+       (display_variables) Ditto.
+       (describe_variable) Ditto.
+
+       * t-test.q: (print_t_groups) Use value label ADT.
+
+       * temporary.c: (copy_variable) Use value label ADT.
+       (free_dictionary) Ditto.
+
+       * val-labs.c: (verify_val_labs) Use value label ADT.
+       (get_label) Ditto.
+       (debug_print) Ditto.
+       (val_lab_cmp) Removed.
+       (inc_ref_count) Removed.
+       (copy_value_labels) Removed.
+
+       * var.h: (struct value_label) Removed.
+       (struct variable) Change AVL tree `val_lab' into hash table
+       `val_labs'.
+
+       * vars-atr.c: (init_variable) Use value label ADT.
+       (clear_variable) Ditto.
+       (free_value_label) Removed.
+       (free_val_lab) Removed.
+       (get_val_lab) Removed.
+       (compare_variables) New function.
+       (hash_variable) New function.
+
+       * vfm.c: (dump_splits) Use value label ADT.
+
+Fri Dec 19 11:18:11 2003  Ben Pfaff  <blp@gnu.org>
+
+       Add to the hash table interface.
+
+       * hash.c: (hsh_hash_bytes) Add assertion.
+       (hsh_hash_string) Ditto.
+       (hsh_clear) Ditto.
+       (hsh_rehash) Ditto.
+       (hsh_probe) Ditto.
+       (hsh_create) Ditto.  Also make minimum `size'.
+       (hsh_destroy) Rephrase.
+       (sort_nulls_last) Removed.
+       (not_null) New function.
+       (hsh_data) Ditto.
+       (comparison_helper) Ditto.
+       (hsh_sort) Rewritten.
+       (hsh_data_copy) New function.
+       (hsh_sort_copy) Ditto.
+       (hsh_insert) Ditto.
+       (hsh_replace) Ditto.
+       (hsh_hash_double) Ditto.
+       (hsh_delete) Fix stupid bug.
+       
+Thu Dec 18 12:27:03 WAST 2003 John Darrington <john@darrington.wattle.id.au>
+        * added a calculation of the mode to FREQUENCIES
+
+Wed Dec 17 12:53:01 WAST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * moved (un)defs of DEBUGGING to config.h
+
+Mon Dec 15 21:35:59 2003  Ben Pfaff  <blp@gnu.org>
+
+       * groff-font.c: (add_kern) Fix indentation.
+       (add_kern) Use & instead of % to take power-of-2 modulus.
+       (font_get_kern_adjust) Likewise.
+
+Fri Dec 12 23:54:37 2003  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.c: (recode) Replace stupid use of memcpy() by
+       memberwise copy.
+       (hash_alpha_value) Use hsh_hash_bytes().  Get rid of nasty casts.
+       (hash_numeric_value) Ditto.
+       (autorecode_proc_func) pool_strdup() was wrong here because the
+       source string was not null-terminated.  Use new pool_strndup()
+       instead.
+
+       * crosstabs.q: (enum_var_values) Remove superfluous and bizarre
+       use of hsh_iterator_init().
+
+       * data-in.c: (parse_N) Initialize i->v->f.
+
+       * flip.c: (cmd_flip) Use memmove(), not memcpy(), to copy
+       overlapping arrays.
+
+       * groff-font.c: Use power-of-2 hash table sizes, not prime.
+       (groff_read_font) Don't call hsh_next_prime().  Don't call
+       fclose(NULL).
+       (static var hash) Remove `size_p', `max_used' members.
+       (font_char_name_to_index) Don't call hsh_next_prime().  Use
+       hsh_hash_string() instead of hashpjw(), & instead of %.
+       (default_font) Don't call hsh_next_prime().
+
+       * pool.c: (pool_strndup) New function.
+       (pool_strdup) Reimplement in terms of pool_strndup.
+
+       * postscript.c: (hash_font_entry) Use hsh_hash_string().  Get rid
+       of nasty casts.
+       (hash_ps_encoding) Use hsh_hash_string().
+       (hash_ps_combo) Use hsh_hash_string(), hsh_hash_int().
+       (hash_filename2font) Use hsh_hash_string().
+
+       * som.c: Add #include <stdlib.h>.
+
+       * tab.c: (tab_destroy) Don't set t->container after freeing `t'
+       (by destroying its pool).
+       
+Fri Dec 12 23:18:59 2003  Ben Pfaff  <blp@gnu.org>
+
+       Miscellaneous hash table code cleanup:
+       
+       * hash.h: (struct hsh_table) Moved into hash.c.
+       (hsh_count) Ditto, and transformed into function.
+       (hsh_compare_func) New typedef, used for defining otherwise-long
+       function types here and in hash.c
+       (hsh_hash_func) Ditto.
+       (hsh_free_func) Ditto.
+       
+       * hash.c: (struct hsh_table) Renamed `n' to `used', `m' to `size',
+       `table' to `entries'.  Removed `mp'.  All references updated.
+       (hsh_clear) Don't shrink entries array; if the hash was this big
+       once, it probably will be again.
+       (hsh_rehash) Made static.
+       (force_hsh_insert) Renamed hsh_force_insert.
+       (force_hsh_find) Renamed hsh_force_find.
+
+       Made hash table sizes powers of 2, because that's fine with any
+       reasonable hash function and because taking a power-of-2 modulus
+       is faster than any other:
+       
+       (hsh_prime_tab) Removed;
+       (hsh_next_prime) Ditto.
+       (next_power_of_2) New function.
+       (hsh_create) Use next_power_of_2.
+       (hsh_rehash) Use & instead of %.
+
+       Cleaned up hsh_sort:
+       
+       (internal_comparison_fn) Removed.
+       (sort_nulls_last) New function.
+       (hsh_sort) Removed second parameter, switched to using the new
+       quicksort() function from quicksort.h to avoid using nasty need
+       for static variables with qsort().  All references updated.
+
+       Changed the hash functions offered, because there are better hash
+       functions than the ones we had, and cleaned up the names to boot:
+       
+       * hash.c: (hashpjw_d) Removed.
+       (hashpjw) Ditto.
+       (hsh_hash_bytes) New function.
+       (hsh_hash_string) New function.
+       (hsh_hash_int) New function.
+
+       Improved the hash table iteration interface:
+       
+       * hash.h: (hsh_iterator_init) Removed.
+       (struct hsh_iterator) Removed `init' member, change `next' to
+       size_t.
+
+       * hash.c: (hsh_foreach) Removed.  All references updated to use
+       hsh_first/hsh_next instead.
+       (hsh_first) New function.  Notably, unlike hsh_foreach() it does
+       not treat a null pointer as an empty hash table.
+       (hsh_next) New function.
+
+       Made deletion possible, though slow:
+
+       * hash.c: (locate_matching_entry) New function.
+       (hsh_find) Use locate_matching_entry().
+       (hsh_delete) New function also using locate_matching_entry().
+       (hsh_force_delete) New function.
+
+Fri Dec 12 23:16:10 2003  Ben Pfaff  <blp@gnu.org>
+
+       * quicksort.c: New file implementing a sort routine with a
+       interface better than qsort() because it passes a user-provided
+       parameter to the sort routine.
+
+       * Makefile.am: Add quicksort.c, quicksort.h.
+
+Fri Dec 12 13:31:58 2003  Ben Pfaff  <blp@gnu.org>
+
+       * All source files: Get rid of nasty special cases for Checker,
+       which is pretty obsolete now.
+
+Thu Dec 11 21:38:24 WST 2003 John Darrington <john@darrington.wattle.id.au>
+
+       * Fixed a bug apparent when using the FREQUENCIES command with the
+       html driver.  The html driver was incorrectly trying to display 
+       empty cells.
+
+Sun Jan  2 21:40:13 2000  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Reorganized.  Put locale dir in version.c instead
+       of passing it to each compile command.  Only put local gmp libs in
+       LD_ADD if not installed on system.  Remove `boast' target.
+
+       * All source files: struct and union typedefs eliminated.
+       `sizeof type' replaced by `sizeof object' where practical.  Moved
+       `unused' qualifiers from start to end of declarations for gcc
+       2.7.2 compatibility.  Change `while (1)' to `for (;;)'.  Made
+       assertions on pointers strictly compliant.  Removed _ prefixes on
+       some function parameter names.
+
+       * alloc.c: New source file, containing these external linkage
+       functions removed from common.c: xmalloc, xcalloc, xrealloc,
+       xstrdup.
+
+       * arena.c: Removed.
+       
+       * arena.h: Removed.
+
+       * ascii.c: Migrated from arenas to pools.
+       (struct ascii_driver_ext) ops[], box[], fonts[] changed from
+       c_string to len_string.  All references changed.
+       (ascii_option) Signature changed to comply to new output.c
+       interface.
+       (count_fancy_chars) Removed.
+       (delineate) Removed support for rich text.
+       (ascii_text_metrics) Ditto.
+       (text_draw) Ditto.
+       (output_shorts) Change `box', `off', `on' from c_string to
+       len_string.  Change `remaining' from int to size_t.
+       (ascii_close_page) Make page numbering less haphazard.
+
+       * autorecode.c: Migrate from arenas to pools.
+
+       * avl.c: Migrate from arenas to pools.  Synch from libavl 1.4.0.
+
+       * bitvector.h: New file containing these macros from misc.h:
+       SET_BIT, CLEAR_BIT, SET_BIT_TO, TEST_BIT, BIT_INDEX.
+
+       * command.c: (struct command) cmd1, cmd2, cmd3 members changed to
+       word[3].  ncmd removed.
+       (var empty_string) Removed.
+       (var cmd_table) Declaration updated.
+       (var cmdtab) Removed.
+       (cmp_command) Removed.
+       (split_words) Rewritten to use strtok_r().
+       (init_cmd_parser) Renamed cmd_init().  Rewritten.
+       (find_command) Removed.
+       (FILE_TYPE_okay) Rewritten.
+       (cmd_parse) Rewritten.  Semantics of the return value of command
+       handlers has changed: they must now return one of the new CMD_*
+       enumerals, rather than a magic value.  This meant that all
+       commands had to be modified, and they were.
+       (figure_out_command) New function.
+
+       * command.def: Add CORRELATIONS, PEARSON CORRELATIONS.  Add
+       #defines for INIT, INPU, etc.
+
+       * command.h: New CMD_* enum series.
+       (cur_proc) Make const char *, not char *.
+       (cmd_init) Prototype.
+       (cmd_parse) Ditto.
+
+       * common.c: Removed.
+
+       * common.h: Removed.
+
+       * correlations.q: New file.
+
+       * crosstabs.q: Migrate from arenas to pools.  Migrate to new-style
+       q2c.
+       (custom_tables) Renamed crs_custom_tables().
+       (custom_variables) Renamed crs_custom_variables().
+       (calc_integer) Add in some `const' qualifiers.
+       (table_value_missing) Change from a_string to len_string.
+       (float_M_suffix) Change from a_string to len_string.
+
+       * data-in.c: Rewritten.  All references to
+       parse_string_as_format() changed to data_in().
+
+       * data-in.h: New file.
+
+       * data-list.c: Change DLS_* from #define's to enums.  Move from
+       rpd_msg() to tmsg().
+       (RPD_ERR) New #define.
+       (do_reading) Change dfm_push_cust() to dfm_push(), pop_cust() to
+       dfm_pop().
+       (read_from_data_list_fixed) Change from old
+       parse_string_as_format() to new data_in().
+       (read_from_data_list_free) Ditto.
+       (read_from_data_list_list) Ditto.
+       (cmd_repeating_data) Modify approach to checking for end of
+       command.
+       (rpd_msg) Removed.
+       (rpd_parse_record) Change from old parse_string_as_format() to new
+       data_in().  Change from old convert_format_to_string() to new
+       data_out().
+       (read_one_set_of_repetitions) Change dfm_push_cust() to
+       dfm_push(), pop_cust() to dfm_pop().
+
+       * data-out.c: Rewritten.  All references to
+       convert_format_to_string() changed to data_out().
+
+       * descript.q: Migrate to new q2c.
+       (cmd_descriptives) Removed.
+       (internal_cmd_descriptives) Renamed cmd_descriptives ().
+       (custom_variables) Renamed dsc_custom_variables().
+
+       * dfm.c: (struct dfm_fhuser_ext) `ln' removed.  All references
+       removed.
+       (open_file_r) Initialize h->where.line_number.  Migrate to new
+       struct string.
+       (open_file_w) Initialize h->where.line_number.
+       (read_record) Change from ext->ln to h->where.line_number.
+       Migrate to struct string.
+       (dfm_put_record) Rephrased.
+       (dfm_push_cust) Renamed dfm_push(), rewritten.
+       (dfm_pop) New function.
+
+       * error.c: All references updated.
+       (glob var error_count) Renamed err_err_count.
+       (glob var warning_count) Renamed err_warning_count.
+       (glob var error_already_flagged) Renamed err_already_flagged.
+       (glob var verbosity) Renamed err_verbosity.
+       (glob var cust_fn) Removed.
+       (glob var cust_ln) Removed.
+       (static var file_loc) New.
+       (static var nfile_loc) New.
+       (static var mfile_loc) New.
+       (tmsg) New function.
+       (push_cust) Removed.
+       (pop_cust) Removed.
+       (msg) Rewritten.
+       (static var terminating) Removed.
+       (failure) Renamed err_failure().
+       (hcf) Renamed err_hcf().
+       (err_push_file_locator) New function.
+       (err_pop_file_locator) New function.
+       (err_location) New function.
+       (check_error_count) Renamed err_check_count().
+       (vmsg) Renamed err_vmsg().  Interface changed.
+       (verbose_msg) Removed.
+       (err_cond_fail) New function.
+       (error_break) Renamed err_break().
+
+       * error.h: All references updated.
+       (enum MSG_CLASS_COUNT) Renamed ERR_CLASS_COUNT.
+       (enum ERR_CLASS_MASK, ERR_VERBOSITY_SHIFT, ERR_VERBOSITY_MASK)
+       New.
+       (struct file_locator) New.
+       (struct error) New.
+       (macro verbose_msg) Removed.
+       (macro cond_fail) Removed.
+
+       * expr-opt.c: (evaluate_tree) sizeof(char) == 1.
+
+       * expr-prs.c: Reorganized.  All references updated.
+       (exprtypename) Renamed expr_type_name().
+       (typename) Renamed type_name().
+       (free_expression) Renamed expr_free().
+       (parse_expression) Renamed expr_parse().  Uses new type_check()
+       function.
+       (init_functab) Renamed init_func_tab().
+       (type_check) New function.
+       (parse_or) Rewritten to use new allocate_nonterminal() and
+       append_nonterminal_arg() functions.
+       (parse_and) Ditto.
+       (parse_not) Ditto.
+       (parse_rel) Ditto.  Also simplified logic.
+       (parse_add) Ditto.
+       (parse_mul) Ditto.
+       (parse_neg) Ditto.
+       (parse_exp) Ditto.
+       (SYSMIS_func) Ditto.
+       (VALUE_func) Rephrased.
+       (CONCAT_func) Fix memory leak by replacing free by free_node on
+       lossage.
+       (generic_str_func) Ditto.
+       (parse_function) Ditto.  Also rephrasings.  Uses bsearch() to find
+       function.
+       (allocate_nonterminal) New function.
+       (append_nonterminal_arg) New function.
+       (static func_tab[]) Now at file level.
+       (cmp_func) Moved.
+       (init_func_tab) Moved.  Now just uses qsort() to sort func_tab[].
+
+       * expr.h: (enum series OP_*) Moved to exprP.h.
+       (OP_* defines) Ditto.
+       (struct op_desc) Ditto.
+       (global ops[]) Ditto.
+       (struct num_con_node) Ditto.
+       (struct str_con_node) Ditto.
+       (struct var_node) Ditto.
+       (struct lag_node) Ditto.
+       (struct casenum_node) Ditto.
+       (struct nonterm_node) Ditto.
+       (union any_node) Members renamed.
+       (struct sys_node) Removed.
+       (struct val_node) Removed.
+       (operator typedef) Removed.
+       (typedef exprtype) Removed.
+       (enum series EX_*) Moved to exprP.h.
+       (struct expression) Ditto.  Also renamed a lot of the members.
+       (PXP_* defines) Changed to enums.
+       (free_node prototype) Moved to exprP.h.
+
+       * file-handle.h: (struct file_handle) New member `where'.
+
+       * file-handle.q: Migrated to new q2c format.
+       (prepend_current_directory) Removed (dead code).
+       (cmd_file_handle) Incorporated all of internal_cmd_file_handle().
+       (fh_get_handle_by_filename) Removed dead code.
+       Set new `where' member.
+
+       * file-type.c: (file_type_source_read) References to
+       parse_string_as_format() changed to data_in().
+       dfm_push_cust()/pop_cust() changed to dfm_push()/dfm_pop().
+
+       * filename.c: All references updated.
+       (init_filename) Renamed fn_init().
+       (expand_line) Removed.
+       (macro EXPAND_LINE) Removed.
+       (interp_vars) Renamed fn_interp_vars().  Now uses st_*() instead
+       of custom functions.
+       (gnu_getcwd) Renamed fn_get_cwd(), rewritten.
+       (tilde_expand) Renamed fn_tilde_expand(), uses ds_*().
+       (normalize_filename) Renamed fn_normalize().
+       (search_path) Renamed fn_search_path(), rewritten.
+       (prepend_dir) Renamed fn_prepend_dir().
+       (blp_getenv) Renamed fn_getenv().
+       (blp_dirname) Renamed fn_dirname().
+       (fn_basename) New function, not used.
+       (absolute_filename_p) Renamed fn_absolute_p().
+       (is_special_filename) Renamed fn_special_p().
+       (file_exists) Renamed fn_exists_p().
+       (readlink_malloc) Renamed fn_readlink().
+       (getenv_default) Renamed fn_getenv_default().
+       (open_file) Renamed fn_open().
+       (close_file) Renamed fn_close().
+       (open_file_ext) Renamed fn_open_ext().
+       (close_file_ext) Renamed fn_close_ext().
+
+       * font.h: Migrate from arenas to pools.
+
+       * format.c: (parse_format_specifier_name) Deal with ds_* strings.
+
+       * frequencies.g: Migrate from arenas to pools.
+
+       * frequencies.q: Migrate to new q2c version.  Migrate from arenas
+       to pools.
+
+       * getline.c: All references updated.
+       (global getl_buf) Changed from char * to struct string.
+       (static getl_include_path) Ditto.
+       (global getl_buf_len) Removed.
+       (global getl_buf_size) Removed.
+       (getl_include_path) Deal with new getl_buf, getl_include_path.
+       (getl_uninitialize) New function.
+       (getl_get_current_directory) Rewritten.
+       (getl_clear_include_path) Rewritten.
+       (getl_add_include_dir) Rewritten.
+       (getl_add_file) Assertion fixed.
+       (getl_add_virtual_file) Change initial value of `remaining_loops'
+       from 2 to 1.
+       (welcome) Rewritten.
+       (handle_line_buffer) Make static.  Change logic to make
+       getl_add_virtual_file() change sensible.  Use ds_*() strings.
+       (getl_read_line) Use ds_*() strings.  Implement SET ECHO.
+       (getl_close_file) Moved.
+       (getl_location) New function.
+
+       * getline.h: All references updated.
+       (macro curln) Removed.
+       (macro curfn) Removed.
+       (macro am_interactive) Renamed getl_am_interactive.
+       (macro am_reading_script) Renamed getl_reading_script.
+
+       * glob.c: (global fmt_parse_ignore_error) Removed.
+       (init_glob) Use locale_dir not LOCALEDIR.  Use feholdexcept() on
+       systems that support it (C99).  Turn off SET ECHO by default.  No
+       necessary julcal initialization anymore.
+
+       * groff-font.c: Migrate from arenas to pools.
+       (groff_read_font) Use err_push_file_locator().
+       (groff_read_DESC) Ditto.
+       (font_msg) Use tmsg().
+
+       * hash.c: (hsh_sort) Fix debug code.
+       [GLOBAL_DEBUGGING] Include stdio.h.
+
+       * hash.h: (macro force_hsh_insert) Rephrase.
+
+       * heap.c: Rewritten.
+       
+       * heap.h: Rewritten.
+
+       * html.c: (html_option) Change from outp_value to struct string.
+       (postopen) Change from curfn to getl_location().
+       (escape_string) Remove rich-text code.  Signature changed.
+       (output_tab_table) Switch from a_string to struct len_string.
+       Remove rich text support.
+
+       * lexer.c: All references updated.  Largely rewritten.  Major
+       changes listed below.  Removed tagged quote support.  Adapted to
+       struct string tokstr.
+       (global tokstr) Changed to struct string.
+       (global tokstr_size) Removed.
+       (global tokstr_len) Removed.
+       (global tokid) New.
+       (global tokint) Removed.
+       (global toklongstr) Removed.
+       (C* defines) Removed.
+       (static tbl[]) Removed.
+       (static id[]) Removed.
+       (static une[]) Removed.
+       (discard_line) Renamed lex_discard_line().
+       (get_entire_line) Renamed lex_entire_line().
+       (get_rest_of_line) Renamed lex_rest_of_line().
+       (get_dotted_rest_of_line) Merged into lex_rest_of_line().
+       (make_hexit) Removed.
+       (syntax_error) Renamed lex_error().  Return value removed.
+       (get_token_representation) Renamed lex_token_representation().
+       (putback) Renamed lex_put_back().
+       (putfwd) Renamed lex_put_forward().
+       (convert_negative_to_dash) Renamed lex_negative_to_dash().
+       (set_prog) Renamed lex_set_prog().
+       (init_lex) Renamed lex_init().
+       (reset_eof) Renamed lex_reset_eof().
+       (lookahead) Renamed lex_look_ahead().
+       (check_id) Rewritten.
+       (yylex) Renamed lex_get(), rewritten.
+       (lex_end_of_command) New function.  Many commands were rephrased
+       using this.
+       (lex_integer_p) New function.  Replaces compare of tokint against
+       NOT_LONG.
+       (lex_integer) New function.  Replaces tokint.
+       (match_tok) Renamed lex_match().
+       (match_id) Renamed lex_match_id().
+       (match_int) Renamed lex_match_int().
+       (force_match_id) Renamed lex_force_match_id(), added return value.
+       (force_match) Renamed lex_force_match(), added return value.
+       (force_string) Renamed lex_force_string(), added return value.
+       (force_int) Renamed lex_force_int(), added return value.
+       (lex_id_match_len) New function.
+       (id_match) Renamed lex_id_match(), rewritten.
+       (get_line) Renamed lex_get_line().
+       (preprocess_line) Renamed lex_preprocess_line().
+       (tokname) Renamed lex_token_name().
+       (bin_value_func) Removed.
+       (oct_value_func) Removed.
+       (hex_value_func) Removed.
+       (unexpected_eof) New function.
+       (convert_numeric_string_to_char_string) New function.
+       (parse_string) Rewritten, signature changed.
+       (add_tokstr_char) Removed.
+       (add_tokstr_unsigned) Removed.
+       (add_tokstr_string) Removed.
+       (parse_tagged_quote) Removed.
+       (skip_comment) Renamed lex_skip_comment().
+
+       * lexer.h: All references updated.
+       (macro is_id1) Renamed CHAR_IS_ID1.
+       (macro is_idn) Renamed CHAR_IS_IDN.
+       (token names ID, NUM, STRING, STOP, ... WITH, EXP) Renamed with
+       prefix T_: T_ID, T_NUM, T_STRING, T_STOP, ... T_WITH, T_EXP.
+       (macro get_token) Removed.
+       (macro id_match) Removed.
+       (macro force_match_id) Removed.
+       (macro force_match) Removed.
+       (macro force_string) Removed.
+       (macro force_int) Removed.
+       (macro force_num) Removed.
+       (macro force_id) Removed.
+
+       * lexerP.h: Removed.
+
+       * list.q: Migrated to new q2c format.
+       (write_line) Deal with struct len_string.
+       (write_varname) Ditto.
+       (write_fallback_headers) Ditto.
+
+       * magic.c: New file, incorporating the following global variables
+       previously in other files: endian, second_lowest_value.  And both
+       of those are conditional on #define's.
+
+       * magic.h: New file, incorporating the following global variable
+       declarations: endian, second_lowest_value, and the following macro
+       declarations: NOT_DOUBLE, NOT_LONG, NOT_INT.
+
+       * main.c: Added declarations of pgmname, finished, curdate,
+       start_interactive.
+       (main) Call new parse_script() function.
+       (parse_script) New function.
+       (execute_command) New function.
+       (dump_token) Removed.
+       (handle_error) New function.
+
+       * matrix.c: New file.
+
+       * matrix.h: New file.
+
+       * matrix-data.c: Migrated from arenas to pools.
+       (mget_token) Change from parse_string_as_format() to data_in().
+
+       * means.q: Migrate to new q2c.
+       (custom_tables) Renamed mns_custom_tables().
+       (custom_crossbreak) Renamed mns_custom_crossbreak().
+       (custom_variables) Renamed mns_custom_variables().
+
+       * mis-val.c: (static var width) Changed from `int' to `size_t'.
+       (parse_varnames) Prototype.
+       (parse_numeric) Rephrasings.
+       (parse_alpha) Adapt to new struct string tokstr.
+
+       * misc.c: (intlog10) Rewritten.
+       (spacing) Removed.
+       (ansi_rand) Renamed real_rand(), moved into random.c.
+       (ansi_srand) Renamed real_srand(), moved into random.c.
+       (setup_randomize) Moved to random.c.
+       (rand_uniform) Ditto.
+       (rand_normal) Ditto.
+       (rand_simple) Ditto.
+       (get_config_line) Removed.
+       (reverse) Removed (dead code).
+
+       * misc.h: (macro SET_BIT) Moved to bitvector.h.
+       (macro CLEAR_BIT) Ditto.
+       (macro TEST_BIT) Ditto.
+       (macro SET_BIT_TO) Ditto.
+       (macro BIT_INDEX) Ditto.
+
+       * output.c: (outp_read_devices) Move to err_push_file_locator()
+       from push_cust().  Use struct string.
+       (expand_op_tokstr) Removed.
+       (static var op_tokstr) Changed to struct string.
+       (static var op_tokstr_size) Removed.
+       (tokener) Rephrasings.  Use struct string.
+       (parse_options) Use struct string.
+       (destroy_driver) Fix assertion.
+       (outp_get_paper_size) Move to err_push_file_locator().
+       [0] Removed dead code.
+       (outp_string_width) Move to len_string.
+
+       * output.h: Comment fixes.
+       (TAG_* enum series) Removed.
+       (struct outp_value) Removed.
+       (enum OUTP_T_FANCY) Removed.
+       (struct outp_text) `s' changed from a_string to len_string.
+       (struct outp_class) `option' change arg 3 from outp_value to
+       struct string.
+
+       * pfm-read.c: (corrupt_msg) Rewritten.
+
+       * pfm-write.c: (bufwrite) Fix assertion.
+
+       * pool.c: New file, reference version.
+
+       * pool.h: New file, reference version.
+
+       * postscript.c: (ps_font_sizes) Fix assertion.
+       (ps_option) Change arg 3 from outp_value to struct string.
+       Adapt to struct string.
+       (macro output_line) Removed.
+       (macro add_string) Removed.
+       (output_encodings) Adapted to struct string.  Moved to
+       err_push_file_locator().
+       (find_encoding_file) Fix assertion.
+       (read_ps_encodings) Move to err_push_file_locator().
+       (postopen) Use getl_location() instead of curfn.
+       (out_text_plain) Move to len_string.
+       (text) Ditto.  Remove rich text support.
+
+       * print.c: (cmd_print) Remove now-unneeded resource cleanup code.
+       (cmd_print_eject) Ditto.
+       (cmd_write) Ditto.
+       (internal_cmd_print) Now cleans up after itself.  Uses
+       fh_parse_file_handle() now.
+       (cmd_print_space) Use PXP_NUMERIC to type-check.
+
+       * q2c.c: Overhauled.  Removed _("") i18n support.  All references
+       updated.  All output functions updated to handle structures rather
+       than local or static variables.  Adapt to new PSPP lex_*()
+       functions.
+       (macro _) Removed.
+       (macro N_) Removed.
+       (macro MAX_N_SBC) Removed.
+       (global bare) Removed.
+       (enum STRING) Renamed T_STRING.
+       (enum ID) Renamed T_ID.
+       (get_buffer) Buffer size increased.
+       (strlower) Renamed st_lower(), rephrased.
+       (strupper) Renamed st_upper(), rephrased.
+       (skip_ws) New function.
+       (get_line) Don't special-case any types of lines (like those
+       beginning with ! or $, for instance).
+       (get_token) Renamed lex_get().  Rephrased.
+       (static var `prefix') New.
+       (parse) New function.
+       (parse_setting) Minor rephrasing.
+       (dump_specifier_vars) Ditto.
+       (make_identifier) Put null terminator on identifier, duh.
+       (dump_vars) Renamed dump_declarations().  Never indent.  Never
+       static.  Output changed entirely.
+       (dump_specifier_init) Rephrase.
+       (dump_vars_init) No index variable needed.  Other modifications.
+       (dump_parser) Don't parse command name.  Do dump functions instead
+       of just code fragments.
+       (dump_free) Dump function instead of code fragment.
+       (recognize_directive) New function.
+       (main) Use recognize_directive().  Don't rely on magic $ line
+       beginning: instead, parse comments.  Update list of headers.
+
+       * random.c: New file, containing the following functions:
+       real_rand(), real_srand(), setup_randomize, shuffle, rand_uniform,
+       rand_normal, rand_simple.
+
+       * random.h: New file.
+
+       * recode.c: (cmd_recode) Merge internal_cmd_recode() into this
+       function.  `max_src_width', `max_dst_width' changed to size_t.
+       (internal_cmd_recode) Removed.
+       (parse_dest_spec) Merge similar cases.
+       (parse_src_spec) Add assertion.
+
+       * repeat.c: (recognize_keyword) New function.
+       (internal_cmd_do_repeat) Parse and handle PRINT keyword on END
+       REPEAT.  Improve recognition of END REPEAT (use
+       recognize_keyword()).  Move from curfn to getl_location().  Use
+       struct string.
+               
+       (perform_DO_REPEAT_substitutions) Adapt to struct string.
+
+       * set.q: Adapt to new q2c.
+       (cmd_set) Range-check some values better.
+       (custom_blanks) Renamed stc_custom_blanks().
+       (custom_length) Renamed stc_custom_length().
+       (custom_results) Renamed stc_custom_results().
+       (custom_seed) Renamed stc_custom_seed().
+       (custom_width) Renamed stc_custom_width().
+       (custom_format) Renamed stc_custom_format().
+       (custom_journal) Renamed stc_custom_journal().
+       (custom_color) Renamed stc_custom_color().
+       (custom_listing) Renamed stc_custom_listing().
+       (custom_disk) Renamed stc_custom_disk().
+       (custom_log) Renamed stc_custom_log().
+       (custom_rcolor) Renamed stc_custom_rcolor().
+       (custom_viewlength) Renamed stc_custom_viewlength().
+       (custom_workdev) Renamed stc_custom_workdev().
+
+       * settings.h: Not necessary to include format.h any longer.
+
+       * sfm-read.h: (macro bswap_int32) Moved here from sfmP.h.
+       (corrupt_msg) Rewritten.
+
+       * sort.c: Adapt to rewritten heap ADT.
+
+       * str.c: (aa_strcpy) Removed.
+       (ab_strcpy) Removed.
+       (ac_strcpy) Removed.
+       (ba_strcpy) Removed.
+       (bb_strcpy) Removed.
+       (ca_strcpy) Removed.
+       (aa_strdup) Removed.
+       (aa_strdupcpy) Removed.
+       (ba_strdup) Removed.
+       (sa_strdup) Removed.
+       (memrev) Renamed mm_reverse().
+       (memrmem) Renamed mm_find_reverse().
+       (cmp_str) Renamed st_compare_pad().
+       (strmaxcpy) Removed.
+       (strbarepadcpy) Renamed st_bare_pad_copy(), signature changed.
+       (strbarepadlencpy) Renamed st_bare_pad_len_copy(), signature
+       changed.
+       (strpadcpy) Renamed st_pad_copy(), signature changed.
+       (blpstrset) Removed.
+       (ds_create) New function.
+       (ds_init) New function.
+       (ds_replace) New function.
+       (ds_destroy) New function.
+       (ds_clear) New function.
+       (ds_extend) New function.
+       (ds_shrink) New function.
+       (ds_truncate) New function.
+       (ds_length) New function.
+       (ds_size) New function.
+       (ds_value) New function.
+       (ds_end) New function.
+       (ds_concat) New function.
+       (ds_concat_buffer) New function.
+       (ds_printf) New function.
+       (ds_putchar) New function.
+       (ds_getline) New function.
+       (ds_get_config_line) New function derived from the old
+       misc.c:get_config_line().
+       (ls_create) New function.
+       (ls_create_buffer) New function.
+       (ls_init) New function.
+       (ls_shallow_copy) New function.
+       (ls_destroy) New function.
+       (ls_null) New function.
+       (ls_null_p) New function.
+       (ls_empty_p) New function.
+       (ls_length) New function.
+       (ls_value) New function.
+       (ls_end) New function.
+
+       * str.h: Reformatted.
+       (struct a_string) Removed.
+       (struct b_string) Removed.
+       (struct c_string) Removed.
+       (struct len_string) New.
+       (struct string) New.
+       (macro as_streq) Removed.
+       (macro bs_streq) Removed.
+       (macro cs_streq) Removed.
+       (macro sa_streq) Removed.
+       (macro sb_streq) Removed.
+       [__GNUC__] (inline function ds_putchar) New function.
+       [__GNUC__] (inline function ds_length) New function.
+       [__GNUC__] (inline function ds_value) New function.
+       [__GNUC__] (inline function ds_end) New function.
+
+       * sysfile-info.c: (cmd_sysfile_info) Rephrased.
+       (display_vectors) Fix missing i18n.
+
+       * t-test.q: Migrate to new q2c.
+
+       * tab.c: Migrate from arenas to pools.
+       (tab_create) Use struct len_string.
+       (tab_realloc) Ditto.
+       (text_format) Ditto.
+       (tab_joint_text) Ditto.
+       (tab_natural_width) Remove rich text support.
+       (tab_natural_height) Ditto.
+       (tab_output_text) Handle TAT_FIX.
+       (tab_raw) Change arg from a_string to len_string.
+       (tabi_driver) Fix assertion.  Use struct len_string.
+       (render_strip) Use struct len_string.  Remove rich text support.
+       Add `const' qualifiers.
+
+       * tab.h: (enum TAB_RICH) Remove.
+       (enums TAB_COL_NONE, TAB_COL_DONE) New.  Where appropriate,
+       SOM_COL_* updated to read TAB_COL_*.
+       (struct tab_table) Change arena to pool.  Change a_string to
+       len_string.
+
+       * temporary.c: (restore_dictionary) Rewrite Checker code.
+
+       * var.h: (macros MAX_SHORT_STRING, MIN_LONG_STRING, SYSMIS,
+       LOWEST, HIGHEST) Moved here from common.h.
+       (typedef any_trns) Removed.  All references changed to `struct
+       trns_header'.
+
+       * vars-atr.c: (force_create_variable) Fix assertion.
+       (force_dup_variable) Fix assertion.
+       
+Thu Jun  3 18:40:42 1999  Ben Pfaff  <blp@gnu.org>
+
+       Using alphanumeric variables in functions under AGGREGATE
+       segfaulted.  Fixed.  Thanks to Dr. Dirk Melcher
+       <BZN-mdksh@t-online.de> for reporting this bug.
+       
+       * aggregate.c: (parse_aggregate_functions) When setting the
+       FSTRING bit, also allocate memory for the `string' member of
+       agr_next.
+       (free_aggregate_functions) Free iter->string.  Don't use the
+       non-function bits when indexing the array of functions.
+       [DEBUGGING] (debug_print) Don't use the non-function bits when
+       indexing the array of functions.        
+
+Sun May 30 00:00:54 1999  Ben Pfaff  <blp@gnu.org>
+
+       Under certain circumstances, the final case would be omitted from
+       the results of an AGGREGATE operation.  Fixed.  Thanks to Dr. Dirk
+       Melcher <BZN-mdksh@t-online.de> for reporting this bug.
+       
+       * aggregate.c (agr_00x_end_func): Increment number of cases in
+       sink before writing case.  For streams that keep track of how many
+       cases there are based on this value, this means that the last case
+       will be read in on the next stream read.
+
+Sat May 29 22:03:31 1999  Ben Pfaff  <blp@gnu.org>
+
+       Undefined behavior was invoked by referencing a freed pointer.
+       
+       * vfm.c (memory_stream_write): Free pointer *after* checking for
+       non-null status.
+
+Sat May 29 22:02:22 1999  Ben Pfaff  <blp@gnu.org>
+
+       A wrong record size was displayed when paging the active file to
+       disk.
+       
+       * vfm.c: (memory_stream_write) Fix off-by-one error.
+
+Sat May 29 21:50:26 1999  Ben Pfaff  <blp@gnu.org>
+
+       Not having enough temporary space for sorting caused a core dump.
+       Fixed.
+       
+       * sort.c: (allocate_cases) Initialize i.
+
+Sat May 29 21:40:54 1999  Ben Pfaff  <blp@gnu.org>
+
+       Syntax errors in function descriptions on AGGREGATE caused core
+       dumps.  Fixed.
+       
+       * aggregate.c (cmd_aggregate): Don't free agr_dict after calling
+       free_aggregate_functions(), since that function already frees
+       agr_dict.
+       
+Sat May 29 21:06:10 1999  Ben Pfaff  <blp@gnu.org>
+
+       A null pointer was dereferenced, causing a core dump, when
+       PERCENTILES was specified on FREQUENCIES.  This fixes the problem,
+       but PSPP still doesn't calculate percentiles.  Thanks to Regnor
+       Jernsletten <rjernsle@eunet.no> for reporting this problem.
+       
+       * arena.c: (arena_malloc) If the arena hasn't been initialized
+       already, initialize it.
+
+Sat May 29 20:47:29 1999  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.cygwin: New file supplied by Hankin <hankin@dunno.com>
+       for compilation with Cygnus Windows B20.  Not used by other
+       systems.
+
+Sat May 29 20:36:04 1999  Ben Pfaff  <blp@gnu.org>
+
+       SORT always sorted in ascending order.  Fixed.  Thanks to Dr. Dirk
+       Melcher <BZN-mdksh@t-online.de> for reporting this bug.
+
+       * sort.c: (compare_case_lists) Reverse sense of comparison if
+       sorting in descending order.
+       (compare_record) Ditto.
+
+Tue Mar  9 13:18:54 1999  Ben Pfaff  <blp@gnu.org>
+
+       SPLIT FILE with a string variable caused a core dump.  Fixed.
+
+       * vfm.c: If the variable is a string then make a temporary value
+       struct pointing to it.  The underlying problem is a lot bigger
+       than this (see TODO) but this is a stopgap for the simple case at
+       least.
+       
+Tue Mar  9 13:15:53 1999  Ben Pfaff  <blp@gnu.org>
+
+       Nested INCLUDEs didn't work.  Fixed.
+
+       * getline.c: (getl_include) Set first_line to NULL in allocated
+       structure.
+
+Tue Mar  9 13:13:46 1999  Ben Pfaff  <blp@gnu.org>
+
+       The MATCH FILES procedure set the values of variables not present
+       to 0.  It should have been SYSMIS.  This is now fixed.
+
+       * get.c: (mtf_delete_file_in_place) Replace 0.0 by SYSMIS.
+
+Tue Mar  9 12:52:23 1999  Ben Pfaff  <blp@gnu.org>
+
+       The REMARK command was too aggressive about skipping lines.  It
+       didn't like being the last command in a file.
+
+       * command.c: (cmd_remark) Call get_entire_line() instead of
+       get_line().
+
+Tue Mar  9 12:48:05 1999  Ben Pfaff  <blp@gnu.org>
+
+       Comment parsing wasn't consistent with the rest of the code in its
+       idea of where one command ends and another starts.  This meant
+       that sometimes commands would be mysteriously ignored.  Thanks to
+       Dr. Dirk Melcher <BZN-mdksh@t-online.de> for reporting this bug.
+        
+       * command.c: (parse_cmd) Hand off comment parsing to new function
+       skip_comment() in lexer.c.
+       * lexer.c: (skip_comment) New function.
+
+Wed Jan 20 20:22:07 1999  Ben Pfaff  <blp@gnu.org>
+
+       The TABLE subcommand on MATCH FILES worked only erratically at
+       best.  This fixes it.  Thanks to Dr. Dirk Melcher
+       <BZN-mdksh@t-online.de> for reporting this bug.
+
+       * get.c: (mtf_compare_BY_values) When comparing string values, a
+       difference of 1 is still a difference :-)
+       (mtf_processing) Inverted TABLE reading logic fixed.  Also don't
+       advance TABLE files automatically when matched.  Comment fixes.
+
+Tue Jan 19 22:32:31 1999  Ben Pfaff  <blp@gnu.org>
+
+       VARIABLE LABELS rejected a slash before the first variable
+       specification, contradicting the documentation.  Thanks to Walter
+       M. Gray <graywm@northernc.on.ca> for reporting this bug.
+
+       * var-labs.c: (cmd_variable_labels) Ignore a leading slash in
+       command specification.
+
+Tue Jan 19 22:29:54 1999  Ben Pfaff  <blp@gnu.org>
+
+       Because of an incorrect optimization in memory allocation,
+       CROSSTABS sometimes segfaulted when asked to output multiple
+       tables.  Thanks to Walter M. Gray <graywm@northernc.on.ca> for
+       reporting this bug.
+
+       * crosstabs.q: (postcalc) New variables maxcols, maxcells, which
+       are passed to output_pivot_table() for its use.
+       (output_pivot_table) Instead of assuming the number of columns is
+       constant, keep track with maxcols.  In general mode, use maxcells
+       to determine whether more matrix cells need to be allocated.    
+
+Tue Jan 19 22:27:46 1999  Ben Pfaff  <blp@gnu.org>
+
+       CROSSTABS didn't display value labels for column and row
+       variables.  Thanks to Walter M. Gray <graywm@northernc.on.ca> for
+       reporting this bug.
+
+       * crosstabs.q: (table_value_missing) If the specified value has a
+       value label for this variable, then show it instead of the raw
+       value.
+       (display_dimensions) Delegate display of value_labels to
+       table_value_missing.
+
+Mon Jan 18 20:04:06 1999  Ben Pfaff  <blp@gnu.org>
+
+       WRITE didn't write line ends.  Fixed.  Thanks to Dr. Dirk Melcher
+       <BZN-mdksh@t-online.de> for reporting this bug.
+
+       * print.c: (print_trns_proc) Write (CR/)LF if PRINT is used _or_
+       if the file isn't declared as binary.
+
+Mon Jan 18 19:56:45 1999  Ben Pfaff  <blp@gnu.org>
+
+       MATCH FILES corrupted memory and dumped core on some syntax
+       errors.  Fixed.
+
+       * get.c: (cmd_match_files) Set file->handle to NULL before
+       jumping to lossage.
+       (mtf_free_file) Don't free a null dictionary.   
+
+Mon Jan 18 19:27:57 1999  Ben Pfaff  <blp@gnu.org>
+
+       MATCH FILES should set numeric values not available to the
+       system-missing value, not to 0.  Thanks to Dr. Dirk Melcher
+       <BZN-mdksh@t-online.de> for reporting this bug.
+
+       * get.c: (mtf_processing) Set unused records to system-missing,
+       not 0.
+
+Mon Jan 18 15:06:46 1999  Ben Pfaff  <blp@gnu.org>
+
+       KEEP didn't work properly on the SAVE procedure.  Fixed.  Thanks
+       to Ralf Geschke <ralf@kuerbis.org> for reporting this bug.
+
+       * temporary.c: (save_dictionary) Initialize var_by_name AVL tree
+       in newly created dictionary, and add each copied variable to the
+       tree.
+Mon Jan 18 15:04:48 1999  Ben Pfaff  <blp@gnu.org>
+
+       Memory leak fix.
+       
+       * get.c: (trim_dictionary) Free variable list for KEEP after
+       finishing with it.
+
+Mon Jan 18 12:57:36 1999  Ben Pfaff  <blp@gnu.org>
+
+       Some systems didn't like the way open_file was coded.  Thanks to
+       Hankin <hankin@rogue.consultco.com> for pointing this out.
+
+       * filename.c: (open_file) Don't try to store stdin, stdout,
+       stderr as part of an array, because that doesn't always work.
+
+Mon Jan 18 12:53:27 1999  Ben Pfaff  <blp@gnu.org>
+
+       The SAVE procedure didn't save long string variables properly.
+       Fixed by this patch.  Thanks to Hankin
+       <hankin@rogue.consultco.com> for this patch.
+       
+       * sfm-write.c: (write_variable) Fix off-by-one error in writing
+       out variable pad records.
+
+Tue Jan  5 14:29:27 1999  Ben Pfaff  <blp@gnu.org>
+
+       Previously, if PRINT SPACE were given a negative argument, it
+       would report an error, then spin in an (almost) infinite loop.
+       This fixes that behavior.
+
+       * print.c: (print_space_trns_proc) After reporting a negative
+       argument, set number of lines to print to 1.
+
+Tue Jan  5 13:59:55 1999  Ben Pfaff  <blp@gnu.org>
+
+       SPSS 8.0 outputs some new record types in its system files, and it
+       allows longer value labels.  Accept these system files.
+
+       * sfm-read.c: (sfm_read_dictionary) Ignore record type 7 subtype
+       11 emitted by SPSS 8.0.
+       
+Tue Jan  5 13:55:50 1999  Ben Pfaff  <blp@gnu.org>
+
+       The LIST procedure was too conservative in allocating space for
+       buffers, which caused a bug that only showed up with very long
+       output variables.  Thanks to Hankin <hankin@dunno.com> for this
+       bug report.
+
+       * list.q: (determine_layout) Allocate 1022 bytes instead of 256.
+
+Tue Jan  5 13:34:34 1999  Ben Pfaff  <blp@gnu.org>
+
+       Typo meant string format specifiers weren't checked properly.  I
+       think that Hankin <hankin@dunno.com> sent me this report, but I'm
+       willing to be corrected on this point.
+       * format.c: (check_string_specifier) Fix obvious typo.  
+
+Tue Jan  5 12:50:42 1999  Ben Pfaff  <blp@gnu.org>
+
+       Using $CASENUM in an expression didn't work.  Here's a fix.
+       Thanks to Dirk Melcher <BZN-mdksh@t-online.de> for reporting this
+       bug.
+        
+       * expr-evl.c: (evaluate_expression) Add OP_CASENUM case.
+
+       * expr-opt.c: (dump_node) OP_CASENUM is acceptable.
+
+Tue Jan  5 12:47:48 1999  Ben Pfaff  <blp@gnu.org>
+
+       The changes in 0.2.1 to fix DATA LIST FREE parsing broke some
+       other behavior, *sigh*.  This patch hopefully fixes that.  This
+       time I've actually tested it.
+
+       Thanks to Hankin <hankin@dunno.com> for reporting this bug.
+
+       * data-list.c: (read_from_data_list_free,
+       read_from_data_list_list) Call parse_string_as_format() directly
+       without mucking around with the field width.
+
+Tue Jan  5 12:31:19 1999  Ben Pfaff  <blp@gnu.org>
+
+       Occasionally, you may encounter a script that wants to be
+       interpreted in interactive mode.  Make -i emulate this behavior to
+       allow such scripts to be executed with PSPP.
+
+       Thanks to Hankin <hankin@dunno.com> for reporting this behavior.
+
+       * cmdline.c: (pre_syntax_message[]) Update -i description.
+
+       * lexer.c: (preprocess_line) When getl_interactive is 2 (i.e.,
+       when -i is given on the command line) don't treat unindented lines
+       as starting a new command.
+
+Tue Jan  5 12:30:10 1999  Ben Pfaff  <blp@gnu.org>
+
+       In conjunction with egcs 1.1.1, Checker emits some bogus warnings,
+       mostly caused by local initialized aggregates.  After egcs is
+       fixed upstream these can be removed, but for now they're not a big
+       deal.
+       
+       * ascii.c: (ascii_postopen_driver) Checker chokes on local
+       initialized arrays.  Avoid this.
+
+       * sfm-write.c: (sfm_write_dictionary) Don't use a local
+       initialized struct.
+
+Tue Jan  5 12:07:24 1999  Ben Pfaff  <blp@gnu.org>
+
+       egcs 1.1.1 has some new warnings relative to gcc 2.8.1, which the
+       following changes avoid.  Currently I compile sources with egcs
+       1.1.1 and gcc 2.7.2.3 before sending them out.
+
+       * apply-dict.c: (apply_dict) Use new avl_traverser_init() macro.
+       
+       * ascii.c: (option_tab[]) Initialize all struct members.
+
+       * avl.h: (avl_traverser_init) New macro.
+       
+       * command.c: (DEFCMD, UNIMPL macros, cmd_table[]) Initialize all
+       struct members.
+
+       * crosstabs.q: (enum_var_values) Use new hsh_iterator_init()
+       macro.
+
+       * hash.c: Comment fix.
+
+       * hash.h: (hsh_iterator_init) New macro.
+
+       * html.c: (option_tab[]) Initialize all struct members.
+
+       * pfm-write.c: (write_value_labels) Use new avl_traverser_init()
+       macro.
+
+       * postscript.c: (option_tab[]) Initialize all struct members.
+       (output_encodings, preclose, dump_lines) Use new
+       hsh_iterator_init() macro.
+
+       * sfm-write.c: (write_value_labels) Use new avl_traverser_init()
+       macro.
+
+       * sysfile-info.c: (describe_variable) Use new avl_traverser_init()
+       macro.
+
+Thu Nov 19 12:32:45 1998  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: Examined each of the parsing functions to make sure
+       that they wouldn't dump core if they were passed a string of the
+       wrong length, since now the DATA LIST FREE/LIST routines don't
+       check for field width before passing it to the data parser.
+       (parse_RBHEX, parse_AHEX) Reject odd length input.
+       (parse_string_as_format) Reject input that's too short or too
+       long.
+
+       * data-list.c: Before, the DATA LIST FREE/LIST routines would pad
+       a field to its entire declared output width then pass it to the
+       data-in parsing routines.  This contradicted the documented
+       behavior.  This is fixed in these changes.  Thanks to Mark H. Wood
+       <mwood@IUPUI.Edu>.  In addition, this fixes a few more details of
+       free-format parsing that differed from SPSS.
+       (cut_field) Commas and spaces are treated identically.  Returns
+       the proper column instead of a fixed 1 value.
+       (parse_field) Removed.
+       (read_from_data_list_free, read_from_data_list_list) Call
+       parse_string_as_format directly instead of parse_field.
+
+       * heap.c: (heap_delete) Stylistic fixes.
+
+Sun Aug  9 11:12:13 1998  Ben Pfaff  <blp@gnu.org>
+
+       * loop.c: (loop_2_trns_proc) Formatting fix.
+
+       * sel-if.c: (cmd_filter) Set FILTER_before_TEMPORARY.
+
+       * var.h: (glob var FILTER_before_TEMPORARY) New global var.
+
+       * vfm.c: (macro FILTERED) New.
+       (static var filter_var) New.
+       (process_active_file_write_case) Use FILTERED.
+       (setup_filter) Set filter_var.
+       (close_active_file) Delete the filter if not
+       FILTER_before_TEMPORARY.
+       (procedure_write_case) Use FILTERED.
+
+Sat Aug  8 00:20:14 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: Changed /PIVOT={ON,OFF} to /FORMAT={PIVOT,NOPIVOT}.
+
+       * data-in.c: (parse_day_count) Message fix.
+       (parse_month) Style fix.
+
+       * data-list.c: (struct data_list_pgm) New member eof.
+       (cmd_data_list) Init eof to 0.
+       (do_reading) Implement the /END subcommand and read-past-eof
+       checking.
+
+       * do-if.c: Include stdio.h when debugging.
+       (cmd_else_if) Make sure the command is .-terminated.
+
+       * glob.c: (init_glob) Capitalize the command prompt.
+
+       * inpt-pgm.c: (end_case_trns_proc) Debugging message.
+       (end_file_trns_proc) Debugging message.
+
+       * loop.c: (internal_cmd_loop) Make it work when there's no loop
+       index!
+       (loop_2_trns_proc) Enable MXLOOPS (why was this disabled?)
+
+       * main.c: (dump_token) Make kwtab[] const.
+
+       * set.q: Spelling, comment fixes.
+
+       * sysfile-info.c: (cmd_display) DISPLAY VECTORS not DISPLAY
+       VECTOR.
+
+       * vars-prs.c: (fill_all_vars) Style fix.
+
+       * vfm.c: (index_to_varname) Return const.
+
+Tue Aug  4 23:49:23 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Changes in many source files for partial -ansi -pedantic and
+       no-debugging compliance: Remove trailing common in enum
+       declarations; add `unused' attributes; insert some appropriate
+       casts.
+
+       * cmdline.c: (parse_command_line) Add new --testing-mode flag.
+
+       * command.c: (shell) Make static.
+       (run_command) Make static.
+
+       * data-list.c: (dump_fixed_table) Remove use of local_strdup().
+
+       * dfm.c: (cmd_begin_data) I18n fix.
+
+       * error.c: (verbose_msg) Define if __STRICT_ANSI__.
+
+       * error.h: (macro verbose_msg) Define if __STRICT_ANSI__.
+
+       * expr-opt.c: (evaluate_tree) Don't initialize local arrays if
+       __STRICT_ANSI__.
+
+       * file-handle.q: Don't prepend the source file directory name to
+       the data file name.  (Ongoing issue.)
+       (prepend_current_directory) Comment out.
+       (internal_cmd_file_handle) Don't call prepend_current_directory().
+       (fh_get_handle_by_filename) Ditto.
+
+       * filename.c: Append zero byte to readlink() return value.
+
+       * getline.c: (getl_read_line) I18n fix.
+
+       * lexer.h: Don't use gcc features if __STRICT_ANSI__.
+
+       * misc.h: Don't use gcc features if __STRICT_ANSI__.
+
+       * pfm-write.c: (bufwrite) Don't try to increment a void * pointer
+       directly.
+
+       * postscript.c: (output_encodings) Don't use local_strdup().
+       (postopen) Ditto.
+
+       * print.c: Don't use gcc features if __STRICT_ANSI__.
+
+       * q2c.c: (dump_vars) Don't put a , at the end of the last enum.
+
+       * recode.c: (parse_src_spec) Fully brace nested if's.
+
+       * set.q: (global var set_testing_mode) New var.
+
+Wed Jul 29 22:01:44 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: Add some more `unused' attributes that only come into
+       play when NDEBUG is defined.
+       (ascii_close_page) Set s_len when reallocating s.
+       
+       * crosstabs.q: (delete_missing) New function.
+       (output_pivot_table) Call delete_missing() if /MISSING=REPORT.
+       (make_summary_table) Create summary table reallocable.
+
+       * postscript.c: Add more `unused' attributes as above.
+
+       * tab.c: (tab_create) [GLOBAL_DEBUGGING] Set reallocable member.
+       (tab_realloc) [GLOBAL_DEBUGGING] Assert that table is reallocable.
+        
+       * tab.h: (struct tab_table) [GLOBAL_DEBUGGING] New `reallocable'
+       member.
+
+       * var.h: (macro force_dup_variable) [!GLOBAL_DEBUGGING] Remove
+       gratuitous space between parameter definition.
+
+       * vars-atr.c: Changed some assert(0)'s to abort()'s to prevent
+       complaints about running off the end of functions with NDEBUG
+       enabled.
+
+Sun Jul  5 00:17:25 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Several source files: Removed some PORTME notes when reflection
+       revealed that ANSI forbids that sort of breakage.  Also, added
+       lots of `unused' qualifiers here and there.
+
+       * aggregate.c: (accumulate_aggregate_info) Remove local var
+       weighting that turned out not to be used.
+
+       * avl.c: Update to version 1.1.0.  Add unused specifier.
+       (avl_destroy) Initialize ab to 0.  Comment fixes.  Cast return
+       value to void *.
+       (avl_probe) Replace some instances of 1 with +1 where appropriate.
+       (avl_find) Cast return value to void *.
+       (avl_delete) q doesn't need to be initialized at the beginning of
+       the function.  Replace some instances of 1 with +1.
+       (force_avl_delete) Renamed avl_force_delete, all references changed.
+       (compare_ints) `param' marked unused.
+       (print_int) `param' marked unused.
+       (recurse_tree) Replace some instances of 1 with +1.
+
+       * avl.h: Update to version 1.1.0.  Only declares avl function
+       types if not already declared.
+       (AVL_MAX_HEIGHT) Only define if not already defined.
+       (struct avl_node) New unused member char pad[2].
+       [GLOBAL_DEBUGGING] Change conditionalization to NDEBUG instead.
+       (force_avl_insert) Renamed avl_force_insert.
+       (force_avl_delete) Renamed avl_force_delete.
+
+       * crosstabs.q: (struct table_entry) Put `freq' into a union with
+       new member `data'.
+       (struct crosstab) Add new member `ofs'.
+       (glob var int_tab) Removed.
+       (custom_tables) In integer mode, assign v[i] properly through the
+       indirect var_dict.
+       (custom_variables) Now p.crs.max == max + 1.
+       [DEBUGGING] (debug_print) p.crs.min and p.crs.max are now ints.
+       (precalc) Implement integer mode.
+       (calc_integer) Implement integer mode.
+       (compare_table_entry) Remove unused local variable `comparing'.
+       (make_summary_table) Implement integer mode.
+       (macro ns_rows) Implemented as static variable now.
+       (several variables) Made static, from global.
+       (output_pivot_table) Use table_value_missing() for column heads.
+       Remove several unused local variables.  Implement integer mode
+       table summing.  Count up ns_rows.
+       (crosstabs_dim) Make columns wider when /MISSING=REPORT requested.
+       (find_pivot_extent) Moved into find_pivot_extent_general; now just
+       calls that function or find_pivot_extent_integer.
+       (find_pivot_extent_integer) New function.
+       (enum_var_values) Implemented for integer mode.
+       (table_value_missing) New function.
+       (display_dimensions) Call table_value_missing() for heads.
+       (float_M_suffix) New function.
+       (display_crosstabulation) Call table_value_missing() for row
+       heads.  Handle missing values in /MISSING=REPORT mode.
+       (calc_fisher) Remove unused var N.
+       (calc_r) Remove unused var fact.
+
+       * data-list.c: (dump_fixed_table) Fix table dimensioning.
+       (read_one_set_of_repetitions) Remove unused vars var_spec, column.
+
+       * data-out.c: (insert_commas) Remove unused var cp.
+       (convert_CCx) Remove unused vars save_set_decimal,
+       save_set_grouping.
+
+       * descript.q: (dump_z_table) Fix table dimensioning.
+       (pre_calc) Remove unused var j.
+       (display) Remove unused vars title, s.  Fix table dimensioning.
+
+       * expr-evl.c: Comment fixes.
+
+       * frequencies.q: (full_dim) New function.
+       (dump_full) Fix table dimensioning.
+       (condensed_dim) New function.
+       (dump_condensed) Fix table dimensioning.
+
+       * get.c: (cmd_match_files) Remove unused var n_val.  Remove unused
+       label winnage.
+
+       * html.c: (html_close_drive) Remove unused var i.
+       (postopen) Remove unused vars title, curfn_len, cp.
+       (preclose) Remove unused vars this, x.
+
+       * lexer.c: Comment fixes.
+
+       * matrix-data.c: (cmd_matrix_data) Remove unused var index.
+
+       * means.q: (custom_tables) Remove unused var m_dim.
+
+       * mis-val.c: Format fix.
+
+       * modify-vars.c: (cmd_modify_vars) Remove unused var new_dict.
+
+       * output.c: (outp_get_paper_size) Remove unused var cp.
+
+       * pfm-read.c: (read_float) Remove unused var save, unused label
+       underflow.
+       (read_variables) Remove unused vars cp, j.
+       (read_value_label) Remove unused var j.
+
+       * pfm-write.c: (bufwrite) Remove unused var i.
+
+       * postscript.c: (ps_postopen_drive) Remove unused vars dev_info,
+       fn.
+       (output_encodings) Remove unused vars char_cp, n_output.
+       (read_ps_encodings) Remove unused var ep.
+       (postopen) Remove unused var title.
+       (preclose) Remove unused var fp.
+       (ps_open_page) Remove unused vars true, false, orientation,
+       mirror_horz, mirror_vert, width, length.
+       (ps_text_metrics) Remove unused var x.
+
+       * q2c.c: (find_symbol) Remove unused var y.
+       (parse_setting) Remove unused parameter sbc, all references
+       changed.
+       (dump_parser) Remove unused var cp.
+       (dump_free) Remove unused var i.
+
+       * set.q: (static vars args, n) Removed.
+       (internal_cmd_gset) Removed.
+
+       * sfm-read.c: (sfm_read_dictionary) Removed unused var i.
+       (read_machine_flt64_info) Removed unused var file_endian.
+       (read_documents) Removed unused var i.
+       (read_compressed_data) Removed unused parameter dict, all
+       references changed.
+
+       * sfm-write.c: (bufwrite) Removed unused var i.
+       (sfm_write_case) Removed unused var i.
+
+       * sort.c: (merge_once) Remove unused var t.
+       (write_separate) #if 0 out as dead code.
+
+       * split-file.c: (cmd_split_file) Remove unused var i.
+
+       * sysfile-info.c: (sysfile_info_dim) New function.
+       (cmd_sysfile_info) Fix table dimensioning.
+       (variables_dim) New function.
+       (display_variables) Fix table dimensioning.
+       (describe_variable) Remove unused var prev_r.
+
+       * t-test.q: (z_postcalc) Removed.
+       (pairs_calc) Remove unused var bad_weight.
+       (postcalc) Remove unused vars dfn, dfd.
+
+       * tab.c: (tab_create) Set t->dim to NULL.
+       (tab_dim) Make sure t->dim is NULL first.
+       (tab_natural_width) Remove parameter `clamp'.
+       (tab_value) Remove duplicate assertion for table.
+       (tab_raw) New function.
+       (nowrap_dim) New function.
+       (wrap_dim) New function.
+       (tab_output_text) Fix table dimensioning.
+
+       * tab.h: (tab_raw) New macro.
+
+       * val-labs.c: (get_label) Remove unused var type.
+       (copy_value_labels) Remove unused var trav.
+
+       * var.h: (struct crosstab_proc) Completely changed.
+
+       * vars-prs.c: (parse_dict_variable) Remove unused var v.
+
+       * vfm.c: (open_active_file) Remove unused vars i, lp.
+
+       * weight.c: (weight_trns_proc) #if 0 out as dead code.
+       
+Tue Jun  2 23:37:21 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add apply-dict.c, flip.c.
+
+       * apply-dict.c: New file.
+       
+       * command.c: (struct command) Make cmd[] larger for CLEAR
+       TRANSFORMATIONS command name.
+       (parse_cmd) Make sure we're in a valid state before using it as an
+       index.  Discard variables and reset state on invalid transitions.
+       (cmd_clear_transformations) New function.
+
+       * command.def: Add APPLY DICTIONARY, CLEAR TRANSFORMATIONS, FLIP.
+       Add unimplemented PRESERVE, RESTORE.
+
+       * file-handle.h: Include stddef.h.
+
+       * flip.c: New file.
+       
+       * pfm-read.c: (parse_value) Pad value label values with spaces,
+       not nulls.
+
+       * sfm-read.c: (struct sfm_fhuser_ext) Add reference count.
+       (sfm_close) Decrement reference count, make sure it's zero.
+       (sfm_maybe_close) New function.
+       (sfm_read_dictionary) Handle reference counts.
+
+       * vars-atr.c: (clear_default_dict) New function.
+       (discard_variables) Use clear_default_dict().
+
+Sun May 31 00:58:05 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add pfm-write.c.
+       (LDADD) Add the libgmp2 libraries.
+
+       * command.def: Define EXPORT.
+
+       * get.c: (cmd_export) New function.
+       (export_write_case_func) New function.
+
+       * pfm-read.c: (static spss2ascii[]) Make it const.
+
+       * pfm-write.c: New file.
+
+       * sfm-write.c: Formatting, comment fixes.
+
+       * var.h: Comment fix.
+
+Fri May 29 21:44:12 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add pfm.h, pfm-read.c.
+
+       * command.def: IMPORT is now implemented.
+
+       * format.c: (glob var translate_fmt[]) New var.
+
+       * get.c: (enum GTSV_NONE) Renamed GTSV_OPT_NONE.
+       (cmd_import) New function.
+       (import_source_read) New function.
+       (glob var import_source) New var.
+
+       * pfm-read.c: New file.
+
+       * pfm.h: New file.
+       
+       * sfm-read.c: (parse_format_spec) Local variable translate_fmt[]
+       moved in format.c.
+       (dump_dictionary) Disabled printing a couple of items.
+
+Mon May 25 12:42:37 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (postcalc) Call make_summary_table().
+       (make_summary_table) New function.
+       (insert_summary) New function.
+       (display_dimensions) Remove some unnecessary arguments, all
+       references changed.
+       (output_pivot_table) Fix lots of problems with the risk table
+       setup.
+       (submit) Don't display an empty table.
+       (display_risk) Fix order of arguments to calc_risk().
+
+       * glob.c: Always include assert.h and stdlib.h.
+
+       * output.h: (enum OUTP_T_JUST_FULL) Removed, all references
+       removed.
+
+       * tab.c: (tab_create) Cosmetic changes.
+
+       * tab.h: (enum TAB_JUSTIFY) Removed, all references removed.
+
+Sun May 24 22:39:23 1998  Ben Pfaff  <blp@gnu.org>
+
+       * tab.def: Removed.
+
+       * crosstabs.q: (output_pivot_table) Headers drawing and submission
+       code simplified, moved into new function submit().
+       (submit) New function.
+       (crosstabs_dim) New function.
+       (display_directional) Substitute variable names for %s where
+       appropriate.
+       (somers_d_v[], somers_d_ase[], somers_d_t[]) New static vars.
+       (calc_symmetric) Initialize parameters only if non-NULL.
+       Calculate Somers' d.
+       (calc_directional) Calculate Somers' d (or copy it, really).
+       Calculate eta.
+
+       * output.c: (outp_string_width) New function.
+
+       * postscript.c: (postopen) Calculate font widths based on the
+       width of the zero '0' character, not the width of the space
+       character.  Set paper-width and paper-length based on points, not
+       device units.
+       (ps_open_page) Fix page setup string for landscape mode.
+
+       * som.h: (struct som_dimension) Removed.
+       (struct som_table_class) height, width members take int * not
+       som_dimesion * now.
+
+       * tab.c: Many functions now have added parameter validation.
+       (tab_height, tab_width) These functions were removed and merged
+       into a single function tab_resize(), and all references changed.
+       (tab_dim) Rewritten since the interface changed; reduced from
+       hundreds of lines to two.  All callers were changed.  Currently
+       most of them just use tab_natural_dimensions as their callback and
+       await detailed translation of functionality.
+       (tab_natural_width) New function.
+       (tab_natural_height) New function.
+       (tab_natural_dimensions) New function.  This is a callback
+       function, not something that you'd want to call directly.
+       (tab_nat_dim) Removed.
+       (tabi_table) Allocates t->w and t->h.
+       (tabi_driver) Inlined sum_columns()'s functionality.  Calls the
+       dimensions callback.
+       (evaluate_dimensions) Removed.
+       (sum_columns) Removed.
+
+       * tab.h: (enum TAL_1THIN) Removed.
+       (enum series t_*) Removed.
+       (struct tab_table) Members trh, trv changed to unsigned char *
+       from int *.  Member dim changed to a function pointer from a
+       unsigned char *.  Member max_stack_height removed.  New members
+       hr_tot, vr_tot.
+       (macros tab_l, tab_r, tab_t, tab_b) New.
+
+Sat May 23 23:22:13 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (delineate) Assign last_space_nchars before skipping
+       spaces, to fix right justification.
+
+       * crosstabs.q: (static vars risk, direct) New vars.
+       (static var pearson_r) Removed.
+       (glob var chisq_fisher) Made static.
+       (static vars row_tot[], col_tot[]) Don't include grand total
+       anymore.
+       (static var grand_total) Renamed W, all references changed.
+       (output_pivot_table) Only make `table' if num_cells != 0.  Make
+       risk and directional tables.  Deal with grand total no longer part
+       of col_tot[].  Free rows and cols after we're done with them.
+       (display_risk) New function.
+       (display_directional) New function.
+       (clac_r) Rewritten so that it stores all its results into its
+       arguments, so it can be used for Spearman's correlation too.
+       (calc_symmetric) Added a t[] argument, all references changed.
+       Calculates ASEs for tau-b, tau-c, gamma.  Calculates Spearman's r,
+       Pearson's r, Cohen's kappa.
+       (calc_risk) New function.
+       (calc_directional) New function.
+
+       * som.c: (som_submit) Improved debugging code.
+
+       * stats.c: (hypercube) New function.
+       (cube) New function.
+       (sqr) New function.
+       (normal_sig) Went back to old implementation, which actually
+       worked.
+
+       * stats.h: (macros square, cube, hypercube) Removed.  The
+       equivalent functions in stats.c are inlined here; all references
+       to square changed to sqr.
+
+Fri May 22 00:03:41 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (N_SYMMETRIC) New define.
+       (postcalc) Disable debug printing.
+       (static vars chisq_fisher, pearson_r) New.
+       (output_pivot_table) Add support for symmetric measures.  Add
+       chi-square output of exact sigs.
+       (display_chisq) Rewritten.
+       (display_symmetric) New function.
+       (gamma_int) New function.
+       (Pr) New function.
+       (swap) New function.
+       (calc_fisher) New function.
+       (calc_chisq) Check boundary conditions better. Calculate Yates,
+       Fisher, Mantel-Haenszel tests.
+       (calc_r) New function.
+       (calc_symmetric) New function.
+
+       * stats.c: (normal_sig) Rewritten with new algorithm.  Renamed
+       from calc_normal.
+       (chisq_sig) Better boundary conditions.  Renamed from
+       calc_significance.
+
+       * tab.h: (struct tab_table) New member cf.
+
+       * tab.c: (tab_create) Set cf.
+       (tab_width) New function.
+       (tab_realloc) Handle cf.
+       (tab_vline) Handle cf.
+       (tab_hline) Handle cf.
+       (tab_box) Handle cf.
+       (tab_value) Handle cf.
+       (tab_float) Handle cf.
+       (tab_text) Handle cf.
+       (tab_joint_text) Handle cf.
+       (tab_offset) Handle cf.
+       (tab_next_row) Handle cf.
+       (evaluate_dimensions) Handle cf.
+       (render_strip) Handle cf.
+
+Wed May 20 00:03:59 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (postcalc) New vars row_tot, col_tot, pass them to
+       output_pivot_table().
+       (output_pivot_table) Moved lots of local variables outside and
+       made them static.  Add beginnings of chi-square statistic
+       support.  Now column and row totals aren't in the main matrix.
+       Always zero out any leftover rows & columns after we're done with
+       the table entries.  Move all output stuff into
+       display_dimensions(), display_crosstabs(), display_chisq().
+       (display_dimensions) New function.
+       (display_crosstabulation) New function.
+       (display_chisq) New function.
+       (calc_chisq) Implemented Pearson and likelihood-ratio chisquares.
+
+       * frequencies.q: (dump_full, dump_condensed) Remove tab_null()
+       references, simplify logic.
+
+       * postscript.c: Remove scale, translate-x, translate-y,
+       mirror-horz, mirror-vert, rotate-180 options.
+       (struct ps_driver_ext) Remove scale, translate_x, translate_y.
+       All references deleted.
+       (macro YT) New macro.
+       (array option_tab[]) Removed options.
+       (ps_option) Removed options.
+       (ps_open_page) Write page setup explicitly to output file, without
+       using now-deleted BP function.
+       (macro dump_line) Use YT().
+       (macro dump_thick_line) Use YT().
+       (draw_headers) Use YT().
+       (switch_font) Reorder arguments to SF function.
+       (write_text) Use YT().
+
+       * sfm-read.c: (sfm_read_case) Don't attempt to read variables that
+       have get.fv == -1.
+
+       * sysfile-info.c: (describe_variables) Don't use tab_nulls().
+
+       * tab.c: (tab_create) Initialize t->ct to zeros.  Remove
+       null-debugging code.
+       (tab_realloc) Remove null-debugging code.  Initialize new regions
+       of t->ct to zeros.
+       (tab_vline) Support offsets.
+       (tab_hline) Support offsets.
+       (tab_box) Support offsets.
+       (tab_null) Removed.
+       (tab_nulls) Removed.
+       (tab_row) Removed.
+       (tab_col) Removed.
+       (evaluate_dimensions) Remove null-debugging code.  Understand
+       TAB_EMPTY attribute.  Assert that text.s.s is always non-NULL if
+       TAB_EMPTY not present.
+
+       * tab.h: New cell attribute TAB_EMPTY.
+       (macros tab_nr, tab_nc, tab_row, tab_col) New.
+
+       * vars-atr.c: (init_variable) Set get.fv to -1 so that GET doesn't
+       try to read them from system files.
+
+       * vfm.c: (dump_splits) Don't call tab_null().   
+
+Sat May 16 19:36:55 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (struct crosstab) Added `missing' member.
+       (custom_tables) Init missing.
+       (calc_general) Handle missing values.
+       (calc_chisq) New function.
+       (output_pivot_table) Start work on chi-square output.  Update for
+       new tab offset support functions.  Shorten statistic names.
+
+       * Several files: add in more `const's to placate gcc's warnings.
+
+       * tab.h: (struct tab_table) Add col_ofs, row_ofs members.  Comment
+       fixes.
+
+       * tab.c: (tab_height, tab_realloc, tab_vline, tab_hline, tab_box,
+       tab_null, tab_nulls, tab_value, tab_float, tab_text,
+       tab_joint_text) Add col_ofs and row_ofs support.
+       (tab_offset) New function.
+       (tab_next_row) New function.
+       (tab_row) New function.
+       (tab_col) New function.
+       (tabi_table) Add col_ofs and row_ofs support.
+
+       * vars-atr.c: (is_system_missing) New function.
+
+Tue May 12 16:14:30 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: Expanded subcommand names RESID --> RESIDUAL, etc.
+       (static var no_cells) Removed.
+       (static var num_cells) New.
+       (static var expected) New.
+       (static var cells[]) New.
+       (internal_cmd_crosstabs) Deal with new variables.
+       (postcalc) Removed most of the meat and put it in new function
+       output_pivot_table().
+       (output_pivot_table) Calculates and outputs an entire pivot table.
+
+       * postscript.c: (postopen) Fix problems with free()ing addresses
+       not obtained from malloc().
+
+       * som.c: (som_submit) Add assertion.
+
+       * sysfile-info.c: (describe_variable) Use new tab_nulls()
+       function.
+
+       * tab.c: (static var tab_names[]) New.
+       (tab_realloc) -1 for nc or nr indicates no change.
+       (tab_nulls) New function.
+       (tab_dim) Use tab_names[].
+       (tabi_cumulate) Don't include bottom or right headers.  Furrfu.
+       (evaluate_dimensions) Don't terminate on uninited cells, just put
+       an X in them and emit a notice.  Use tab_names[].
+
+       * tab.h: Move bits into tab.def.
+
+       * tab.def: New.  Don't try to declare tab_table_class because then
+       som.h has to be included.       
+       
+Thu May  7 22:55:04 1998  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: New file, contains all the command definitions
+       previously included bodily in command.c.
+
+       * format.def: New file, contains all of the format definitions
+       previously split across format.h, format.c, and sfm-write.c.
+
+       * lexer.h: Renamed from tokens.h in order to match corresponding
+       .c file name.
+
+       * lexerP.h: Moved some rarely used functions exported by lexer.c
+       into here.
+
+       * Makefile.am: Commemorate renamed files.
+       (EXTRA_DIST) Add command.def, format.def.
+
+       * command.c: [0] (walk_cmdtable_func) Removed.
+
+       * crosstabs.q: (postcalc) Made it work and print out matrices
+       proving it.
+       (enum_column_values) Renamed enum_var_values, generalized for any
+       variable.
+
+       * format.h: (struct fmt_desc) New member `spss'.
+
+       * q2c.c: (main) Generated code includes lexer.h instead of
+       tokens.h.
+
+       * sfm-write.c: (write_format_spec) Use new spss member of fmt_spec
+       instead of an independent translation table.
+
+Tue May  5 13:19:03 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Lots of source files: Added const to declarations.
+
+       * aggregate.c: (parse_aggregate_function) Rename inner i to j.
+       
+       * arena.c: (arena_clear) Set prev pointer to null when done.
+
+       * ascii.c: (ascii_option) Rename index as indx.
+
+       * avl.c: This is now a separate library called libavl.
+       (xmalloc) Make static.
+       (avl_probe) Step A7 can use the cache instead of an explicit
+       compare.
+       (avl_delete) Don't maintain a q pointer because it's always
+       available in the pointer stack.  Comment fix.
+
+       * avl.h: This is now a separate library called libavl.
+
+       * command.c: (cmd_table[]) Remove spurious trailing "".
+
+       * common.h: Only include random() fix if this system needs it.
+
+       * crosstabs.q: Include alloca headers.
+       (n_sorted_tab) New global var.
+       (postcalc) Mostly rewritten.
+       (find_pivot_extent) Rewritten.
+       (enum_column_values) Rewritten.
+
+       * data-out.c: (convert_F) Rename inner n as n_spaces.
+
+       * error.c: (dump_message) Don't have an outer var i.
+
+       * file-handle.q: (static var f) Removed.  All references removed.
+       (internal_cmd_file_handle) Uses a local variable instead of f.
+
+       * get.c: (trim_dictionary) Change scope of i, i1, i2.
+       (cmd_match_files) Don't strcpy tokstr into sbc (why was this ever
+       done?)
+
+       * getline.h: Declare getl_history as extern.  Reported by
+       palme@uni-wuppertal.de (Hubert Palme).
+
+       * postscript.c: (postopen) Some large mods for constness.
+
+       * recode.c: Remove spurious copyrights since PSPP is owned by FSF
+       anyway.
+
+Fri Apr 24 12:52:47 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Rename BUILT_SOURCES to q_sources, all references
+       changed.  Add avl.c, avl.h to pspp_SOURCES.  Remove avllib from
+       LDADD.
+
+       * avl.c, avl.h: New files.  These form a clean-room
+       reimplementation of avllib.  Iterative algorithms are used in
+       place of recursive ones, so there is no resemblance in the code.
+
+       * Lots of headers: Don't include other headers by default.
+
+       * Lots of source files: Explicitly include all needed headers.
+
+       * arena.c: (arena_clear) New function.
+
+       * crosstabs.q: (ROW_VAR, COL_VAR) New enums.
+       (static var ar) Removed.
+       (staitc vars ar_tc, ar_col) New.
+       (cmd_crosstabs) Destroy the arenas.
+       (internal_cmd_crosstabs) Create the arenas.
+       (precalc) Don't need a free function for the hash.
+       (calc_general) Make sure to zero out the trailer on the key data
+       before inserting.
+       (print_table_entries) Updated.
+       (postcalc) Worked on actually implementing.
+       (find_pivot_extent) New function.
+       (compare_value) New function.
+       (enum_column_values) New function.
+
+       * data-in.c: (parse_month) Make local array `static const'.
+       
+       * data-out.c: (convert_date) Make local array `static const'.
+       (convert_WKDAY) Same.
+       (convert_MONTH) Same.
+
+       * frequencies.q: (postprocess_freq_tab) avl_walk_inorder() has
+       been renamed to avl_walk().
+       
+       * hash.c: Rewritten more efficiently.
+
+       * hash.h: Add attribute const to hsh_next_prime declaration.
+
+       * lexer.c: (id_match) Make arguments const.
+
+       * postscript.c: (ps_postopen_driver) Make default fonts the
+       Helvetica family.
+
+       * q2c.c: (main) Generated code needs stdlib.h.
+
+       * sfm-write.c: (write_value_labels) An avl_traverser needs to be
+       initialized to 0 now, not to NULL.  All other references to
+       avl_traverser were updated in the same way.
+
+       * tokens.h: Macro version of id_match updated to use const
+       properly.
+
+       * val-labs.c: (inc_ref_count) New function.
+       (copy_value_labels) Simply through use of new avl_copy() function.
+
+Wed Apr 15 13:01:58 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: Probably doesn't compile.  New PIVOT subcommand.
+       (postcalc) Worked on this.
+
+       * postscript.c: (OPO_DOUBLE_LINE) New enum.
+       (struct ps_driver_ext) New line_width_thick member.
+       (ps_preopen_drive) Init line_width_thick.
+       (option_tab[]) Add line-* options.
+       (ps_option) Parse line-* options.
+       (postopen) Add line_width_thick support.  Strip leading spaces on
+       prologue output lines.
+       (ps_open_page) Include line_width_thick in output.
+       (macro dump_thick_line) New.
+       (dump_fancy_line) Support thick lines as well as double lines.
+
+Tue Apr 14 00:50:08 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add crosstabs.c to BUILT_SOURCES.  Add crosstabs.q
+       to pspp_SOURCES.  Add crosstabs.q to EXTRA_DIST.
+
+       * Many source files: Rename `options' to `pv_opts' as appropriate.
+
+       * command.c: (static var cmd_table[]) Add CROSSTABS command.
+
+       * common.c: (xcalloc) New function.
+
+       * crosstabs.q: New file.  Not finished yet, though.
+               
+       * data-list.c: Comment fix.
+
+       * error.c: Remove some old Checker cruft.
+
+       * frequencies.q: (dump_full) Cumulate valid percent instead of
+       regular percent.
+
+       * getline.c: Comment fix.
+
+       * hash.c: Comment fixes.
+
+       * hash.h: (struct hsh_table) Make hash functions return unsigned
+       instead of int to avoid problems with taking the modulo of
+       negative return values.  All references changed.
+
+       * misc.c: (intlog10) Make its table static const instead of auto.
+
+       * sfm-read.c: (read_header) Make `prefix' static const instead of
+       auto.
+
+       * var.h: (union value) Add member `hash'.
+       (struct variable) Rename prv_index as `foo'--all references
+       changed.  Reorder.
+       (typedef pv_opts) Removed.  All references changed.
+
+       * vars-prs.c: (parse_variables) Message fixes.
+       
+Mon Mar  9 15:35:08 1998  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_match_files) Don't reverse the order of FILEs as
+       they are being inserted.  Don't check for BY variables of
+       different types.  Discard variables if the active file isn't
+       included in the merge.
+       (mtf_processing) Essentially rewritten.
+       (mtf_merge_dictionary) Check for master/slave variables of
+       different types/widths.
+
+       * vfm.c: (static var not_canceled) New var.
+       (process_active_file) Don't call vfm_source->read() if
+       there's no vfm-source.  Initialize not_canceled.
+       (process_active_file_write_case) Honor and update not_canceled.
+       (prepare_for_writing) Rollback changes from yesterday, they were
+       wrong.
+       (close_active_file) Don't destroy vfm_source unless it exists.
+       
+Mon Mar  9 00:56:16 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Lots of source files: Added { } around nested if/else constructs
+       to avoid new gcc 2.8 warnings.
+
+       * data-in.c: (parse_Z) Declare `int' type explicitly.
+       (convert_Z) Ditto.
+
+       * get.c: (struct mtf_file) Add prev, next_min, by, input members.
+       (cmd_match_files) Initialize mtf_by_values.  Manage by, input,
+       prev members.  Put TABLEs at the end of the chain and FILEs at the
+       beginning.  Don't allow the active file in STATE_INIT.  Use proper
+       `seen' value for the active file.  Fill out the by members and
+       make sure they're of consistent type.  Do the actual merge
+       operation.
+       (mtf_processing_finish) New function.
+       (var_type_description) New function.
+       (mtf_free_file) New function.
+       (mtf_free) Rewritten.
+       (mtf_delete_file_in_place) New function.
+       (mtf_read_nonactive_records) New function.
+       (mtf_compare_BY_values) New function.
+       (static var mtf_seq_no) New var.
+       (mtf_processing) New function.
+       (mtf_merge_dictionary) Assign nval members for the system file
+       dictionary.  Assign fv values for its variables.  Point each slave
+       variable to the corresponding master variable.
+
+       * hash.c: Include str.h.
+
+       * mis-val.c: (copy_missing_values) src arg is const.
+
+       * misc.c: (spacing) Make `max' var explicitly int.
+
+       * sfm-read.c: (dump_dictionary) Message reformatting.
+       (sfm_read_case) Add assertion.
+
+       * sort.c: Esthetic fixes.
+
+       * var.h: (struct match_files_proc) New struct.
+       (struct variable) Add private data match_files_proc.
+
+       * vars-atr.c: (delete_variable) Implement.  Add argument for the
+       dictionary that owning the variable.
+       (dup_variable) Add assertion.
+
+       * vfm.c: Comment fixes, hopefully the comments are correct now.
+       (process_active_file) New function.
+       (process_active_file_write_case) New function.
+       (process_active_file_output_case) New function.
+       (prepare_for_writing) Use temp_dict->nval for vfm_info, not
+       default_dict.nval.
+       (write_case) Renamed procedure_write_case().  Now write_case is a
+       pointer to a function.  Style fixes.
+       
+1998-03-05  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (q2c) Link with libmisc.
+       (version.c) Define default_config_path, include_path,
+       groff_font_path.
+
+       * ascii.c: (ascii_postopen_driver) When the default newline string
+       is requested, open file in text mode.  Suggested by
+       palme@uni-wuppertal.de (Hubert Palme).
+       (static vars line_buf, line_p) Change from char * to unsigned char
+       *.
+       (ascii_close_page) char * to unsigned char *.
+
+       * cmdline.c: (parse_command_line) Implement -r option by
+       prepending ~/.pspp/rc to the list of files to process.
+
+       * command.c: (cmd_remark) Reset getl_prompt to the standard prompt
+       before pulling in a final line.
+       (null_func, null_int_func) Removed (dead code).
+
+       * descript.q: (display) Calculate width of variable name column
+       properly.  Calculate number of valid cases properly.  Reported by
+       palme@uni-wuppertal.de (Hubert Palme).
+
+       * filename.c: (init_filename) Use default_config_path instead of
+       now obsolete CONFIG_PATH.
+
+       * getline.c: (getl_initialize) Use include_path instead of now
+       obsolete INCLUDE_PATH.
+       (getl_add_file) New argument `where'.  All references changed.
+
+       * groff.c: (find_font_file) Use groff_font_path instead of now
+       obsolete GROFF_FONT_PATH.
+       
+       * postscript.c: (find_ps_file) Use groff_font_path instead of now
+       obsolete GROFF_FONT_PATH.  Copy through temporary variable to
+       avoid problems with constness.
+
+       * str.h: (macro cs_streq) New macro.
+
+       * version.h: (glob var default_config_path, include_path,
+       groff_font_path) New vars.
+       
+1998-02-23  Ben Pfaff  <blp@gnu.org>
+
+       * Many source files: Change verbose_msg() priority levels and
+       messages.
+
+       * aggregate.c: Include debug-print.h.
+
+       * cmdline.c: (parse_command_line) Add --safer/-s and --command/-c
+       options.
+       (static var pre_syntax_message) Document --safer/-s and
+       --command/-c.
+
+       * command.c: (cmd_erase, cmd_host) Disable if set_safer is set.
+
+       * dfm.c: (open_inline_file) [__CHECKER__] Zero out ext->file,
+       because it's not used but it's still copied.
+       (open_file_r) Remove gratuitous debug message.
+
+       * filename.c: (safety_violation) New function.
+       (open_file) Remove gratuitous debug messages.  Don't allow pipe
+       files if set_safer is set.
+
+       * get.c: Turn off debugging.
+
+       * getline.c: (getl_add_virtual_file) New function.
+       (getl_read_line) Add verbose_msg() call for opening new syntax
+       file.
+       (getl_perform_delayed_reset) Add a return value describing whether
+       any action was taken.  Call reset_eof().
+
+       * getline.h: Comment fix.
+
+       * groff-font.c: (groff_read_font) Use `goto next_iteration' in
+       place of incorrect `continue'.  Use strtok_r() instead of
+       strtok().  Always check strtok_r() return value.
+       (groff_read_DESC) Use strtok_r() instead of strtok().
+
+       * lexer.c: (reset_eof) New function.
+
+       * main.c: (parse) Get a token after performing a delayed reset
+       action; allow empty syntax files.
+
+       * postscript.c: (output_encodings) Use strtok_r() instead of
+       strtok().
+
+       * q2c.c: (dump_parser) Use strtok_r() instead of strtok().
+
+       * set.q: Comment fixes.
+       (glob var set_safer) New var.
+       (internal_cmd_set) Support SAFER.
+
+       * str.h: [!HAVE_STRTOK_R] Declare strtok_r() prototype.
+
+       * temporary.c: (free_dictionary) Set d->splits to NULL after
+       freeing.
+
+       * vars-atr.c: (clear_variable) Decrement dict->n_splits if
+       variable deleted, not if it *isn't* deleted.
+
+1998-02-16  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (array cmd_table[]) Add MATCH FILES.
+
+       * common.c: Comment fixes.
+
+       * data-list.c, dfm.c, error.c, filename.c, list.q, matrix-data.c,
+       modify-vars.c, postscript.c, sfm-read.c, sfm-write.c, tab.c:
+       Include alloca.h.  Problem reported by palme@uni-wuppertal.de
+       (Hubert Palme).
+
+       * expr-opt.c: Include str.h.  Problem reported by
+       palme@uni-wuppertal.de (Hubert Palme).
+
+       * get.c: (cmd_get) [DEBUGGING] Update v->p.get to v->get.
+       (static var mtf_by) Change from char ** to variable **.
+       (static var mtf_master) New var.
+       (mtf_merge_dictionary) New function.
+       (cmd_match_files) Init mtf_master.  Parse mtf_by according to new
+       var type.  Reorder tests properly.  Initialize file->dict.  Detect
+       TABLE= without BY=.  Read file dictionaries and merge them.  Give
+       subcommand name with IN, LAST, FIRST error messages.  Create IN,
+       LAST, FIRST variables.  Comment fixes.
+       (mtf_free) Don't free default_dict.  Free mtf_master.
+
+       * getline.c: Define getl_mode.  Change getl_buf_size to size_t
+       from int.
+       (handle_line_buffer) Cast int to size_t in comparison to avoid
+       warning.
+
+       * getline.h: Declare getl_mode extern.
+
+       * groff-font.c: (groff_read_font) Type-fix calls to getline.
+       (groff_read_DESC) Make line_size a size_t.
+       (match_tok) Parenthesize name to avoid macro expansion.
+
+       * mis-val.c: (copy_missing_values) New function.
+
+       * postscript.c: (postopen) Make buf_size a size_t.
+
+       * sfm-read.c: (dump_dictionary) Make global from static.  Print
+       variable info in parts for easier debugging with Checker.
+
+       * temporary.c: (copy_variable) Use copy_value_labels().
+       (new_dictionary) New arg: whether to copy file label, documents.
+
+       * val-labs.c: (copy_value_labels) New function.
+
+       * var.h: (enums MISSING_*) Add MISSING_COUNT.
+
+       * vars-atr.c: [GLOBAL_DEBUGGING] (force_dup_variable) New
+       function.
+       (dup_variable) Set prv_index, get.fv, get.nv.
+
+Fri Feb 13 15:38:36 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pspp_SOURCE) Add htmlP.h.
+
+       * Many source files: For ANSI-compliance, add empty statement
+       after label.  Reported by palme@uni-wuppertal.de (Hubert Palme)
+       and Micah Altman <maltman@www-vdc.fas.harvard.edu>.
+
+       * data-in.c: (parse_numeric) Some header files break on
+       -DBL_MIN_10_EXP because they get a --; add () for safety.
+       Reported by palme@uni-wuppertal.de (Hubert Palme).
+
+       * dfm.c: Idea by Dr Eberhard W Lisse <el@linux.lisse.na>.
+       (struct dfm_fhuser_ext) Change `file' from FILE * to file_ext.
+       (dfm_close) Use close_file_ext.
+       (open_inline_file) Set file.file to NULL, not file.
+       (open_file_r, open_file_w) Initialize file.file; fill in file_ext
+       struct and use open_file_ext().
+       (read_record) Use file.file.
+
+       * file-handle.q: (prepend_current_directory) Pass through special
+       filenames.
+
+       * filename.c: Only include unistd.h if HAVE_UNISTD_H.
+       (normalize_filename) Pass through special filenames.
+       (open_file, close_file) Accept pipe| and |pipe syntaxes as
+       equivalent.
+       (dirname) Rename blp_dirname() because of name conflict on some
+       OS.  All references changed.  Reported by palme@uni-wuppertal.de
+       (Hubert Palme).
+       (is_special_filename) New function.
+
+       * get.c: (GTSV_OPT*) Add GTSV_OPT_MATCH_FILES.
+       (trim_dictionary) Conditionalize some of the options on whether
+       GTSV_OPT_MATCH_FILES is in *options.
+       (rename_variables) Don't allow variables to be renamed as scratch
+       variables.
+       (MTF_*) New enum series.
+       (struct mtf_file) New struct.
+       (static vars mtf_head, mtf_tail, mtf_by, mtf_n_by, mtf_free) New
+       vars.
+       (cmd_match_files, mtf_free) New functions.
+
+       * lexer.c: (match_int) Needed parentheses around name to escape
+       macro expansion.  Reported by Micah Altman
+       <maltman@www-vdc.fas.harvard.edu>.
+
+       * print.c: Needed to include alloca.h.  Reported by Micah Altman
+       <maltman@www-vdc.fas.harvard.edu>.
+
+       * recode.c: (convert_to_double) Parenthesize -DBL_MIN_10_EXP to
+       -(DBL_MIN_10_EXP).  Reported by palme@uni-wuppertal.de (Hubert
+       Palme).
+       
+       * str.h: Include stdarg.h.  Reported by palme@uni-wuppertal.de
+       (Hubert Palme) and Micah Altman <maltman@www-vdc.fas.harvard.edu>.
+
+Thu Feb  5 00:18:21 1998  Ben Pfaff  <blp@gnu.org>
+
+       * html.c: (struct html_driver_ext) Move into htmlP.h.
+       (html_preopen_driver) Initialize cp_x, cp_y.
+       (html_submit) Implement as call to output_tab_table().
+       (change_attributes) New function.
+       (escape_string) New function.
+       (output_tab_table) New function.
+
+       * list.q: (write_all_headers) Add code for writing headers for the
+       html driver.
+       (clean_up) Write out the html close-table tag.
+       (determine_layout) Ignore html driver.
+       (list_cases) Write html data.
+
+       * som.c: (som_submit) Move more of the code into output_table().
+
+       * tab.c: (static var hit) Make a global var and rename tab_hit.
+       (static var tab_table_class) Make a global var.
+
+       * htmlP.h: New file.
+
+Tue Feb  3 16:12:18 1998  Ben Pfaff  <blp@gnu.org>
+
+       * dump-sysfile.c: Removed.
+
+       * html.c: (preclose) Change comment in emitted code.
+
+       * matrix-data.c: Debugging off by default.  Comment fixes.
+       (static var container) New var.
+       (cmd_matrix_data) Create and destroy container.  Initialize
+       is_per_factor[] to 0s.  Move code into new function
+       string_to_content_type().  Require split values to be present in
+       the data when ROWTYPE_ is explicit.  Call specific function, not
+       general read_matrices().
+       (string_to_content_type) New function.
+       (context) Exclude all whitespace, not just spaces.
+       (mget_token) A dot is a number.  Add assertion.
+       (static var data) Renamed nr_data.
+       (static var factor_values) Renamed nr_factor_values.
+       (read_matrices) Renamed read_matrices_without_rowtype().  Handle
+       only specific case.  Close data_file before exit.
+       (fill_matrix) New function.
+       (read_data_lines) Renamed nr_read_data_lines().  Remove debug
+       printing.  Style fixes.  Message fixes.  Move code into
+       fill_matrix().
+       (read_matrices_without_rowtype) Rename
+       matrix_data_read_without_rowtype().  Fix off-by-one error on
+       loops.  Allocate nr_data[] memory from arena.
+       (read_matrices_with_rowtype) Removed.
+       (read_splits) Renamed nr_read_splits().  Style fixes.
+       (read_factors) Renamed nr_read_factors().
+       (dump_cell_content) Comment fixes.  Arguments changed.  Change
+       debug printing.  All references changed.
+       (output_data) Renamed nr_output_data().
+       (static var wr_content) New var.
+       (struct factor_data) New struct.
+       (static var wr_data) New var.
+       (static var wr_current) New var.
+       (matrix_data_source_destroy_source) Removed.
+       (read_matrices_with_rowtype) New function.
+       (matrix_data_read_with_rowtype) New function.
+       (wr_read_splits) New function.
+       (compare_factors) New function.
+       (wr_output_data) New function.
+       (wr_read_rowtype) New function.
+       (wr_read_factors) New function.
+       (wr_read_indeps) New function.
+       (glob var matrix_data_source) Make destroy_source member NULL as
+       well.
+
+Fri Jan 23 00:09:08 1998  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (syntax_error) Give better error message when at end of
+       file.
+
+       * matrix-data.c: (var content_names[]) Fix PROX spelling.  Change
+       N_SCALAR to output as plain N.
+       (mdump_token) Change output format.
+       (context) Fix message output interaction with spaces in input.
+       (another_token) New function.
+       (force_eol) Improved error message.
+       (static var max_cell_index) New var.
+       (read_matrices) Init `cells'.  factor_values is now per-cell.
+       Init max_cell_index.
+       (read_data_lines) Replace `compare' local with new `compare' arg.
+       Debugging messages changed.  Only read factors if per_factor.
+       Propagate error return from read_factors(), force_eol().
+       Copy N_SCALAR values across the N vector.
+       (read_matrices_without_rowtype) Don't init `cells'.  Don't need to
+       check parentheses manually since we now have is_per_factor[].
+       Call read_data_lines() with new args.  Check for end of data after
+       looping, using another_token().
+       (read_factors) Arguments changed.  Use max_cell_index to determine
+       whether to read or compare factors.  Message fixes.
+       (dump_cell_content) New function.
+       (output_data) Completely rewritten because content types were
+       supported to be nested inside factor values, not vice versa.
+       
+Thu Jan 22 00:26:38 1998  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (syntax_error) Support formatted varargs messages.
+
+       * matrix-data.c: Turn debugging on by default.
+       (static content_type[]) New array.
+       (static content_names[]) New array.
+       (static rowtype_, varname_) New vars.
+       (static is_per_factor[]) New array.
+       (static split_values) Moved declaration.
+       (static n_continuous, first_continuous) New var.
+       (cmd_matrix_data) Don't init split_values.  Assign ROWTYPE_ to
+       rowtype_.  Simplify SPLIT code.  Init is_per_factor[].  Assign
+       VARNAME_ to varname_.  Initialize first_continuous, n_continuous.
+       Check for continuous variables.
+       [DEBUGGING] (debug_print) Remove content_names[].
+       (mdump_token) New macro.
+       (mget_token_dump) New function.
+       (mdump_token) New function.
+       (context) New function.
+       (mget_token) Fix messages.
+       (static var data, split_values, factor_values) New vars.
+       (read_matrices) Manage split_values, factor_values.
+       (read_data_lines) New function.
+       (read_matrices_without_rowtype) Implemented.
+       (read_splits) Message fixes.  Uses `just_read'.
+       (read_factors) New function.
+       (output_data) New function.
+       (matrix_data_source_destroy_source) Close the file handle.
+       (glob var matrix_source) Change name from "DATA LIST" to "MATRIX
+       DATA".
+
+       * str.c: (strpadcmp) Removed.
+
+       * vfm.c: (dump_splits) Initialize i; fix test for end of splits.
+
+Sun Jan 18 00:30:59 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Lots of source files: Add cast to unsigned character to calls to
+       tolower() and toupper().
+
+       * aggregate.c: Set default_dict.splits to NULL.
+
+       * command.c: (static variable tab[]) Add MATRIX DATA.
+
+       * data-in.c: Add debugging defines.  Formatting fixes.
+
+       * expr-opt.c: Formatting fixes.
+
+       * lexer.c: (syntax_error) Message fixes.
+
+       * matrix-data.c: New enum series.
+       (static vars fmt, section, diag, explicit_rowtype, signle_split,
+       split_values, n_factors, factors, cells, pop_n, contents,
+       n_contents) New vars.
+       (cmd_matrix_data) Finished implementation.
+       (compare_variables_by_mxd_vartype) New function.
+       [DEBUGGING] (debug_print) New function.
+       (static vars mtoken, mtokstr, mtoklen, mtokval) New vars.
+       (read_matrices) New function.
+       (read_matrices_without_rowtype) New function.
+       (read_matrices_with_rowtype) New function.
+       (read_splits) New function.
+       (mget_token) New function.
+       (force_eol) New function.
+       [0] (test_tokenizer) New function.
+       (matrix_data_source_destroy_source) New function.
+       (glob var matrix_data_source) New var.
+
+       * misc.h: Include ieeefp.h if present.
+
+       * split-file.h: (cmd_split_file) Changes corresponding to struct
+       dictionary changes.
+
+       * str.h: Fix memmem prototype.
+
+       * temporary.c: (save_dictionary, restore_dictionary,
+       free_dictionary) Changes corresponding to struct dictionary
+       changes.
+
+       * var.h: (MXD_* enums) New enum series.
+       (struct matrix_data_proc) New struct.
+       (struct split) Removed.
+       (struct dictionary) Changed `splits' member from `split *' to
+       `variable **'.
+       (macro force_create_variable) New macro.  Replaced lots of
+       create_variable()/assert() calls with calls to this macro.
+
+       * vars-atr.c: (discard_variables) Changed assertion.
+       [GLOBAL_DEBUGGING] (force_create_variable) New function
+       called by the macro of the same name.
+       (clear_variable) Changes to delete splits from the dictionary
+       corresponding to struct dictionary changes.
+
+       * vars-prs.c: (parse_variables) [GLOBAL_DEBUGGING] Check for
+       corrupted variable `index' values in the dictionary passed in
+       every time this function is called.
+
+       * vfm.c: (dump_splits, SPLIT_FILE_procfunc) Changes corresponding
+       to struct dictionary changes.
+
+Tue Jan 13 23:45:02 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pspp_SOURCES) Add matrix-data.c.
+
+       * command.c: New includes.
+       (static array cmd_table[]) Add ERASE, HOST, NEW FILE.
+       (cmd_erase) New function.
+       [unix] (shell) New function.
+       (run_command) New function.
+       (cmd_host) New function.
+       (cmd_new_file) New function.
+
+       * expr-prs.c: (parse_primary) Message fix.
+
+       * inpt-pgm.c: Formatting fix.
+       (cmd_reread) Implement the FILE subcommand.
+
+       * matrix-data.c: New file.
+
+       * q2c.c: (dump_header) Change output commenting style.
+
+       * weight.c: Comment fix.
+
+Tue Jan 13 00:53:39 1998  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (buf64_10x) Renamed buf64_1xx, all references
+       changed.
+       (buf_10x) Renamed buf_1xx, all references changed.
+       (cmd_aggregate) Implemented cases 010, 011, 110, and 111 (all
+       cases now implemented).
+       (create_sysfile) New function.
+       (agr_11x_func) New function.
+
+       * data-in.c: (parse_numeric) Work properly if there's an
+       explicitly coded decimal point in the data and decimal places are
+       specified on DATA LIST.  Bug reported by Dr Eberhard W Lisse
+       <el@linux.lisse.na>.
+
+       * get.c: (cmd_get, cmd_save_internal) Allow extraneous slash
+       before file specification on GET, SAVE, XSAVE.  Bug reported by Dr
+       Eberhard W Lisse <el@linux.lisse.na>.
+
+       * q2c.c: [!HAVE_STRERROR] Include misc/strerror.c, not
+       strerror.c.  Bug reported by Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       * sort.c: Include sort.h.  Comment fixes.  A few esthetic fixes.
+       (static var separate_case_tab) New var.
+       (cmd_sort_cases) Cancel temporary transformations here.  Free
+       v_sort before return.
+       (sort_cases) Run an EXECUTE procedure if SEPARATE is nonzero and
+       we're reading from a sort stream.  Don't cancel temporary
+       transformations.  Offload internal sorting to do_internal_sort().
+       (do_internal_sort) New function.  Handles internal sorting even
+       when SEPARATE is nonzero.  Doesn't free v_sort.
+       (do_external_sort) Take new arg SEPARATE.  Only destroy `x' if
+       it's non-NULL.
+       (write_initial_runs) Take new arg SEPARATE.  Only destroy the old
+       sink if SEPARATE is zero.
+       (read_output_cases) Renamed read_sort_output(), all references
+       changed.  Now uses separate_case_tab when it exists.
+       (write_separate) New function.
+
+       * vfm.c: (page_to_disk) Destroy memory_source_cases, not
+       memory_sink_cases.  Don't redundantly call
+       vfm_source->destroy_source().
+       (memory_stream_mode) After switching over, set memory_sink_cases
+       to NULL.
+
+Sat Jan 10 23:35:51 1998  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: (struct agr_var) Expand dbl[] array from 2 to 3
+       elements.
+       (static var prev_case) New, moved out of aggregate_single_case()
+       local scope.
+       (static var buf64_10x, buf_10x) New.
+       (cmd_aggregate) Initialize prev_case.  Comment fixes.  Implement
+       the 000, 001, 100, and 101 cases.  Free prev_case.
+       (parse_aggregate_functions) Disallow scratch variables.
+       (free_aggregate_functions) Only free agr_dict if non-null.  Use
+       iter->function to determine numeric/string type, not
+       iter->src->type.
+       (aggregate_single_case) Don't manage prev_case.  Initialize
+       aggregate info after dumping it.
+       (accumulate_aggregate_info) Fix sum, weighted sum, mean, weighted
+       mean, stddev, weighted stddev definitions.
+       (dump_aggregate_info) Implemented.
+       (initialize_aggregate_info) Renamed from
+       initialize_aggregate_functions().  Initializes dbl[2].
+       (agr_00x_trns_proc, agr_00x_end_func, write_case_to_sfm,
+       agr_10x_trns_proc, agr_10x_trns_free, agr_10x_end_func) New.
+
+       * cases.c: (alloc_val) Removed.
+
+       * get.c: (cmd_save_internal) Initialize new `dict' member.
+
+       * sfm-write.c: (sfm_write_dictionary, write_header,
+       write_variable, write_value_labels, write_documents) Reorganize,
+       simplify for new parameter structure.
+       (write_variable) Only one variable * argument now.
+
+       * sfm.h: (struct sfm_write_info) Removed `pri', `sec', and
+       replaced by new `dict' member.
+
+       * temporary.c: (new_dictionary) Initialize n_documents.
+
+       * vars-atr.c: (dup_variable) Allocate `value's from dict into
+       v->fv manually.
+       (init_variable, replace_variable) Eliminate usage of alloc_val().
+
+       * vars-prs.c: (parse_DATA_LIST_vars) Accept PV_NO_SCRATCH option.
+
+       * vfm.c: (arrange_compaction) Allow `temporary' value of 2 to
+       signal that AGGREGATE is to be used for forming final cases.
+       (close_active_file) Call end_func before stopping lagging.  Cancel
+       temporary after finishing compaction.
+       (write_case) Comment fixes.  Cleaned up.
+       (compact_case) Let AGGREGATE handle compaction when `temporary' is
+       2.
+
+Sat Jan 10 02:10:47 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (BUILT_SOURCES) Add means.c.
+       (pspp_SOURCES) Add means.c.
+       (EXTRA_DIST) Add means.q.
+
+       * command.c: (array cmd_table[]) Add MEANS.
+
+       * common.h: Esthetic fixes.  Comment fixes.  Test for
+       MAX_SHORT_STRING greater than 8.
+       (macros LOWEST, HIGHEST) New.
+
+       * data-in.c, data-list.c, recode.c: Comment fixes.
+
+       * means.q: New file, base version.
+
+       * mis-val.c: (parse_num_or_range, parse_numeric) Replace -DBL_MAX
+       with LOWEST, DBL_MAX with HIGHEST.
+
+       * q2c.c: (dump_vars) Add an enum to array types giving the number
+       of values for the enum.
+
+       * sfm-read.c: (sfm_read_dictionary, read_machine_flt64_info)
+       Replace second_lowest_value with second_lowest_flt64.
+
+       * sfm-write.c: (write_variable, write_rec_7_34) Replace
+       second_lowest_value with second_lowest_flt64.
+
+       * t-test.q: Comment fix.
+
+       * temporary.c: (restore_dictionary) Esthetic fix.
+
+       * tokens.h: (force_match_id, force_match, force_string, force_int,
+       force_num, force_id) Replace msg() with syntax_error().
+
+       * var.h: (struct means_proc) New.
+       (struct variable) Add mns member to `p' union.
+
+       * vars-prs.c: (parse_variable, parse_dict_variable,
+       parse_variables, parse_DATA_LIST_vars) Replace msg() with
+       syntax_error().
+
+Thu Jan  8 22:28:41 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pspp_SOURCES) Add tab.h.
+
+       * Most source files: Added a cast to unsigned char in usages of
+       the ctype is*() functions.  Replaced `end of command expected'
+       calls to msg() with calls to syntax_error().
+
+       * frequencies.q: (dump_condensed) Fix tab_dim() column reference.
+
+       * lexer.c: (hex_val) Removed (was dead code).
+       (idmatch) Parenthesize function name to avoid macro expansion.
+
+       * postscript.c: Comment fixes.
+       (ps_preopen_driver) Change default font size to 10pt.
+
+       * sfm-read.c: (read_variables) Byteswap sv.print, sv.write as
+       int32s.
+       (parse_format_spec) Change system-file format spec argument type
+       to int32.  Parse the format spec with bitwise operators.
+
+       * sfmP.h: (struct sysfile_format) Removed.
+       (struct sysfile_variable) Changed print, write members from
+       sysfile_format to int32.
+
+       * tokens.h: Esthetic fixes.
+       [__GNUC__] (macro id_match) New macro to hopefully speed up
+       identifier matching.
+       (macros match_id, match_tok, match_int) Implemented in
+       compiler-independent manner; no longer GNU C only.
+
+       * vfm.h: Include time.h.
+
+Mon Jan  5 11:06:15 1998  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: (dump_fixed_table) Change tab_dim().
+
+       * dump-sysfile.c: (open_sysfile) Fix mmap() call.
+
+       * error.c: Include command.h.
+
+       * frequencies.g: Formatting fixes.
+
+       * frequencies.q: Add tab_dim() calls.  Make the total cell a
+       joined cell.
+
+       * glob.c: Include command.h.
+
+       * sfm-read.c: (struct sfm_fhuser_ext) New members sysmis, highest,
+       lowest.
+       (sfm_read_dictionary) Initialize sysmis, highest, lowest.
+       (sfm_read_machine_flt64_info) Update sysmis, highest, lowest.
+       (read_variables) Byteswap sv.type; byteswap sv.print, sv.write as
+       the other elements (is this right?).
+       (read_variables) Use lowest, highest members.
+       (parse_format_spec) New arg `vv' for more stringent checking.
+       (dump_dictionary) Byteswaps nonexplicit data.
+       (sfm_read_case) Byteswap numeric data.
+
+       * som.c: Initialize table_num to 1.
+       (render_segments) Remember to increment y_index after each table
+       segment.
+
+       * sysfile-info.c: (cmd_sysfile_info) Change tab_dim().  Don't call
+       avl_count() on a NULL tree.  No title for the second table.
+       (cmd_display) Handle DISPLAY VECTORS by calling display_vectors().
+       Handle AS_SCRATCH as AS_NAMES.  Warn if no variables.  Re-enable;
+       fix call to display_variables().
+       (display_variables) Default to 4 columns, not 3.  Set up headers.
+       Column title is Variable, not Name.  Fix index column.
+       Add joint text.  Add tab_dim().  Handle value labels properly.
+       Handle DISPLAY LABELS properly.  Draw boxes correctly.
+       (describe_variable) Value labels don't need titles.  Don't clear
+       nonexistent index column.
+       (compare_vectors_by_name) New function.
+       (display_vectors) New function.
+
+       * tab.c: (tab_height) Add assertion.
+       (tab_null) Add debug code.
+       (evaluate_dimensions) Add debug code.
+
+       * var.h: (struct variable) get_proc data is sometimes used
+       simultaneously with other per-procedure info, therefore it was
+       removed from the union.  All references changed.        
+
+Sun Jan  4 18:13:33 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_close_page) Put title on second line of headers
+       if there is no subtitle.
+
+       * command.c: (glob var cur_proc) Move definition here, from
+       common.c.
+       (cmd_remark) Emit blank line before remarks.
+
+       * command.h: (glob var cur_proc) Move declaration here, from
+       common.h.
+
+       * data-list.c: (dump_fixed_table) Fix messages.
+       (dump_free_table) Call tab_nat_dim().
+
+       * descript.q: (dump_z_table) Modify tab_dim() call.
+
+       * frequencies.q: (dump_condensed, dump_statistics) Add tab_dim()
+       call.
+       (dump_statistics) Don't output header.
+
+       * groff-font.c: Minor format fix.
+
+       * html.c: Comment fix.
+
+       * list.q: (write_varname) Indent after advancing page.
+
+       * output.h: Minor reordering.
+
+       * postscript.c: Comment fixes.  Many places, '\n' was replaced by
+       a reference to eol[].
+       (struct ps_driver_ext) New member eol[].
+       (ps_preopen_driver) Initialize eol[].
+       (ps_postopen_driver) Fix sense of text for text_opt, line_opt
+       defaults.  Handle headers.  Fix test for minimum page length.
+       (static var option_tab[]) Add `line-ends'.
+       (ps_option) Handle line-ends to change eol[].
+       (postopen) Scale prop_em_width and fixed_width properly.  Set the
+       prologue title to outp_title if applicable.  Replace the prologue
+       line ends with eol[].  Call draw_headers() if headers are enabled.
+       (text_width) New function.
+       (out_text_plain) New function.
+       (draw_headers) New function.
+
+       * print.c: (dump_table) Call tab_nat_dim().
+
+       * som.c: (som_blank_line) Only advance a line if not at the top of
+       a page.
+       (som_submit) Move several informational table calls here.
+       Increment subtable_num if SOMF_NO_TITLE not set.
+       (output_table) Advance a line if SOMF_NO_SPACING not set.
+       (render_columns, render_segments, render_simple) Handle spacing
+       between tables.  Handle table titles.  Remove debug output.
+
+       * som.h: (SOMF_*) New enum series.
+       (struct som_table_class) New member `flags'.
+
+       * sysfile-info.c: (cmd_sysfile_info) Calls tab_nat_dim().  No
+       headers or spacing.
+       (display_variables) Calls tab_nat_dim().
+       (describe_variable) Remove restriction on number of value labels.
+       Make value labels separated by thin lines.
+
+       * tab.c: (tab_create) Default `flags' to none.
+       (tab_float) New arg `w'.  All references changed.
+       (tab_nat_dim) New function.
+       (tab_output_text) No title or spacing.
+       (tab_flags) New function.
+       (tabi_flags) New function.
+       (tabi_title) New function.
+       (strip_height) Removed.
+       (tabi_render) Skip title when necessary.
+       (static var tab_tab_class) Add tabi_flags, tabi_title.
+       (evaluate_dimensions) Disable display of column, row size.
+       (sum_columns) Add title height to top header.
+       (render_strip) Moved within file.
+
+       * tab.h: (struct tab_table) New member `flags'.
+
+       * vfm.c: (dump_splits) Calls tab_nat_dim().  No title.
+
+Sat Jan  3 16:55:44 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Most source files: Add `const' attribute in all appropriate
+       places.
+       
+       * sysfile-info.c: (cmd_sysfile_info) Add tab_dim() call, add a
+       column to the variables table for use by describe_variable().
+       (cmd_display) Disable for the present.
+       (display_documents) Don't wrap documents.
+       (display_variables) Table has four columns now.
+       (describe_variable) Table has four columns now.  Don't use a
+       subtable, use joined cells instead.
+
+       * tab.c: (tab_create) Don't set `join'.
+       (tab_realloc) ct array is not made up of a_string's.
+       Reallocate trh, hrh, h arrays, initialize trh array.  Initialize
+       cell contents on GLOBAL_DEBUGGING, not DEBUGGING.
+       (text_format) New function.
+       (tab_title) Rewritten, uses text_format().
+       (tab_text) Rewritten, uses text_format().
+       (tab_joint_text) New function.
+       (tab_join) Removed.
+       (static var hit) New variable.
+       (render_strip) New args r1, r2.  Implement joined cells that fit
+       on a single page.
+       (tabi_render) Increment hit.  Pass new args to render_strip().
+       (evaluate_dimensions) [GLOBAL_DEBUGGING] Check for uninitialized
+       cells.  For t_naw and t_nah, ignore joined cells and null cells in
+       calculations.
+       
+       * tab.h: (struct tab_join_rect) Removed.
+       (struct tab_table) Removed `join'.
+       (TAB_JOIN_MAIN) Removed.
+       (struct tab_joined_cell) New struct.
+       (TAT_NOWRAP) New enum.
+
+Fri Jan  2 01:39:58 1998  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_postopen) Replace ASCII_* macros with their
+       expansions.
+       (ascii_postopen_driver) Fix initialization of *_spacing so that
+       the TAL_0 bit doesn't count.
+
+       * data-list.c: (dump_fixed_table) Use natural width for Format
+       column.
+
+       * glob.c: (rerange) Removed.
+       (get_date) Formatting fixes.  Internationalization fix.
+
+       * html.c: (html_postopen_driver) Replace HTML_DEFAULT_OUTPUT_FILE
+       with "pspp.html".
+
+       * postscript.c: (ps_postopen_driver) Replace
+       PS_DEFAULT_OUTPUT_FILE with "pspp.ps".
+
+       * som.c: (som_submit) Don't eject page before every table.
+       (output_table) Fix order of arguments on call to area().
+       (render_columns) Fix calculation of max_len.
+       
+       * tab.c: (tabi_cumulate) Minor change to increase elegance.
+       (render_strip) New function.
+       (strip_height) New function.
+       (tabi_render) Rewrite as calls to render_strip().
+
+       * tab.h: (TAT_* enums) Removed TAT_RICH, all references removed.
+       Renumbered TAT_PRINTF, TAT_TITLE, TAT_FIX to correspond better
+       with the TAB_* and OUTP_T_* constants.
+       
+Thu Jan  1 11:53:52 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Formatting fixes.
+
+       * ascii.c: (ascii_postopen_driver) Initialize *_line_spacing[],
+       *_line_width[].
+
+       * data-list.c: (dump_fixed_table) Add tab_dim() call.
+
+       * descript.q: (dump_z_table, display) Add tab_dim() calls.
+
+       * dump-sysfile.c: (glob var length) Make type off_t.
+       (usage) Fix arguments.
+       (main) Return 0.
+
+       * output.h: (OUTP_T_*) Change constants' value to match tab.h.
+       Now right-justification is the default so many references had to
+       change.
+       (struct outp_class) Removed line_width, all references changed.
+       (OUTP_DEV_*) Add OUTP_DEV_DISABLED.
+       (struct outp_driver) Add elements horiz_line_width,
+       vert_line_width, horiz_line_spacing, vert_line_spacing.  Remove
+       som element.
+
+       * postscript.c: (outp_encodings) Formatting fixes.  Fix garbage
+       collection.
+       (postopen) Initialize all the informational members of
+       outp_driver.
+
+       * som.c: (som_blank_line) New function, renamed from blank_line(),
+       all references changed.
+       (som_submit) Disables drivers whose pages can't be opened.
+       (render_columns, render_simple, render_segments) Add debug output.
+       (render_columns) Fix loop range.
+       (render_simple) Don't try to render the headers, they're taken
+       care of automatically.  Advance cp_y past the table when done.
+       (render_segments) Fix loop ranges.
+
+       * tab.c: Initialize new members of tab_table.
+       (tab_vline) Handle trv[]; don't set style for spacing-only lines.
+       (tab_hline) Handle trh[]; don't set style for spacing-only lines.
+       (tab_box) Handle trh[], trv[]; don't set style for spacing-only
+       lines.
+       (set_expr) Removed.
+       (tab_dim) New function.
+       (tab_col_width) Removed.
+       (tab_row_height) Removed.
+       (tab_output_text) Call tab_dim().
+       (tabi_driver) Call evaluate_dimensions(), sum_columns().
+       (tabi_area) Implemented.
+       (tabi_cumulate) Implemented.
+       (tabi_render) Partially implemented, but broken.
+       (var tab_table_class) Made static.
+       (evaluate_dimensions) New function.
+       (sum_columns) New function.
+
+       * tab.h: (enum t_*) Now start at t_end.  New: t_ptw, t_nr, t_nc,
+       t_nah, t_naw, t_neg, t_xch, t_dup, t_lbl, t_jnz, t_sac, t_sar,
+       t_scr, t_srr, t_sentinel.  Removed: t_nat.
+       (struct tab_table) New: wl, wr, ht, hb, trh, hrh, trv, wrv, dim,
+       max_stack_height, w, h.  Removed: ce, re.
+       (macro blank_line) Removed.
+       (glob var zero_length) Removed.
+
+Fri Dec 26 15:44:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Most source files: include some of the new include files broken
+       out of var.h.
+       
+       * Makefile.am: (pspp_SOURCES) Add all the new source files to the
+       list.
+
+       * aggregate.c: (glob var outfile) Make static.
+
+       * command.c: (glob var pgm_state) Move here.
+
+       * common.c: (glob vars endian, second_lowest_value, pgmname,
+       finished, curdate, cur_proc, start_interactive, history_file) Move
+       here.
+
+       * descript.q: (structs dsc_z_score, descriptives_trns) Move here.
+
+       * file-handle.q: (glob vars files, inline_file) Move here.
+
+       * glob.c: Lost lots of glob vars, detailed in individual file
+       entries.
+       (init_glob) set_printer, set_screen were obsolete, deleted.
+       set_cprompt has fewer spaces because pspp has fewer letters than
+       fiasco.
+
+       * inpt-pgm.c: (glob vars inp_init, inp_init_size) Move here.
+       (inp_nval) Made static.
+
+       * lexer.c: (glob vars token, tokval, tokstr, tokstr_size,
+       tokstr_len, toklongstr, tokint) Move here.
+
+       * misc.c: Lost several vars and functions.
+
+       * set.q: (all the set_* variables) Move here.
+
+       * str.c: (strmaxcpy, strbarepadcpy, strbarepadlencpy, strpadcpy,
+       blpstrset, strpadcmp, memrev, memrmem, cmp_str) Move here from
+       misc.c.
+
+       * tab.c: (set_expr, tab_col_width, tab_row_height) New functions.
+
+       * tab.h: (enum series t_*) New enums.
+       (struct tab_table) Use arena struct tag.  New members ce, re.
+
+       * tokens.h: Comment fixes.
+
+       * var.h: Move lots of enums and variables and functions and
+       structures to other files.  Use and declare a lot more union and
+       struct tags.  Comment fixes.  
+
+       * vector.c: (glob vars vec, nvec) Move here.
+
+       * vfm.c: (glob vars reinit_sysmis, reinit_blanks, init_zero,
+       init_blanks, last_vfm_invocation) Move here.
+
+       * cases.h: New file.
+       (struct long_vec) Move here.
+       (vec_init, vec_clear, vec_insert, vec_delete, devector, envector)
+       Move here.
+
+       * command.h: New file.
+       (STATE_* enums) Move here.
+       (glob var pgm_state) Move here.
+
+       * format.c: New file.
+       (glob var formats) Move here.
+       (parse_format_specifier_name, fmt_to_string,
+       check_input_specifier, check_output_specifier,
+       check_string_specifier, convert_fmt_ItoO, parse_format_specifier)
+       Move here.
+
+       * format.h: New file.  Move functions now in format.c here.
+       (FMT_* enums) Move here.
+       (struct fmt_desc) Move here.
+       (FCAT_* enums) Move here.
+       (struct fmt_spec) Move here.
+       (glob vars formats, fmt_parse_ignore_error) Move here.
+
+       * inpt-pgm.h: New file.
+       (INP_* enums) Move here, make #defines into enums.
+       (glob vars inp_init, inp_init_size) Move here.
+
+       * sort.h: New file.
+       (glob vars v_sort, nv_sort) Move here.
+       (sort_cases, read_sort_output) Move here.
+
+       * vector.h: New file.
+       (struct vector) Move here, add struct tag.
+       (glob vars vec, nvec) Move here.
+       (find_vector) Move here.
+
+       * New file.
+       (glob vars last_vfm_invocation, temp_case, reinit_sysmis,
+       reinit_blanks, init_zero, init_blanks) Move here.
+       (struct case_stream) Move here.
+       (glob vars vfm_source, vfm_sink, vfm_memory_stream,
+       vfm_disk_stream, sort_stream, data_list_source,
+       input_program_source, file_type_source, get_source, n_lag) Move
+       here.
+       (procedure, write_case, lagged_case, compact_case, page_to_disk)
+       Move here.
+               
+Wed Dec 24 22:40:42 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (pspp_SOURCES) Added html.c, som.c, som.h.
+       (LDADD) Add libdcdflib.
+
+       * ascii.c: Comment and formatting fixes.  Almost every external
+       function had an assert added, checking driver_open and page_open.
+       (ascii_init_driver) Broken into ascii_preopen_driver,
+       ascii_postopen_driver, ascii_close_driver.  Manages driver_open.
+       (ascii_open_page) Sets page_open.
+       (ascii_close_page) Clears page_open.
+
+       * html.c: Comment and formatting fixes.  Almost every external
+       function had an assert added, checking driver_open and page_open.
+       (html_init_driver) Broken into html_preopen_driver,
+       html_postopen_driver, html_close_driver.  Manages driver_open.
+       (html_open_page) Sets page_open.
+       (html_close_page) Clears page_open.
+       (html_submit) Disabled.
+
+       * lexer.c: (parse_string) Remove debugging printf.
+
+       * list.q: (determine_layout) Open a page if one is not yet open.
+
+       * output.c: Comment fixes.
+       (add_class) Set the class member of the new list element.
+       (parse_options) Don't handle device type.
+       (colon_tokenize) New function.
+       (configure_driver) New four-field format with a field for device
+       type.  Now initialize driver_open, page_open, next, and prev
+       fields.  Use new colon_tokenize() function.  Don't do a memory
+       copy to replace a driver, it doesn't work; instead delete the old
+       driver and insert a new one.
+       (destroy_driver) Don't call som_destroy_driver().  Close the page
+       if it's open.  Find the class in the list of classes and decrement
+       that reference count.  Remove the driver from the global driver
+       list.
+       (outp_iterate_enabled_drivers) Renamed outp_drivers().  All
+       references changed.  Rewritten.  Don't return a driver that's not
+       enabled.
+       (outp_eject_page) All references to som_internal_eject_page()
+       changed to use this.  Sets cp_x to 0 as well as cp_y.
+
+       * output.h: (OUTP_I_* enums) Removed.
+       (struct som_submission_form) Removed.
+       (struct outp_class) init_driver broken into preopen_driver,
+       postopen_driver, and close_driver.  submit changed to take a
+       som_table argument.
+
+       * postscript.c: Comment and formatting fixes.  Almost every
+       external function had an assert added, checking driver_open and
+       page_open.
+       (ps_init_driver) Broken into ps_preopen_driver,
+       ps_postopen_driver, ps_close_driver.  Manages driver_open.
+       (ps_open_page) Sets page_open.
+       (ps_close_page) Clears page_open.
+
+       * som.c: New file, base implementation.
+       
+       * som.h: (struct som_table) Add struct tag.
+       (enum SOM_COL_ACROSS) Removed.
+       (SOM_ROWS, SOM_COLUMNS) New enums.
+       (struct som_table_class) Add member `cumulate'.  Remove `segment';
+       change `render' arguments.
+       (struct som_point, struct som_rect) Removed.
+       (som_submit_table) Fixed typo, should have been som_submit.
+
+       * sysfile-info: (describe_variable) Don't try to insert a
+       subtable; just destroy it for now.
+
+       * t-test.q: Include dcdflib/cdflib.h instead of cdflib.h.  Fix
+       references to value labels.
+
+       * tab.c: (tab_destroy) New function.
+       (tab_columns) Change argument.
+       [0] (tab_submit) Remove dead code.
+       (tab_title) Allocate string from the table's arena.
+       (tab_output_text) Only free the buffer if we allocated it.
+       (tab_submit) New function.
+       (static vars t, d) New static vars.
+       (tabi_table, tabi_driver, tabi_count, tabi_area, tabi_columns,
+       tabi_headers, tabi_cumulate, tabi_render) New functions.
+       (glob var tab_table_class) New global var.
+
+       * tab.h: (struct tab_join_rect) Don't use a som_rect; directly
+       encapsulate the rectangle.  All references changed.
+       
+Sun Dec 21 16:18:58 1997  Ben Pfaff  <blp@gnu.org>
+
+       * All header files updated to use struct tags in addition to
+       typedefs for all structures.  Don't use word `struct' in struct
+       tags.
+       
+       * Makefile.am: (pspp_SOURCES) Remove html.c.
+       (INCLUDES) Replace the lib/* includes with a single lib/ include;
+       all references updated.
+
+       * command.c: (parse_cmd) Remove call to som_check_workspace.
+       (output_line) Update to new som.
+
+       * data-in.c: (parse_numeric) A single dot is not an error; it is
+       the system-missing value.
+
+       * data-list.c: (dump_fixed_table, dump_free_table) Update to new
+       som.
+
+       * data-out.c: Added `const' as appropriate to many prototypes.
+       (convert_E, convert_F, convert_CCx) Take double argument instead
+       of value * argument.
+       (convert_format_to_string) Call changed functions appropriately.
+       Instead of modifying the caller's value for FCAT_SHIFT_DECIMAL,
+       make a local copy of the value.
+
+       * descript.q: Remove custom_variables() prototype now provided by
+       q2c.  
+       (custom_variables) Don't increment sbc_variables, the caller does
+       this.
+       (dump_z_table, display) Update to new som.
+
+       * error.c: (vmsg) Add const to prototype.  Remove code to handle
+       `too many errors' condition.
+       (check_error_count) New function.
+       (msg) Add const to prototype.
+
+       * filename.c: (open_file) Rewrite for elegance.
+
+       * frequencies.q: Remove custom_*() prototypes now provided by q2c.
+       (dump_full, dump_condensed, dump_statistics) Update for new som.
+
+       * list.q: Don't include somP.h.  Change all references to
+       som_driver_ext to refer to the new members of som_driver.  Change
+       som_internal_eject_page() references to outp_eject_page().
+
+       * main.c: (parse) Rewrite for elegance.  Add call to
+       check_error_count().
+
+       * output.c: (add_class, outp_list_classes, outp_configure_driver)
+       Rewrite or revise for new outp_driver_class_list structure.
+       (outp_iterate_enabled_drivers) Fix comparison between disabled
+       devices and current device type.
+       (outp_eject_page) New function.
+
+       * output.h: Comment fixes.
+       (struct outp_driver) New members driver_open, page_open, cp_x,
+       cp_y, font_height, prop_em_width, fixed_width.  Deleted members
+       ref_count, next.
+       (struct outp_driver_class_list) New struct.
+       (outp_class_list) Changed to type outp_driver_class_list; all
+       references updated.
+
+       * print.c: (dump_table, print_trns_proc) Updated for new som.
+
+       * q2c.c: (dump_vars) Simplify array subcommand code.  Declare
+       prototypes for custom subcommands.
+       (dump_subcommand) Always include the `else'.
+       (dump_parser) Fix comments in output code.
+
+       * set.q: Reordered functions.
+
+       * som-frnt.c, som-high.c, som-low.c, somP.h: Removed.
+       
+       * som.h: Rewritten from scratch.
+
+       * str.h: Remove dead code.
+
+       * tab.c, tab.h: New files, base implementation.
+
+       * sysfile-info.c: (cmd_sysfile_info, describe_variable) Update to
+       new som.
+
+       * t-test.q: New code from John Williams
+       <johnr.williams@stonebow.otago.ac.nz>.  Include math.h, cdflib.h.
+       Many many new static vars and defines.
+       (precalc, postcalc, g_postcalc, z_postcalc, t_pairs, t_groups,
+       groups_calc, pairs_calc, z_dev_calc, z_calc) New functions.
+       (struct value_list) New struct.
+       (variance, covariance, pooled_variance, oneway, pearson_r, f_sig,
+       t_crt, t_sig, print_t_groups) New functions.
+       (cmd_t_test) Implemented.
+
+       * temporary.c: (cancel_temporary) Only free the temp_dict if it's
+       non-NULL.
+
+       * vfm.c: (dump_splits) Update to new som.
+
+Thu Dec  4 23:02:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (fiasco_SOURCES) Add html.c.
+
+       * aggregate.c: Base source.
+
+       * ascii.c: (postopen, preclose) Reformat.
+
+       * data-out.c, expr-evl.c: Comment fixes.
+       
+       * filename.c: (open_file) When opening a file for writing, use
+       line buffering instead of full buffering for better interactive
+       performance.  Suggested by Valerio Aimale
+       <valerio@svpop.com.dist.unige.it>.  Also, recognize special file
+       names `stdin', `stdout', `stderr'.
+
+       * groff-font.c: Comment fixes.
+
+       * html.c: New file; base version.
+
+       * list.q: (write_all_headers, clean_up, determine_layout,
+       list_cases) Ignore `special' devices for now.  Needs to be fixed
+       later.
+
+       * output.c: (outp_init) Add html driver to list; reverse list
+       order.
+
+       * output.h: (struct outp_class_struct) New members `special',
+       `submit'; comment fixes.  All references changed.
+
+       * postscript.c: (ps_init_driver) Make defaults for text_opt,
+       line_opt depend on whether the OUTP_DEV_SCREEN bit is set on the
+       device.
+       (postopen) Comment fix.
+       (preclose) Comment fixes, formatting fixes.  Change x->file.file
+       references to more proper f->file.
+
+       * som-high.c: (som_submit_table) Special classes use their own
+       renderers.
+
+       * som.h: Comment fixes.
+
+       * temporary.c: (new_dictionary) Don't try to xstrdup() a NULL
+       string.
+       
+Tue Dec  2 14:36:07 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (fiasco_SOURCES) Add aggregate.c back in.
+
+       * aggregate.c: Still working on this.
+
+       * command.c: (cmd_table[]) Add AGGREGATE back in.
+       (split_words) Make '-' a legal word separator as well as ' '.
+
+       * main.c: Comment fixes.
+
+       * q2c.c: (dump_parser) Don't require the procedure's full name to
+       be present, in the generated source.
+
+       * t-test.q: Change name to `t-test' from `t test'.  Let PAIRS be
+       multiply specified and let it be default; let MISSING, CRITERIA,
+       FORMAT be multiply specified.
+       (cmd_t_test) Parse command name.  [DEBUGGING] Call debug_print().
+       (custom_groups) Fix defaults.
+       (custom_pairs) Check whether this is a PAIRS subcommand before
+       attempting to parse.  Better garbage collection.  Proper storage
+       allocation.
+       [DEBUGGING] (debug_print) New function.
+
+       * temporary.c: Comment fixes.
+       (copy_variable) Don't copy variable name and index.
+       (save_dictionary) Copy variable name and index by hand.
+
+       * vars-atr.c: Comment fixes.
+       (create_variable) New dictionary argument.  All references
+       changed.
+       (common_init_stuff) New dictionary argument.  All references
+       changed.
+       (init_variable) New dictionary argument.  All references changed.
+       (dup_variable) New function.
+
+       * vars-prs.c: (parse_variables) If there are any errors, we always
+       return 0.  Previously, it was possible for some types of errors to
+       be ignored.
+       
+Sat Nov 22 01:20:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (fiasco_SOURCES) For 0.1.5 release, remove
+       aggregate.c.
+
+       * command.c: (cmd_table[]) Comment out AGGREGATE; add T TEST.
+
+       * list.q, t-test.q: Remove ALL option from VARLIST declaration in
+       grammar rules.
+
+       * q2c.c: Comment fixes.
+       (SBC_* enums) Remove SBC_VARLIST_ALL; all references removed.
+       
+       * t-test.q: (cmd_list) Rename cmd_t_test.
+
+       * temporary.c: (new_dictionary) Don't declare as static.
+       
+Fri Nov 21 00:03:06 1997  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: Changes, still not finished.
+
+       * file-handle.q, frequencies.q, list.q, set.q: Comment fixes.
+
+       * q2c.c: Comment fixes.  Now its output is internationalized.
+       (get_token) Fix parsing of escapes within literal strings.
+       (main) Fix bad #line directives in output.
+
+       * t-test.q: Base implementation.
+
+       * temporary.c: (new_dictionary) New function.
+       (restore_dictionary) [__CHECKER__] Change fill character to *
+       (from @).
+       
+Sun Nov 16 01:29:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (BUILT_SOURCES, fiasco_SOURCES) Add t-test.c
+
+       * aggregate.c: Changes, still not finished.
+
+       * descript.q, list.q: Comment fixes.
+
+       * q2c.c: Almost completely rewritten.
+
+       * t-test.q: New file, not complete.
+
+Fri Nov 14 00:14:48 1997  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.c: Changes, still not finished.
+
+       * sort.c: (sort_cases) Call cancel_temporary() instead of doing it
+       by hand.
+
+       * temporary.c: (cancel_temporary) New function.
+
+       * vars-atr.c: (discard_variables) Call cancel_temporary() instead
+       of doing it by hand.
+
+       * vfm.c: (close_active_file) After restoring a TEMPORARY
+       dictionary, set temp_dict to NULL.  Cancel TEMPORARY through
+       cancel_temporary().
+       (SPLIT_FILE_procfunc) Comment fix.
+
+Tue Oct 28 16:08:45 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (fiasco_SOURCES) Add aggregate.c.
+
+       * aggregate.c: New file, not finished yet.
+
+       * command.c: (cmd_table) Add AGGREGATE.
+
+       * common.h: (pgm_state) Move declaration to var.h.
+
+       * lexer.c: (bin_value_func, oct_value_func, hex_value_func) i18n
+       fixes.
+       (parse_string) Message fix.
+
+       * recode.c: Comment fix.
+
+       * sfm-read.c: (read_variables) Code esthetic fixes.
+       (write_header) Default date is `Jan', not `JAN'.
+
+       * sfmP.h: (bswap_int32) [!__linux__] Fix off-by-one errors.
+
+       * sort.c: (cmd_sort_cases) Farm the work out to new function
+       parse_sort_variables().
+       (parse_sort_variables) New function.
+       (sort_cases) New function.  Cancels temporary transformations,
+       which sorting didn't do previously.
+       (cmd_sort_cases) Better garbage collection on error.  Uses
+       do_external_sort().
+       (write_initial_runs, merge_once) Improved code esthetics.
+       (sort_stream_read) Reduced to one call to read_output_cases().
+       (read_output_cases) New function.
+
+       * var-labs.c: (cmd_variable_labels) Re-enabled truncation of
+       variable labels to 120 characters.
+
+       * var.h: Comment fixes.
+       (glob var pgm_state) From common.h.
+
+       * vars-atr.c: (discard_variables) Set pgm_state to STATE_INIT.
+
+       * vars-prs.c: (parse_DATA_LIST_vars) Support PV_SINGLE in
+       options.  Set *names to NULL on error.
+
+       * vfm.c: (memory_stream_init) Assert compaction_nval != 0.
+
+Thu Oct  9 09:59:49 1997  Ben Pfaff  <blp@gnu.org>
+
+       * sfm-write.c, vfm.c: [HAVE_UNISTD] #include <unistd.h>, needed by
+       SunOS4.  From Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+Wed Oct  8 18:55:24 1997  Ben Pfaff  <blp@gnu.org>
+
+       * vfm.c: (page_to_disk) Added missing local variables.
+
+Tue Oct  7 20:23:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Comment fix.
+
+       * sort.c: (cmd_sort_cases) Attempt to perform internal sort if the
+       source is anything other than a disk stream, not just if it's in a
+       memory stream.  Call page_to_disk() before external sort.
+       (allocate_cases) Message fix.
+
+       * vfm.c: (prepare_for_writing) Warn user when paging workspace to
+       disk.
+       (page_to_disk) New function.
+
+Sun Oct  5 15:56:14 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (INCLUDES) Include .. instead of $(top_srcdir).
+
+       * common.h: (macro strerror) Remove.  From Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       * get.c: (dict_delete_run) The number of variables to delete is
+       not necessarily the number of variables that need to be shifted
+       up.
+       (trim_dictionary) Don't set *options to 0.  Fix bug that caused
+       too many variables to be deleted.
+
+       * postscript.c: Comment fix.
+
+       * q2c.c: Include strerror.c.  From Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       * set.q: #undef ON and OFF.  From Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       * sfm-read.c: (sfm_read_dictionary) Don't set the file class too
+       early, otherwise errors cause a bad free().
+
+       * str.h: (macro nvsprintf) s/FORMATS/FORMAT/ typo.  From Alexandre
+       Oliva <oliva@dcc.unicamp.br>.
+
+       * temporary.c: (save_dictionary) Don't allocate memory if
+       n_documents is 0.
+
+       * vfm.c: (memory_stream_write) Message fix.
+
+Sat Oct  4 16:20:43 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (static var cmd_table[]) Define REPEATING DATA
+       command.
+
+       * common.h: Added support for broken systems that are missing
+       EXIT_SUCCESS, EXIT_FAILURE, RAND_MAX, and/or strerror().
+
+       * Many source files: Replace syntax error messages via msg() with
+       call to syntax_error().
+
+       * data-list.c: (dump_fixed_table) Add support for dumping table
+       for REPEATING DATA as well as DATA LIST FIXED.
+       (cmd_repeating_data) Allows and requires `/' between subcommands.
+       Does proper thing with allowing rpd.starts_end to stay 0.  Allows
+       CONTINUED specifications to be omitted.  Forces CONTINUED to be
+       specified if ID is.  Calculates starts_end, cont_end from logical
+       record length as reported by fhp.  Calls dump_fixed_table() if
+       requested.  Fixed length of record copied by memcpy.
+       (parse_num_or_var) Sets `num' to 0, not NOT_INT, for variables.
+       Message fix.
+       (realize_value) Returns sensible value for out-of-range variable
+       values.
+       (rpd_parse_record) New argument `ofs'.  Fixed confusion between
+       length of occurrences and length of line.  Added warning for
+       fields that exceed the line length.  Fixed infinite loop.
+       (read_one_set_of_repetitions) Numerous minor changes for more
+       complete SPSS compliance.  Message fixes.
+
+       * dfm.c: (dfm_close) If the file being closed is the inline file,
+       read all the remaining data before closing it.
+       (dfm_get_record) Don't close the file on lossage, as either it
+       has been closed already or it doesn't belong to us.
+
+       * error.c: (puts_stdout) New function.
+       (vmsg) Use puts_stdout instead of puts.
+
+       * file-handle.q: (fh_record_width) New function.
+
+       * inpt-pgm.c: (init_case) Fixed buffer overrun when inp_nval % 4
+       == 0.
+       (clear_case) Ditto.
+       (input_program_source_read) Made an old kluge an approved method.
+
+       * lexer.c: (syntax_error) New function.
+
+       * misc.c: [BROKEN_RAND] (ansi_rand, ansi_srand; static var next)
+       New.
+
+       * output.c: (oupt_get_paper_size) Message fix.
+
+       * q2c.c: Numerous fixes to formatting of generated code made to
+       conform to GNU coding standards.  Uses syntax_error() in generated
+       code.  Other miscellaneous generated message fixes.  Added support
+       for broken systems that are missing EXIT_SUCCESS, EXIT_FAILURE,
+       RAND_MAX, and/or strerror().
+
+Sat Oct  4 02:09:56 1997  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: Comment fixes.
+
+       * data-list.c: (struct repeating_data_trns) New member `id_spec'.
+       (find_variable_input_spec) New function.
+       (cmd_repeating_data) Initializes id_spec.
+       (rpd_parse_record) Implemented.
+       (read_one_set_of_repetitions) Returns -3 by default in order to
+       kluge out some potential bugs.
+
+       * data-out.c: Comment fixes.
+
+       * file-type.c: (internal_cmd_record_type) Message fix.
+
+       * inpt-pgm.c: (input_program_source_read) Special temporary kluge
+       for handling -3 return value.
+
+Sat Sep 20 23:58:15 1997  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: Comment fixes.
+       (struct dls_var_spec) Reordered members.
+       (read_from_data_list_fixed) Restructured.
+       (struct repeating_data_trns) Reordered members.  Renamed `starts'
+       as `starts_beg', `ends' as `starts_end'.
+       (cmd_repeating_data) Calculates length of repeated data if
+       necessary and possible.
+       (parse_num_or_var) Don't allow string variables.
+       (realize_value) New function.
+       (rpd_msg) New function.
+       (rpd_parse_record) New function.  Currently stubbed out.
+       (read_one_set_of_repetitions) Implemented.
+
+       * inpt-pgm.c: (input_program_source_read) Comment fix.
+
+Thu Sep 18 21:34:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (cmd_end_repeat_p) Removed.
+       (init_cmd_parser) Doesn't set cmd_end_repeat_p.
+       (parse_cmd_name) Removed.
+
+       * data-list.c: Comment fixes.
+       (data_list_pgm) Removed `eof' member.
+       (static var first) New var.
+       (cmd_data_list) Sets `first'.  Ensures that DATA LIST uses the
+       FILE TYPE file inside FILE TYPE structures.
+       (append_var_spec) Appends to *first, not dls.spec.
+       (parse_fixed) Message fixes.
+       (struct rpd_num_or_var) New.
+       (struct repeating_data_trns) New.
+       (static var rpd) New.
+       (cmd_repeating_data) New function.
+       (parse_num_or_var) New function.
+       (parse_repeating_data) New function.
+       (read_one_set_of_repetitions) New function.
+
+       * file-type.c: (cmd_file_type) Message fixes.  Always
+       default_handle to FILE TYPE file handle.
+       (internal_cmd_record_type) Message fixes.
+
+Wed Aug 20 14:22:03 1997  Ben Pfaff  <blp@gnu.org>
+
+       * repeat.c: Comment fix.  Disable debugging.
+
+       * temporary.c: (restore_dictionary) Sets splits to NULL and
+       n_splits to 0 before destroying the variables because now doing
+       this tries to remove split variables.
+
+       * vars-atr.c: (discard_variables) Asserts that n_splits is 0 after
+       destroying the dictionary.
+       (clear_variable) Removes a variable from splits after destroying
+       it.
+
+Mon Aug 18 18:06:55 1997  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: (set_compat) Removed.
+       (pick_compat) Removed.
+       (parse_command_line) Removed -c option.
+       (pre_syntax_message) Removed -c option.
+       (usage) Remove compatibility code.
+
+       * common.h: (macros VER_PC, VER_WND, VER_X) Removed.
+       (glob var compat) Removed.
+
+       * compute.c: (type_check) Fixed messages about type mismatches.
+
+       * data-list.c: (cmd_data_list) Removed compatibility code.
+       (fixed_parse_compatible) Calls convert_negative_to_dash().
+       Fixed bug where it only set the variable in fx.spec if it created
+       the variable itself.
+       (dump_fmt_list) Spelling fix.
+       (cut_field) Removed compatibility code.
+
+       * dfm.c: (cmd_begin_data) Don't require a command terminator on
+       BEGIN DATA command.
+
+       * expr-evl.c: (evaluate_expression) Implement LAG.
+
+       * expr-prs.c: (parse_add) Calls convert_negative_to_dash().
+       (parse_neg) Calls convert_negative_to_dash().
+       (LAG_func) Increases n_lag to the lag requested.  Fixed assignment
+       bug.
+
+       * expr.h: (struct expression_struct) Removed member max_lag.
+
+       * file-type.c: (parse_col_spec) Calls convert_negative_to_dash().
+       (internal_cmd_record_type) Removed special handling to produce
+       negative numbers from dash tokens.
+
+       * getline.c: (static var DO_REPEAT_level) New var.
+       (getl_add_DO_REPEAT_file) Increments DO_REPEAT_level.
+       (handle_line_buffer) Copies the line into getl_buf; doesn't call
+       copy_with_DO_REPEAT_substitutions().
+       (getl_read_line) Maintains value of getl_mode.  Calls
+       perform_DO_REPEAT_substitutions() whenever DO_REPEAT_level is
+       positive.
+       (getl_close_file) Decrements DO_REPEAT_level when appropriate.
+
+       * getline.h: (getl_mode) New glob var.
+
+       * glob.c: Comment fixes.
+       (init_glob) Restructured.  Sets set_seed.
+       (init_compat_dependent) Removed.  All references removed.
+       (get_date) Format changed from MM/DD/YY to DD MMM YYYY.
+       (__htonl, __htons) Removed.  (What were these for?)
+
+       * lexer.c: (static var tbl) Dash set to class CNUM.
+       (make_hexit) New function from data-out.c.
+       (get_token_representation) Rewritten.
+       (convert_negative_to_dash) New function.
+       (lex_init_compat_dependent) Removed.
+       (yylex) A dash is parsed as part of a number if it is followed by
+       a digit.  The ASCII representation of a number is copied to
+       tokstr.  String parsing farmed out to parse_string().  Comment
+       fixes.
+       (bin_value_func, oct_value_func, hex_value_func, parse_string) New
+       functions.
+       (preprocess_line) Line processing depends on interactive/batch
+       mode, not on compatibility mode.  Removed PC+ compatibility code.
+
+       * loop.c: (loop_3_trns_proc) Comment fix.
+
+       * main.c: Remove dead code.
+       (main) Remove call to init_compat_dependent().
+
+       * misc.c: (convert_fmt_ItoO) Make E format conversion more
+       conformant.
+
+       * print.c: (parse_string_argument) Calls
+       convert_negative_to_dash().
+       (fixed_parse_compatible) Calls convert_negative_to_dash().
+
+       * repeat.c: (RPT_* defines) Removed.
+       (struct rpt_numeric) Removed.
+       (struct repeat_entry) New member type, changed `replacement' from
+       char * to char **.
+       (clean_up) Deallocation adapted to new repeat_entry.
+       (internal_cmd_do_repeat) `type' defaults to 0.  Remove lookahead()
+       usage.  Creates vars for `type' of 1.
+       (parse_ids) Sets type of 1.  Adapted to new repeat_entry.
+       (store_numeric) Rewritten, new interface.
+       (parse_numbers) Rewritten.
+       (parse_strings) Rewritten.
+       (find_DO_REPEAT_substitution) New function.
+       (perform_DO_REPEAT_substitutions) New function.
+       (copy_with_DO_REPEAT_substitutions) Removed.
+       (debug_print) Rewritten.
+
+       * set.q: Comment fix.
+       (custom_results) Removed compatibility code.
+       (internal_cmd_set) Removed SET EMULATION subcommand.  Removed
+       compatibility code.
+
+       * sysfile-info.c: (cmd_display) Removed compatibility code.
+
+       * tokens.h: Comment fixes.
+       (token types enum) Removed `toktype' typedef name for this int
+       type.  Removed SUBST.  Restructured.
+
+       * vars-atr.c: (discard_variables) Sets n_lag to 0.
+
+       * vars-prs.c: Comment fix.
+
+       * vfm.c: Comment fixes.
+       (glob var n_lag) New var.
+       (static vars lag_count, lag_head, lag_queue) New vars.
+       (procedure) Removed argument nlag.
+       (setup_lag) New function.
+       (close_active_file) Discards lagging state.
+       (lag_case) New function.
+       (lagged_case) New function.
+       (write_case) Lags a case if lagging.
+
+       * weight.c: (cmd_weight) Removed compatibility code.
+       
+Sun Aug 17 22:34:40 1997  Ben Pfaff  <blp@gnu.org>
+
+       * getline.h: (struct getl_script) New members loop_index, macros.
+
+       * getline.c: (getl_add_file) Sets first_line field to NULL.
+       (getl_add_DO_REPEAT_file) New function.
+       (handle_line_buffer) When the current line's length is negative,
+       set the filename and line number.  Increment line number after
+       reading line.  Pass the line to
+       copy_with_DO_REPEAT_substitutions() for processing.
+       (getl_close_file) Free DO REPEAT lines before freeing the
+       filename, and just set the filename to NULL when doing this,
+       because otherwise the filename gets freed twice.
+
+       * glob.c: (glob var queuing) Removed.  All references removed.
+
+       * lexer.c: Comment fixes.
+       (get_token_representation) New function.
+
+       * repeat.c: Comment fixes.
+       (struct repeat_entry) Replaced type and v union members with a
+       simple string.
+       (append_record) New function.
+       (internal_cmd_do_repeat) Started reforming it for the new
+       repeat_entry struct.  Properly records filename changes in the
+       getl_line_buf.  Fixed improper use of = for ==.  Fixed sense of
+       strncasecmp() result usage.  Uses append_record() to simplify.
+       Properly discards END REPEAT line.  Calls getl_add_DO_REPEAT_file
+       to add in the file.
+
+       (copy_with_DO_REPEAT_substitutions) Started coding.
+
+       [DEBUGGING] (debug_print_lines) New function.
+
+       * set.q: (custom_results, internal_cmd_set) s/VER_PCP40/VER_PC/;
+
+       * tokens.h: (macro is_id1, is_idn) New macros.
+
+Sat Aug 16 10:57:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: (static var pre_syntax_message) Changed `win'
+       compatibility mode to `wnd'.
+
+       * data-list.c: (fixed_parse_spss) Renamed
+       fixed_parse_compatible().
+
+       * glob.c: (init_glob) Excise unused code for
+       program_invocation_short_name.
+
+       * lexer.c: (preprocess_line) Leading indentors are ignored in Wnd
+       as well as in X.
+
+       * print.c: (fixed_parse_spss) Renamed fixed_parse_compatible().
+
+       * set.q: `win' compatibility renamed `wnd'.
+
+Thu Aug 14 22:11:12 1997  Ben Pfaff  <blp@gnu.org>
+
+       * filename.c: [__WIN32__] Change the included Windows header files
+       (again).
+       (absolute_filename_p) [__MSDOS__] A filename with a colon as the
+       second character is absolute.
+       (dirname) Fix logic error.  Don't printf() the results.
+       (prepend_dir) Don't printf() the results.
+
+       * getline.c: (handle_line_buffer) New function.
+       (getl_read_line) Reads line with handle_line_buffer() when
+       appropriate.
+       (getl_close_file) Discard line buffer data.
+
+       * getline.h: Comment fixes.
+       (struct getl_line_list) New struct.
+       (getl_script_struct) Added line buffer members.  These are hooks
+       for use by DO REPEAT to allow it to insert virtual source code
+       into the program.
+
+       * glob.c: (init_glob) [__DJGPP__ || (__WIN32__ && __BORLANDC__)]
+       Override Borland C++ stupidity that claims Windows has a console
+       window size of 0x3.
+
+       * repeat.c: This is in the process of being restructured from
+       using a token-buffering approach to the DO REPEAT facility to
+       using the more flexible approach of a line-buffering approach in
+       conjunction with the getline module.  Comment fixes.
+       (struct tok_struct) Removed.
+       (static vars queue_index, queue_head, queue) Removed.
+       (static vars line_buf_head, line_buf_tail) New vars.
+       (internal_cmd_do_repeat) Instead of queuing tokens, queue lines.
+       Not complete.
+       (pull_queue, destroy_queue) Removed.
+       [DEBUGGING] (debug_print_tokens) Removed.
+
+Tue Aug  5 13:57:58 1997  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.q: (prepend_current_directory) New function.
+       (internal_cmd_file_handle, fh_get_handle_by_filename) Prepends
+       current directory before normalizing filename.
+
+       * filename.c: (gnu_getcwd) New function.
+       (absolute_filename_p) New function.
+       (search_path) New argument, PREPEND.  All references changed to
+       pass NULL except those explicitly mentioned.  Uses
+       absolute_filename_p().  Prepends PREPEND before trying the
+       filename.
+       (dirname, prepend_dir) New functions.
+
+       * getline.c: (getl_get_current_directory) New function.
+       (getl_include) Passes getl_get_current_directory() as PREPEND arg
+       to search_path().
+               
+Sun Aug  3 11:42:36 1997  Ben Pfaff  <blp@gnu.org>
+
+       * In several source files, the term `script' was replaced with
+       `syntax file' inside error messages.  Usage of the term `script'
+       in the sense of a syntax file is now deprecated.
+
+       * cmdline.c: (static vars pre_syntax_message, post_syntax_message)
+       Updated messages.
+
+       * dump-sysfile.c: (usage) Update message.
+
+       * getline.c: (getl_read_line) Ignore lines beginning with `#!'.
+
+       * getline.h: (glob var getl_include_path) Declare extern.
+
+       * list.q: Define EXTERN as extern before #including somP.h.
+
+       * var.h: Remove declaration of `disptype' variable.
+
+       * vfm.c: (close_active_file) After switching the data sink to a
+       data source, set vfm_sink to NULL, because it doesn't exist any
+       more.
+
+Thu Jul 17 21:41:44 1997  Ben Pfaff  <blp@gnu.org>
+
+       * glob.c: [__BORLANDC__] Include math.h.  Define _matherr() and
+       _matherrl() to ignore all math errors.
+
+       * sfm-read.c: (read_value_labels) When reading the labels from
+       disk, read the little parts separately instead of as a struct;
+       this avoids alignment problems.
+
+       * sfm-write.c: (struct sfm_fhuser_ext) New member `elem_type'.
+       (sfm_write_dictionary) Sets elem_type and frees it on lossage.
+       (write_header) Allocates and initializes elem_type.
+       (sfm_write_case) Uses elem_type to determine how to handle each
+       flt64 element.
+       (sfm_close) Frees elem_type.
+
+       * sfmP.h: Comment fix.
+       [__BORLANDC__] Uses #pragma -a to adjust structure member
+       alignment.
+       
+Thu Jul 17 01:55:12 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (fiasco_SOURCES) Remove display.c.
+
+       * common.c: Fix typo.
+
+       * dfm.c: (read_record) Remove strncasecmp() emulation and fix the
+       sense of the condition.
+
+       * expr-evl.c: (macro ALLOC_STRING_SPACE) [!PAGED_STACK] Add
+       line-continuation backslash.
+
+       * filename.c: [__WIN32__] Include <windef.h> before <winbase.h>.
+
+       * frequencies.q: (custom_grouped, add_percentile) Don't use a
+       non-constant expression as an argument to sizeof.
+
+       * glob.c: [__WIN32__ && __BORLANDC__] When including <conio.h>,
+       undefine gettext macro because that's a conio function.
+
+       * hash.h: (hsh_prime_tab declaration) Remove.
+
+       * list.q: (write_fallback_headers) Move `leader' allocation out of
+       main loop.  Change to local_alloc() allocation.
+
+       * output.h: Formatting fixes.  Put __attribute__ in right place on
+       function prototypes.
+
+       * sfm-read.c: (read_machine_flt64_info, read_variables) Change
+       incorrect `SECOND_LOWEST_VALUE' references to proper
+       `second_lowest_value'.
+
+       * som-frnt.c: (EXTERN macro) Define as `extern' instead of null
+       value.  This way 2 out of 3 of the som files define the vars
+       extern, the correct way, that actually works under BC++.
+       (som_set_float) Don't use nonconstant initializers for a struct.
+
+       * som-high.c: Add the standard alloca() header.
+       (replicate_table) Add prototype.
+
+       Merged DISPLAY routine.
+       * sysfile-info.c: (AS_*) New enum series.
+       (cmd_sysfile_info) Gutted.  Calls describe_variable() to do the
+       dirty work.
+       (cmd_display, display_macros, display_documents,
+       display_variables) Stolen from defunct display.c.
+       (describe_variable) New function.
+
+       * temporary.c: [0] (display_tree) New debug function.
+       (copy_variable) Performs shallow copy of value labels instead of
+       deep copy; i.e., just copys the AVL tree and increments the
+       reference counts.
+
+       * val-labs.c: Comment fixes.
+       (do_value_labels) Optionally skip leading forward slash.
+       (get_label) Creates only a single value label instead of many
+       copies of one, and sets the reference count.
+
+       * display.c: Removed.
+
+       * dump-sysfile.c: New file, not yet complete.
+
+Fri Jul 11 23:02:18 1997  Ben Pfaff  <blp@gnu.org>
+
+       For lots of source files I added more verbose_msg's.  These aren't
+       listed below as they have tested as being benign.  In some cases
+       these replaced debug_printf() calls.
+
+       * output.c: (outp_read_devices) Message fix.
+
+       * postscript.c: (output_encodings) Message fix.  Reports errors on
+       fclose().
+       (postopen) Message fix.
+       
+Fri Jul 11 14:09:40 1997  Ben Pfaff  <blp@gnu.org>
+
+       * dfm.c: (dfm_close) Don't call fclose() for a NULL FILE.
+
+       * filename.c: (close_file_ext) Set f->file to NULL *after* closing
+       it.
+
+       * main.c: Remove <malloc.h> #include.
+
+       * mis-val.c: (parse_numeric) Set .f member for each missing[]
+       instead of trying to just set the missing[] itself, which is a
+       gcc-specific idiom.
+
+       * sfm-read.c: (read_variables) Same.
+
+       * str.h: Add memmem() prototype.
+
+       * val-labs.c, var-labs.c: Replace <malloc.h> with <stdlib.h>.
+
+Thu Jul 10 22:13:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (q2c) Don't include any libraries in the link.
+
+       * dfm.c: (force_line_buffer_extension) New macro.
+       (count_tabs) New function.
+       (tabs_To_spaces) New function.
+       (read_record) Calls tabs_to_spaces() on the line being processed.
+
+       * q2c.c: Disabled i18n for this proglet so that libintl.a doesn't
+       have to be compiled twice (once for CC, once for LOCAL_CC).
+Sun Jul  6 19:14:33 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (INCLUDES) Add intl directory; fix directories.
+       (LDADD) Add @INTLLIBS@.
+       (q2c) Add LIBS, @INTLLIBS@ to link step.
+
+       * inpt-pgm.c: Turn off debugging.
+
+       * postscript.c: (postopen) Format fix.  local_free() blocks
+       returned by local_alloc(); don't free() them.
+
+Sat Jul  5 23:44:51 1997  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: (parse_string_as_format) Comment fix.  Fix check for
+       string length.
+
+       * data-list.c: (read_from_data_list_fixed) Pass proper value for
+       LEN arg, not simply the full string length.
+
+       * sort.c: (allocate_file_handles) Check SPSS compatible temp file
+       directories before generic temp file directories.
+
+       * vfm.c: Disable debugging.
+
+Fri Jul  4 13:26:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Comment fix.
+       (cmd_save_internal) Always passes GTSV_OPT_SAVE option.
+
+Wed Jun 25 22:52:28 1997  Ben Pfaff  <blp@gnu.org>
+
+       * expr-prs.c: (debug_print_postfix) Conditionally included on
+       GLOBAL_DEBUGGING.  Removed out_header() reference.
+
+       * exprP.h: Removed #undef GLOBAL_DEBUGGING.
+
+Sun Jun 22 22:00:28 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: Removed obsolete ascii_close_page() prototype.
+
+       * command.c: (output_line) Comment fix.
+
+       * data-in.c: Formatting fix.
+       (parse_string_as_format) Now the `fc' argument is used only for
+       the purpose of error messages; it is not an index into the string
+       passed.  All references changed.
+
+       * data-list.c: Comment fix.
+       (cut_field) Comment fix.  Now returns the column number of the
+       position of the field cut out on success.
+       (parse_field) Added `column' argument.  Puts the column numbers in
+       the error message.
+       (read_from_data_list_free, read_from_data_list_list) Record the
+       column number returned by cut_field(), pass it to parse_field().
+
+       * dfm.c: Comment fix.
+
+       * do-ifP.h: Comment fix.
+
+       * expr-prs.c: (SYSMIS_func) Implemented string-type arguments for
+       the SYSMIS function.
+
+       * expr.h, exprP.h: Comment fix.
+
+       * glob.c: (init_glob) Only calls setlocale() and family if
+       ENABLE_NLS set.
+
+       * hash.h: Comment fix.
+
+       * include.c: Comment fix.
+
+       * output.c: Comment fix.
+
+       * postscript.c: (ps_line_intersection) Simplified assertion.
+
+       * repeat.c: Comment fix.
+
+       * vars-atr.c: Comment fix.
+
+       * vars-prs.c: Comment fix.
+
+       * vfm.c: (vector_initialization) [DEBUGGING] Fixed undefined
+       behavior with usage of postincrement.
+       (memory_stream_read) Discards cases as it goes. 
+
+Sun Jun 15 16:45:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Cleans q2c, not just distcleans it.  Distcleans
+       foo.
+
+       * Most source files: Includes debug-print.h, related comment
+       fixes.
+
+       * cases.c: (alloc_val) Removed complex allocation code.  Merely
+       increments default_dict.nval and returns the former value.
+       (envector, devector) Removed references to lv member of struct
+       variable.
+
+       * common.h: (macro VME) Replaced complex definition with simple
+       one.
+
+       * data-list.c: (cmd_data_list) Sets vfm_source instead of
+       read_active_file and cancel_input_pgm.
+       (read_from_data_list, cancel_data_list) Removed.
+       (data_list_source_read, data_list_source_destroy_source) New
+       functions.
+       (glob var data_list_source) New var.
+
+       * dfm.c: (open_file_r, open_file_w) Simplified debug output.
+       (cmd_begin_data) Improved criteria for an input program accessing
+       the inline file.  Still not perfect.
+
+       * do-if.c: (do_if_trns_proc) Simplified debug output.
+
+       * expr-prs.c: Comment fixes.
+       [DEBUGGING] (debug_print_postfix) Simplified debug output.
+
+       * file-handle.q: (fh_close_handle) Simplified debug output.
+
+       * file-type.c: Comment fixes.
+       (cmd_file_type) Sets vfm_source instead of read_active_file and
+       cancel_input_pgm.
+       (cmd_end_file_type) On failure, discards variables in place of
+       just canceling the input program.
+       (read_from_file_type) Renamed file_type_source_read.
+       (cancel_file_type) Renamed file_type_source_destroy_source.
+       (glob var file_type_source) New var.
+
+       * get.c: (GTSV_* enum series) New enums GTSV_OPT_SAVE, GTSV_NONE.
+       (cmd_get) Initializes options to GTSV_NONE before passing to
+       trim_dictionary().  Removed `lv' reference.  Sets vfm_source
+       instead of read_active_file and cancel_input_pgm.
+       (cmd_save_internal) Initializes options before passing to
+       trim_dictionary().  Local var `nval' removed.
+       (dict_delete_run) Comment fixes.
+       (trim_dictionary) Comment fixes.  Disallows scratch variables if
+       GTSV_OPT_SAVE set in options.
+       (read_from_get) Renamed get_source_read.
+       (cancel_get) Renamed get_source_destroy_source.
+       (glob var get_source) New var.
+
+       * inpt-pgm.c: (cmd_input_program) Sets vfm_source instead of
+       read_active_file and cancel_input_pgm.
+       (read_from_input_program) Renamed input_program_source_read.
+       Simplified debug output.
+       (cancel_input_program) Renamed
+       input_program_source_destroy_source.
+       (glob var input_program_source) New var.
+
+       * loop.c: (loop_1_trns_proc) Simplified debug output.
+
+       * main.c: (dump_token) Made eof output more explicit.
+
+       * sfm-read.c: (read_variables, dump_dictionary) Removed `lv'
+       references.
+
+       * sort.c: (cmd_sort_cases) Disallows scratch variables.  Removed
+       code for always-memory or always-disk cases.  malloc's case-list
+       based on vfm_source_info.ncases.  Explicit support for
+       memory_stream via memory_source_cases.
+       (do_external_sort) Sets vfm_source instead of read_active_file and
+       cancel_input_pgm.
+       (allocate_file_handles) The temporary directory permissions are
+       set to 0700 instead of 0777.
+       (allocate_cases) Formatting fixes.  Simplified debug output.
+       (output_record) Compacts the case if necessary before writing it
+       out.
+       (close_handle, open_handle_w) Simplified debug output.
+       (write_initial_runs) Destroys vfm_sink, then sets it to
+       sort_stream.  Writes records to memory based on
+       vfm_sink_info.case_size.
+       (write_to_sort_cases) Renamed sort_stream_write().
+       (merge) Simplified error handling.  Simplified debug output.
+       Formatting fixes.
+       (read_from_external_sort) Renamed sort_stream_read().
+       Reads records based on vfm_source_info.case_size.
+       (sort_stream_write) Writes records to memory based on
+       vfm_sink_info.case_size.
+       (sort_stream_mode) New function.
+       (glob var sort_stream) New variable.
+
+       * temporary.c: (cmd_temporary) Simplified debug output.
+       (copy_variable) Removed references to `lv'.
+
+       * title.c: (get_title) Simplified debug output.
+
+       * var.h: Comment fixes.
+       (struct get_proc) Removed member `lv'.
+       (struct variable) Removed member `lv'.  Comment fixes.
+       (glob vars read_active_file, write_active_file, cancel_input_pgm)
+       Removed.
+       (struct case_stream) New.
+
+       * vars-atr.c: (discard_variables) Changed cancel_input_pgm,
+       read_active_file references to use vfm_source.
+       (init_variable, replace_variable) Removed references to `lv'.
+
+       * vfm.c: Comment fixes.
+       (glob var vfm_source, vfm_sink, vfm_source_info, vfm_sink_info)
+       New variables.
+       (static var queue, qh, qt, n_lag) Removed.  All references
+       removed.
+       (glob var compaction_necessary, compaction_nval, compaction_case,
+       paging) New variables.
+       (record_case) Removed.
+       (procedure) Comment fixes.  Calls vfm_source->read() instead of
+       read_active_file().
+       (lag) Removed.
+       (prepare_for_writing, arrange_compaction, make_temp_case,
+       vector_initialization, setup_filter) New function.
+       (open_active_file) Most of the code moved into the abovementioned
+       new functions.  Now sets temp_dict to &default_dict if there is no
+       temporary dictionary, for convenience.  New debug output.
+       (close_active_file) Deals with changing the sink to the source.
+       Calls finish_compaction().  Frees compaction_case.  Mostly
+       rewritten.
+       (glob vars disk_source_file, disk_sink_file) New vars.
+       (destroy_active_file, read_from_memory) Removed.
+       (disk_stream_init, disk_stream_read, disk_stream_write,
+       disk_stream_mode, disk_stream_destroy_source,
+       disk_stream_destroy_sink) New functions.
+       (glob var vfm_disk_stream) New var.
+       (glob vars memory_source_cases, memory_sink_cases,
+       memory_sink_iter, memory_sink_max_cases) New vars.
+       (memory_stream_init, memory_stream_read, memory_stream_write,
+       memory_stream_mode, memory_stream_destroy_source,
+       memory_stream_destroy_sink) New functions.
+       (glob var vfm_memory_stream) New var.
+       (write_case) Local var `i' renamed `cur_trns'; local var `retval'
+       named `more_cases'.  Simplified debug output.  Otherwise mostly
+       rewritten.
+       (record_case) Moved into the stream drivers.  Removed.
+       (transform) Removed (was dead code).
+       (SPLIT_FILE_procfunc) s/vfm_replacement/vfm_sink_info/.  In the
+       common case that the splits don't change, we don't need to copy
+       the case into prev_case again--pointless.
+       (compact_case) New function.
+       (finish_compaction) New function.
+
+       * vfmP.h: Comment fixes.
+       (DEV_* enum series) Removed. 
+       (struct storage) Renamed `stream_info'.  Removed variant record.
+       Removed `device' member.
+
+       * debug-print.h: New file.
+       
+Sun Jun  8 01:12:38 1997  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.c: Turned off debugging.
+
+       * data-list.c: (destroy_dls) Closes the associated file handle.
+
+       * descript.q: (custom_variables) Added PV_NO_SCRATCH to
+       parse_variables() options.
+
+       * dfm.c: (open_file_r) Removed gratuituous argument to msg() call.
+
+       * display.c: (display_variables) Really fixed null cell bug.
+
+       * file-handle.q: (fh_close_handle) Changed debugging message.
+
+       * frequencies.q: (custom_variables) Added PV_NO_SCRATCH to
+       parse_variables() options.
+
+       * list.q: Added PV_NO_SCRATCH in q2c varlist options.
+       (cmd_list) Fails if no variables specified.
+       (determine_layout) Writes blank lines manually.
+
+       * loop.c: (loop_1_trns_proc) Made debugging code only print
+       messages if debugging.
+
+       * q2c.c: (dump_subcommand) Appends sbc->message to SBC_VARLIST
+       parse_variables() arguments.
+       (main) Parses optional parenthesized options to varlist
+       subcommands into sbc->message.
+
+       * sfm-read.c: Format fix.
+
+       * var.h: (FV_*) New enum series.
+       (PV_*) New enum PV_NO_SCRATCH.
+
+       * vars-prs.c: (find_var) Removed.
+       (fill_all_vars) Takes FV_* enum instead of boolean third
+       argument.  Rewritten to deal with scratch as well as system
+       variables.
+       (parse_variables) Error message on scratch variable if
+       PV_NO_SCRATCH set.
+
+       * vfm.c: (static var virt_begin_func) New var.
+       (procedure) Sets up virt_begin_func.
+       (SPLIT_FILE_procfunc) For the first case, calls virt_begin_func()
+       after dump_splits().  For succeeding groups changes, calls
+       virt_begin_func() instead of begin_func().      
+
+Fri Jun  6 22:42:23 1997  Ben Pfaff  <blp@gnu.org>
+
+       * count.c, data-out.c, file-handle.q, list.q, loop.c: Turned off
+       debugging.
+
+       * dfm.c: Added some debugging messages, disabled by default.
+       (open_file_r) Fixed error message.
+       (read_record) On eof on inline_file, instead of calling
+       fh_close_handle(), simply jump to eof label like a normal file.
+       Message fixes.
+
+       * display.c: Thin lines between rows for certain kinds of
+       listing.  Fixed `null cell' bug.
+
+       * error.c: (failure) Flush stdout, stderr before failing.
+
+       * file-handle.q: (fh_close_handle) Added debugging message.
+
+       * frequencies.q: (dump_full) Bottom line extends across entire
+       table width.  Changed title formatting.
+       (dump_condensed) Changed title formatting.
+       (dump_statistics) Fixed title formatting.
+
+       * glob.c: (init_glob) Moved initialization of cur_proc out of #if.
+       Sets default value of set_format.
+
+       * list.q: (cmd_list) Calls blank_line() before determine_layout().
+       Passes write_all_headers() to procedure() as pre-group func.
+       (write_all_headers) New function.
+       (determine_layout) Removed calls to write_header().
+       Calls blank_line() before and after write_fallback_headers().
+
+       * recode.c: (recode_trns_free) Only attempts to free head->map if
+       non-NULL.
+
+       * sfm-read.c: (read_variables) Allows `#' at beginning of system
+       file variable names but gives a warning.  Sets `left' based on
+       first character being/not being `#'.  On lossage frees dict->var.
+
+       * som-high.c: (som_draw_title) Simplified title formatting.
+
+       * vfm.c: (dump_splits) Fixed and changed splits formatting.
+
+Thu Jun  5 22:51:15 1997  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.c: (cmd_autorecode) Sets h_trans to NULL at
+       beginning.  Frees v_src, v_dest on successful exit.  Frees
+       h_trans[*], h_trans on lossage.
+       (recode) Frees h_trans[*], h_trans.
+
+       * dfm.c: (dfm_close) Formatting change.
+       (open_inline_file) Now passed a dfm_fhuser_ext to initialize; no
+       longer allocates its own in inline_file.
+       (open_file_r) Passes the local dfm_fhuser_ext to
+       open_inline_file().
+       (open_file_w) Message fix. 
+       (read_record) Buffer reallocation strategy changed.  Frees
+       ext->line even in inline_file to prevent leaks.
+       (dfm_put_record) Fixed bug where `ext' was cached before the file
+       was opened and thus it would be NULL when the file really was
+       open.
+       (cmd_begin_data) Sets up inline_file basics itself, then calls
+       open_inline_file() for the dfm_fhuser_ext.  Formatting fix.
+
+       * list.q: (write_line) Formatting fix.
+       (clean_up) Minor strategy change.  Sets proportional font after
+       finishing cleanup.
+       (determine_layout) Sets fixed font before writing regular headers,
+       or after writing fallback headers.
+
+       * modify-vars.c: (cmd_modify_vars) Frees variable lists for DROP
+       and KEEP vars after using them.
+
+       * postscript.c: (ps_init_driver) Frees x->family.
+       (postopen) When loading fonts, free the temporary font name buffer
+       after using it.
+       (ps_text_set_font_by_position) Free temporary font name buffer
+       after using it.
+       (text) Fixed code that calculated `lig' so that `lig' always gets
+       initialized.  Formatting fix.
+
+       * som-low.c: (get_cell_size, som_get_table_size) `prop_height' ->
+       `font_height'.
+       [GLOBAL_DEBUGGIGN] (check_table) Use arena_alloc() to allocate
+       cells, not xmalloc(), so that the cells will get destroyed
+       automatically.
+
+       * sysfile-info.c: (cmd_sysfile_info) Frees the dictionary after
+       using it.
+
+Tue Jun  3 23:33:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_text_draw) Always sets metrics for strings that
+       are drawn.
+
+       * dfm.c: Comment fix.
+
+       * list.q: Comment fixes.  Include somP.h.  Removed static vars
+       table, n_columns, n_rows, part.  New struct list_ext.  New static
+       var line_buf.
+       (n_lines_remaining, n_chars_width, write_line) New functions.
+       (cmd_list, list_cases) Rewritten.
+       (begin_row, end_row, flush_table) Removed.
+       (write_header, clean_up, write_varname, write_fallback_headers,
+       determine_layout) New functions.
+
+       * output.c: (outp_iterate_enabled_drivers) Minor reformat.
+
+       * output.h: Comment fix.
+
+       * postscript.c: Comment fix.
+       (struct ps_driver_ext) Removed prop_size, fixed_size members;
+       added font_size.  All references changed.
+       (ps_init_driver) Initializes font_size.  Simplified space checking
+       code.
+       (static var option_tab[]) Removed prop-size, fixed-size; added
+       font-size.
+       (ps_option) Handles font_size.
+
+       * som-high.c: Moved prototypes into somP.h.
+       (som_init_driver) New function.
+       (som_submit_table) Moved some code into new function
+       som_init_driver().
+       (build_target) Moved some code into new function
+       som_internal_eject_page().
+       (som_eject_page) Uses som_internal_eject_page().
+       (som_internal_eject_page) New function.
+
+       * som-low.c: Moved prototypes into somP.h.
+
+       * som.h: Formatting fixes.
+
+       * somP.h: (struct som_driver_ext) Removed em_width;
+       added prop_em_width, fixed_width.
+
+Mon Jun  2 14:25:25 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added `localedir' definition.  Added
+       -DLOCALEDIR="..." to DEFS.  Added -I. to INCLUDES.
+
+       * ascii.c: (macro draw_line) Fixed capitalization.
+
+       * ascii.c, autorecode.c, cases.c, cmdline.c, command.c, common.c,
+       compute.c, count.c, data-in.c, data-list.c, data-out.c,
+       descript.q, dfm.c, display.c, do-if.c, error.c, expr-evl.c,
+       expr-opt.c, expr-prs.c, file-handle.q, file-type.c, filename.c,
+       formats.c, frequencies.q, get.c, getline.c, glob.c, groff-font.c,
+       hash.c, heap.c, include.c, inpt-pgm.c, lexer.c, list.q, loop.c,
+       main.c, mis-val.c, misc.c, modify-vars.c, numeric.c, output.c,
+       postscript.c, print.c, q2c.c, recode.c, rename-vars.c, repeat.c,
+       sample.c, sel-if.c, sfm-read.c, sfm-write.c, sfmP.h, som-frnt.c,
+       som-high.c, som-low.c, sort.c, split-file.c, sysfile-info.c,
+       temporary.c, title.c, tokens.h, val-labs.c, var-labs.c,
+       vars-atr.c, vars-prs.c, vector.c, vfm.c, weight.c: Marked strings
+       for internationlization.
+
+       * glob.c: [HAVE_LOCALE_H] Includes locale.h.
+
+Sun Jun  1 23:31:18 1997  Ben Pfaff  <blp@gnu.org>
+
+       * do-if.c, sort.c, val-labs.c: Comment fixes.
+
+       * glob.c: (init_glob) Uncommented, updated i18n support.
+       
+       * arena.c, ascii.c, data-in.c, descript.q, error.c, expr-evl.c,
+       expr-opt.c, expr-prs.c, filename.c, frequencies.q, groff-font.c,
+       output.c, postscript.c, sfm-read.c, som-high.c, vars-prs.c: Made
+       the declarations of macros taking arguments a lot nicer.
+
+Sun Jun  1 17:22:04 1997  Ben Pfaff  <blp@gnu.org>
+
+       * error.h: Removed CE, CW aliases for SE, SW.
+
+       * q2c.c: Removed explicit streq() definition since it's duplicated
+       in str.h.
+       
+       * approx.h, error.h, font.h, hash.h, misc.h, output.h, somP.h,
+       stats.h, str.h, tokens.h: Made the declarations of macros taking
+       arguments a lot nicer-looking of <pinard@iro.umontreal.ca>.
+       Comment fixes.
+
+Sun Jun  1 12:02:06 1997  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: Comment fixes.
+       (pick_compat) Changed return type to int.  Now, instead of setting
+       glob var `compat' to the emulation, returns the emulation.  All
+       references changed.
+       (parse_command_line) Added terminating null to end of
+       `long_options' array definition.
+       (pre_syntax_message) Fixes.
+       (usage) Shows the default emulation in the syntax message by
+       calling pick_compat().
+
+       * getline.c: (getl_add_include_dir) Separates paths with
+       PATH_DELIMITER, not DIR_SEPARATOR.
+
+       * glob.c: (init_glob) Fixed references to DEFAULT_VER_PCP40,
+       DEFAULT_VER_WIN61, DEFAULT_VER_X40.
+
+       * output.c: (outp_configure_macro) Make earlier definitions for a
+       particular key override later ones for the same key.
+       
+Fri May 30 19:40:49 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: Comment fixes.
+
+       * output.c: (outp_get_paper_size)
+       s/STAT_OUTPUT_INIT_FILE/STAT_OUTPUT_PAPERSIZE_FILE/.
+       
+Sun May 25 22:34:07 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c, postscript.c, sfm-read.c, sfm-write.c, sort.c: Include
+       <errno.h>.  GNU libc 2 enforces this!
+
+       * command.c: (parse_cmd) Fixed problem with `else' clause being
+       paired with wrong `if'.  Comment fix.
+
+Fri May  9 16:53:52 1997  Ben Pfaff  <blp@gnu.org>
+
+       * getline.c: [!HAVE_LIBREADLINE] (read_console) Changed
+       blp_getline() to getline().
+
+       * output.c: (outp_eval_dimension) Changed the fix from last time;
+       there was no variable `a'.
+
+       * q2c.c: (get_line) Fixed boundary condition overrun bug.
+
+Mon May  5 21:58:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * output.c: (outp_evaluate_dimension) Fixed handling of negative
+       numbers having fractional parts.  Added case of a fraction without
+       a whole-number part.
+
+Fri May  2 22:08:05 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_text_get_font_position) Removed.
+
+       * expr.h, exprP.h: Disabled debugging.
+
+       * groff-font.c, postscript.c: Changed `groff' to `Groff' in
+       several places.
+
+       * output.h: (struct outp_class_struct) Removed
+       text_get_font_position method.  All references deleted.
+
+       * postscript.c: Big change here.  Fontmaps were completely
+       eliminated because of a change in philosophy.  Comment fixes.
+       (struct ps_fontmap, ps2dit_map, font_family, dit2family_map)
+       Removed.
+       (struct ps_driver_ext) `position', `fontmap', `prop_name',
+       `fixed_name' members removed.  New members `prop_family',
+       `fixed_family'.  `family' member changed to type char *.
+       (static var ps_fontmaps) Removed.
+       () Removed.
+       (ps_init_driver) Removed obsolete references, updated.
+       Initializes `translate_x', `translate_y', `scale'.  Doesn't read
+       fontmap, of course.  Refers to font names through internal_name
+       rather than subversive means.  Frees proper items.
+       (static var option_tab[]) Removed `fontmap-file' option; renamed
+       `fixed-font', `prop-font'.
+       (ps_option) Corresponds to option_tab[].
+       (read_fontmap, release_fontmap, ps_to_dit, compare_ps2dit,
+       hash_ps2dit, compare_dit2family, hash_dit2family, compare_family,
+       hash_family) Removed.
+       (postopen) Generates font names from family names.  Gets
+       PostScript font name properly.  New prologue file comment `!!!'
+       style.
+       (ps_open_page) Adds translate_x, translate_y to BP prologue
+       function; gives SF argument floating-point format.
+       (ps_text_set_font_by_name) Doesn't try to map PostScript->Groff
+       font name.  Doesn't change font family.
+       (ps_text_set_font_by_position) Generates Groff font name from font
+       family name instead of through table lookup.
+       (ps_text_set_font_by_family) Renamed `ps_text_set_font_family',
+       all references changed.  Reduced to simple string assignment.
+       (ps_get_font_name) Removed.
+       (ps_get_font_family) Reduced to string return.
+       (text) Doesn't save `position' since it no longer exists.  Ugly
+       kluge to save font family--fix soon?
+       (load_font) Removed PostScript name argument.
+       
+Thu May  1 14:58:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: Comment fix.
+       (ps_open_page) Puts scale factor in PostScript output.
+       
+Sat Apr 26 11:49:32 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Distcleans q2c.
+
+Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (delineate) Sets text size even if width is zero.
+
+       * command.c: Comment fix.
+       (static var cmd_table[]) Re-enabled EVALUATE command.
+       (parse_cmd) Lotsa comment fixes.  Fixed infinite loop in parsing
+       of comments in script files.  Now more liberal on criteria for
+       performing a state transition--if *anything* happened correctly,
+       not just if *everything* happened correctly.
+
+       * data-out.c: (convert_F) Comment fix.  Why in the fsck does
+       Checker segfault on formatting large numbers and why in the fsck
+       hadn't I noticed this before?
+
+       * expr.h, exprP.h: No longer turn off GLOBAL_DEBUGGING.
+
+       * list.q: (cmd_list) Commented out the actual output routine
+       because of various problems.  Probably will abandon the idea of
+       using the general `crushed tables' for the LIST procedure.
+
+       * temporary.c: (restore_dictionary) Sets var_by_name to NULL after
+       clearing it.  Allocates a new var_by_name dictionary before trying
+       to add members to it.
+
+       * vars-atr.c: [DEBUGGING] (dump_one_var_node) Removed argument
+       `sib'.  Changed type of `node' argument.
+       [DEBUGGING] (dump_var_tree) Replaced avlwalk() with
+       avl_walk_inorder().
+       (clear_variable) Only dumps the var tree if var_by_name non-NULL.
+       [DEBUGGING] Only deletes the variable from var_by_name if that var
+       non-NULL.
+
+Fri Apr 18 16:48:41 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added include files to SOURCES.  Added
+       frequencies.q to EXTRA_DIST.  Removed include/ from INCLUDES.  Now
+       includes rules for q2c.  Added `boast' target.
+
+Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Maintainer-clean Makefile.in.
+       
+       * Makefile.am: Fixed redundant EXTRA_DIST line.
+
+       * ascii.c: Comment fixes.
+       (ascii_line_vert) Fixed overly aggressive range check.
+
+       * display.c: Removed dead code.
+
+       * list.q: Turn debugging on.
+       (flush_table) New debug code.
+
+       * sfm-read.c: (read_value_labels) malloc's the structure before
+       trying to assign to its members.
+
+       * sfm-write.c: Comment fix.
+
+       * som-high.c: (som_submit_table) Sets som.t and som.d on each call
+       to output_table().
+       (output_table) No arguments anymore--gets them through `som'
+       global.  New debug code.  In crushed tables, now sets `htv' as
+       well as `hv' to avoid bad confusion later.
+       (dump_crush_page) New debug code.
+
+       * som-low.c: (som_dump_crush_page) New debug code.
+
+Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
+
+       All source files: Broke long lines into multiple lines.
+       
+       * ascii.c: (ascii_close_page) Uses host_system var in place of
+       HOST_SYSTEM constant.
+
+       * cmdline.c: (var syntax_message[]) Broke into
+       pre_syntax_message[] and post_syntax_message[].
+       (usage) Outputs both parts, separated by driver list.
+
+       * error.h: Fixed broken formatting.
+
+       * expr-opt.c: (str_search, str_rsearch) New functions.
+
+       * misc.c: (blp_getdelim) Removed.  All references changed to
+       `getdelim'.
+       (str_search, str_rsearch) Removed.
+       (memrmem) New function.
+
+       * misc.h: (blp_getline) Removed.  All reference changed to
+       `getline'.
+
+       * stat.h: New file.
+
+       * filename.c: Includes "stat.h", not <sys/stat.h>.
+       (blp_getenv) Uses host_system var instead of HOST_SYSTEM constant.
+
+       * output.c: (outp_list_classes) Changed output formatting.
+
+       * sfm-write.c: (write_header) Uses host_system var instead of
+       HOST_SYSTEM constant.
+       (write_rec_7_34) Extracts version numbers from the version string.
+       Untested.
+
+       * sort.c: Includes "stat.h", not <sys/stat.h>.
+
+       * str.c: (strcasecmp) Removed.
+
+       * title.c: (cmd_document) Uses host_system var instead of
+       HOST_SYSTEM constant.
+
+       * version.c: Generated on-the-fly by the Makefile instead of being
+       static.
+
+       * str.h: Comment fixes.  Doesn't substitute for missing memmove or
+       memcpy.
+       [!HAVE_STRNCASECMP] Declares strncasecmp().
+
+       * version.h: Removed stray character.  Comment fixes.
+       (vars host_system, build_system) New vars.
+
+Mon Mar 24 21:47:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Most source files: Changed formatting of copyright notice; fixed
+       FSF address; reformatted to better conform to GNU standards;
+       comment fixes.  Added markups to prevent GNU indent from messing
+       up my beautiful formatting :-).
+       
+       * q2c.c: (get_line) Ignores lines that begin with `/* *INDENT' so
+       that GNU indent markups can be passed through without problems.
+
+Wed Feb 19 21:30:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Turned off debugging.
+
+       * glob.c: (init_glob) Turned on save-file compression by default.
+
+       * sfm-write.c: (sfm_write_case) Fixed bug which resulted in less
+       compression than was possible in save files.
+
+Sun Feb 16 20:57:20 1997  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c: (convert_F) Comment fixes.  Debug message fixes.
+
+       * frequencies.q: Removed Fiasco extensions.  Updated calculation
+       algorithms.  Polished output format. 
+       (struct frq_info_struct) Removed members `max_degree', `min_n',
+       all references removed.
+       (macro frq_extensions) Removed.
+       (static vars min_n, max_degree) Removed, all references removed.
+       (internal_cmd_frequencies) Doesn't handle extensions.  Doesn't
+       calculate `min_n', `max_degree'.
+       (postcalc) Passes new arg to dump_statistics().
+       (dump_full) Honor NOLABEL option.  Buggy?  Adds variable name
+       title.
+       (dump_condensed) Adds variable name title.
+       (sum_freqs) Removed.
+       (calc_stats) Updated calculation algorithm.
+       (dump_statistics) Removed warning for too-few observations.
+       Changed table formatting.  Adds variable name title if passed new
+       arg is nonzero.
+
+       * output.h: Comment fix.
+
+       * recode.c, sample.c, sort.c: Disabled debug code.
+
+       * som-frnt.c: (som_set_value, som_set_float, som_set_text)
+       Improved debug code.
+
+       * var.h: (enum series frq_*) Removed Fiasco extensions.
+
+Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added PROCESS IF to command table.
+
+       * Lots & lots of places, removed checks for NULLs preceding calls
+       to free_expression(), which itself checks.
+
+       * descript.q: Removed Fiasco extensions.  Removed optimizations
+       for non-weighted active files.  Implemented some options.
+       Finished polishing output format.  Comment fixes.  Merged
+       `descript.g'.
+       (static vars n_glob_miss_list, n_glob_valid, n_glob_missing,
+       max_degree, min_n) Removed.
+       (macro dsc_extensions) Removed.
+       (struct dsc_info_struct) Removed `min_n' member, all references
+       fixed.
+       (internal_cmd_descriptives) Removed calculation of min_n,
+       max_degree.  Only deals with one `calc' routine instead of two
+       flavors.
+       (precalc) Eliminated redundancy.  Updated for changes to
+       descriptives_proc structure.
+       (calc) Moved here from `descript.g'.  Rewritten to calculate
+       statistics via `moments about the mean' rather than by summing,
+       summing squares, summing cubes, and so on.
+       (postcalc) Rewritten for new-style statistical calculation.
+       (display) Removed support for displaying variables across rows.
+       No longer crushes the descriptives table.  Removed ancient code.
+       Added display of N, by variable and listwise.
+
+       * descript.g: Removed; merged into `descript.q'.
+
+       * expr-evl.c: (evaluate_expression) Now returns a double.  For
+       numeric results, it returns the result as well as storing it in
+       the passed `value' structure if non-NULL.  For string results it
+       just returns 0.0 and it must be passed non-NULL.  Many references
+       to this function were optimized by use of this change, especially
+       but not exclusively in `compute.c'.
+
+       * frequencies.g: Comment fix.
+
+       * glob.c: (glob var process_if_expr) New global var.
+
+       * postscript.c: (static var option_tab[]) Corrected entry for
+       `fixed_size'.
+       (postopen) Sets x->size to x->prop_size.
+       (ps_text_set_font_by_name) Sets font size as well as typeface for
+       PROP and FIXED fonts.
+       
+       * sel-if.c: (cmd_process_if) New function.
+
+       * sfm-write.c: (struct sfm_fhuser_ext) New member `n_cases'.
+       (sfm_write_dictionary) Sets `n_cases' to 0.
+       (sfm_write_case) Increments `n_cases'.
+       (sfm_close) Attempts to seek the system file back to the header
+       and write the number of cases in its proper slot.
+
+       * som-frnt.c: (som_insert_table) Masks off expansion options since
+       only SOPT_X_NORM seems to work sensibly.
+
+       * som-low.c: (get_cell_size) Fixed bug when a table cell was sized
+       with a `fixed' value of 2.
+
+       * sort.c: (cmd_sort_cases) Cancels PROCESS IF.
+
+       * sysfile-info.c: (cmd_sysfile_info) Doesn't display more than 10
+       value labels; uses SOPT_NONE instead of SOPT_X_BOTH.
+
+       * var.h: (enum series dsc_*) Removed Fiasco extensions.
+       (struct descriptives_proc) Removed `miss_noweight'; new members
+       `X_bar', `M2', `M3', `M4', `min', `max'.
+
+       * vars-atr.c: (discard_variables) Cancels PROCESS IF.
+
+       * vfm.c: (close_active_file) Cancels PROCESS IF.
+       (write_case) Doesn't process cases unselected by PROCESS IF.
+
+Fri Feb 14 23:32:58 1997  Ben Pfaff  <blp@gnu.org>
+
+       * glob.c: (glob var err) Removed.
+
+       * sysfile-info.c: (cmd_sysfile_info) When adjusting table size,
+       doesn't have to take into account number of value labels since
+       they're in a subtable anyway.  Also, doesn't display more than 10
+       value labels since we can't yet break pages in subtables.
+
+Tue Feb  4 15:15:50 1997  Ben Pfaff  <blp@gnu.org>
+
+       * som-frnt.c: (som_change_table_size) Simple change for elegance
+       that shouldn't change behavior.
+       (som_set_value) Comment fix.
+
+       * som-high.c: (som_submit_table) Message fix.
+
+Wed Jan 22 21:54:00 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added SYSFILE INFO to command table.
+
+       * file-handle.q: (fh_handle_filename) New function.
+
+       * get.c: (save_trns_proc) Fixed a bug in padding of output data
+       with spaces.
+
+       * main.c: (parse) New return value for command functions, -3.
+
+       * misc.h: Comment fix.
+
+       * output.h: Comment fixes.
+       (macro COMPONENTS) Removed.
+
+       * postscript.c: (write_text) Modified literal_chars[] so that `('
+       and ')' are not written to the output in strings as literals.
+
+       * sfm-read.c: (sfm_read_dictionary) New argument.
+       (read_header) New argument.  Sets the information structure's
+       values from the header information.  
+       (read_variables) [__CHECKER__] Redefines isalnum()--some sort of
+       bizarre Checker problem, I guess.
+       (read_variables) Proper cleanup on lossage.
+
+       * sfm.h: (struct sfm_read_info) New struct for use by
+       sfm_read_dictionary().
+
+       * som-frnt.c: (som_create_table) New argument CREATE_FLAGS,
+       currently used just for tables that can be dynamically resized and
+       thus have to be allocated with arena_malloc() instead of
+       arena_alloc().  All references changed.
+       (som_change_table_size) New function.
+       (som_insert_table) Bugfix: now inserts `cell', not `c'!
+
+       * som-high.c: [GLOBAL_DEBUGGING] (check_table) Moved to som-low.c.
+       (som_submit_table) [GLOBAL_DEBUGGING] Doesn't call check_table()
+       any more.
+
+       * som-low.c: (draw_cell) Calls draw_table_cell() for SCON_TABLE
+       cells.
+       (draw_intersection) Now takes an argument specifying the table in
+       question.  All references changed.
+       (draw_table_cell) New function.
+       (som_get_table_size) [GLOBAL_DEBUGGING] Calls check_table().
+       (som_get_table_size) Many nice new explanatory comments.
+       [GLOBAL_DEBUGGING] (check_table) Moved here from som-high.c.
+
+       * som.h: New enum series SOM_CREATE_* for use as create flags with
+       som_create_table().
+
+       * str.h: Moved a comment here from TODO.
+
+       * sysfile-info.c: New file.  Reference implementation.
+
+Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added RENAME VARIABLES to table of commands.
+
+       * data-in.c: (dls_error) Sets `cust_field'.
+       (parse_N) Message fix.
+       (parse_day_count) New function.
+       (to_roman) Never outputs VX as a `short form' of V.
+       (parse_month) Fixed parsing of Roman numerals.
+       (parse_trailer) Message fix.
+       (parse_DATE, parse_ADATE, parse_EDATE, parse_SDATE, parse_JDATE,
+       parse_QYR, parse_MOYR, parse_WKYR, parse_DTIME) Issue a message if
+       the date is invalid.
+       (parse_SDATE) Fixed swapped day, year.
+       (parse_JDATE) Fixed bug for dates in 1582.
+       (parse_DTIME) Allows days not between 1 and 31.
+       (parse_numeric) Makes local copy of f.type for easier usage.
+       FMT_DOLLAR fixed.
+
+       * data-out.c: (convert_F) When outputting as scientific, properly
+       sets f.type as fp->type.
+       (insert_commas) Fixed operator precedence problem with setting of
+       nitems.  Changed strcpy to memcpy (no null terminator). 
+       (convert_date) Fixed FMT_JDATE: added 1900 to year.
+       (convert_CCx) Essentially rewritten, but now it works.
+
+       * display.c: (cmd_display) Added DISPLAY FILE LABEL (undocumented
+       feature of Fiasco).
+       (display_documents) Implemented.
+
+       * error.c: (glob var cust_field) New var.
+       (vmsg) Displays cust_field as part of message classes DE and DW.
+
+       * formats.c: (debug_print) Fixed to compile under updated
+       dictionary format.
+
+       * get.c: (cmd_get, cmd_save_internal) Close file handle on
+       failure.
+
+       * misc.c: (parse_format_specifier) Formatting fix.
+
+       * modify-vars.c: (struct var_modification) Renamed `n_reorder' as
+       `n_rename' for clarity.
+       (cmd_modify_vars) Initializes `forward' and `positional' at
+       appropriate times.  Frees lists of vars to rename on failure.
+       Comment fix.  Frees memory on success.  
+       (rearrange_dict) Simplified `for' loop condition.
+
+       * rename-vars.c: New file (reference implementation).
+       
+       * set.q: (internal_cmd_set) Fixed `emu' test condition.
+
+       * sfm-read.c: (read_header) File label is created only if file
+       label in file is not blank.
+       (read_variables) Initializes `dict' local variable.
+       (read_documents) Proper behavior on lossage.
+
+       * sfm-write.c: (write_header) Doesn't blank out the file label
+       (why was this here to begin with?!)
+
+       * temporary.c: (save_dictionary) File label is copied only if
+       non-NULL.  Doesn't try to xstrdup() dictionary documents.
+       Adapted so as to not irritate Checker.
+       (free_dictionary) Only destroys var_by_name if non-NULL.
+
+       * title.c: (cmd_file_label) Doesn't skip FILE, LABEL tokens.
+       (cmd_document) Doesn't skip DOCUMENT token.  Adds some header
+       lines to the document, indents the document.  Also, it works now.
+       (add_document_line) New function.
+
+       * var.h: (struct dictionary) Reordering.
+
+       * vars-prs.c: (parse_variables) On lossage, only local_free()'s
+       bits if it was allocated to begin with.
+
+Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added MODIFY VARS to list of commands.
+
+       * configure.in: Updated custom macros for autoconf 2.12.  Removed
+       mmap reference; fixed termcap library reference.
+
+       * display.c: (display_variables) Fixed a few bugs although it's
+       still not well written.
+
+       * error.c: [!__CHECKER__] (chkr_disp_call_chain) New function.
+       (induce_segfault) Calls chkr_disp_call_chain() instead of
+       inducing an actual SIGSEGV.
+
+       * expr-opt.c: (evaluate_tree) Swapped order of arguments to
+       str_search() and str_rsearch().  Fixed tests for matches on
+       OP_INDEX and OP_RINDEX.
+
+       * filename.c: (good_getcwd) Removed as the new libc for Checker
+       doesn't contain this bug, apparently.
+
+       * misc.c: (str_search, str_rsearch) Changed order of arguments for
+       consistency with GNU memmem.
+       (blp_getdelim) Changed `len' from `int' to `size_t'.
+
+       * modify-vars.c: Reference implementation.
+
+       * som-frnt.c: (zero_length) New global var.
+       (som_create_table) Message fix.
+
+       * som.h: Added gcc attributions to som_set_text(),
+       som_output_text() prototypes.  blank_line() refers to
+       zero_length[] instead of a literal null string to suppress gcc
+       warnings.
+
+       * sort.c: (do_external_sort) Fixed fencepost error on lossage.
+       (allocate_cases) Decrements x_max so the last element of x[] can
+       be used by the algorithm.
+
+       * var.h: Changed minor details of `variable' declaration.  
+       (struct modify_vars_proc) New struct.
+       (struct variable) Added field p.mfv.
+
+       * vars-atr.c: Comment fix.
+
+       * vars-prs.c: (fill_all_vars) More optimal implementation.
+
+       * vfm.c: (dump_splits) Sets the last byte of temp_buf to a null
+       character, which it shouldn't have to do but printf() seems to
+       read the null byte even though I supply a maximum length...
+
+Fri Jan 10 20:22:08 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Removed command alias X for QUIT.
+       (parse_cmd) Fixed comment parsing.
+
+       * dfm.c: (struct dfm_fhuser_ext) Fields `len', `size' are now of
+       type size_t.
+       (read_record) Fixed references to len, size.
+       (dfm_get_record) Restructured.
+
+       * file-handle.h: (struct file_handle) Field `lrecl' now of type
+       size_t.
+
+       * file-handle.q: (internal_cmd_file_handle) Checks for nonpositive
+       record length.
+
+       * modify-vars.c: New file.  Not complete.
+       
+       * set.q: (set_ccx) Fixed operator precedence problem regarding ^
+       and ==.
+
+       * sfm-read.c: (bswap_flt64, read_header, write_variable) Fixed
+       problems caused by int/size_t differences.
+
+       * sort.c: (output_record, merge_once) Cast `size_t's to `int's in
+       appropriate spots.
+
+       * str.c: (strcasecmp) Fixed bug that cropped up when the strings
+       being compared were of equal length.
+
+Thu Jan  2 19:08:23 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added DOCUMENT, DROP DOCUMENTS, FILE LABEL.
+
+       * lexer.c: (get_dotted_rest_of_line) New function.
+
+       * sel-if.c: (cmd_filter) Cannot choose string or scratch variables
+       as filters.
+
+       * sfm-read.c: (sfm_read_dictionary) Calls read_documents() to read
+       type 6 records.  Frees the dictionary properly.
+       (read_header) Initializes the dictionary instead of letting
+       read_variables() do it.  Sets the dictionary file label from the
+       system file.
+       (read_documents) New function.
+
+       * sfm-write.c: (sfm_write_dictionary) Calls write_documents() to
+       write type 6 record if appropriate.
+       (write_header) Writes file label from dictionary.
+       (write_documents) New function.
+
+       * temporary.c: (save_dictionary, restore_dictionary,
+       free_dictionary) Properly handle new fields in dictionary struct.
+
+       * title.c: (get_title) Returns after failure().
+       (cmd_file_label, cmd_document, cmd_drop_documents) New functions
+       for new commands FILE LABEL, DOCUMENT, DROP DOCUMENTS.  Untested.
+
+       * var.h: (struct dictionary) New fields `label', `n_documents',
+       `documents'.
+
+Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added FILTER to list of commands.
+
+       * frequencies.g: [WEIGHTING] Removed test for weighting!=-1 since
+       it's always true.
+
+       * get.c: (cmd_save_internal) Removed weighting code since it's now
+       handled by sfm-write.c.  Properly commented out debug code.
+
+       * glob.c: (glob var weighting) Removed.
+
+       * sel-if.c: Comment fixes.
+       (cmd_filter) New function.
+
+       * sfm-read.c: (struct sfm_fhuser_ext) New field `weight_index'.
+       (sfm_read_dictionary) Sets weighting variable direct in the
+       created dictionary now.  (Apparently we previously didn't support
+       weighting on GET?)
+       (read_header) Sets weight_index field in sfm_fhuser_ext from
+       header read from disk.
+
+       * sfm-write.c: (sfm_write_dictionary) Comment fix.
+       (write_header) Now sets the weighting in the header from the
+       passed primary dictionary instead of from the sfm_write_info.
+
+       * sfm.h: (struct sfm_write_info) Removed field `weight'.
+
+       * som-high.c: (dump_crush_table) Fixed a couple of assertions that
+       broke on boundary conditions.
+
+       * var.h: (struct dictionary) New fields `weight_var',
+       `weight_index', and `filter_var'.
+       (glob var weighting) Removed.  This is now part of struct
+       dictionary.  All references changed; the less mechanical changes
+       are described above.
+
+       * vars-atr.c: (find_dict_variable) New function.
+
+       * vfm.c: (static var filter_index) New variable.
+       (open_active_file) Initializes filter_index from default_dict.
+       (write_case) Calls proc_func() only if the filter variable is
+       nonzero; this implements FILTER behavior.
+
+       * weight.c: (static var weight_varname) Removed.
+       (cmd_weight) Modified default_dict instead of glob vars.
+       (update_weighting) Changed the signature to modify a dictionary
+       instead of glob vars.  Now returns the weighting variable.
+       (get_weighting_variable) Removed; its function is absorbed by
+       update_weighting().
+       (stop_weighting) Operates on a dictionary now.
+
+Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: Removed debugging info from messages.
+       (do_external_sort) Cleans up after itself by deleting the
+       temporary directory on failure.  (On success it is deleted by the
+       input program.)
+       (allocate_cases) Removed debug code.  Added clean up code.
+       (output_record) Removed debug code.
+       (merge) Added code to close all the input files that are currently
+       open.  This is a likely location for bugs, because I'm not sure
+       about boundary conditions.  Removed an unnecesary heap_delete().
+       (merge_once) Removed input file "optimization" that in fact
+       screwed up the rest of the code.  Message and comment fixes.
+
+Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
+
+       * error.c: [__CHECKER__] (induce_segfault) Flushes output streams.
+
+       * heap.c: (heap_delete) New argument.
+
+       * sort.c: Finished implementation of external sort.
+
+       * vfm.c: (read_from_disk) Returns after a disk error.
+
+Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: (static var state) Removed.
+       (static vars max_handles, tmp_basename, tmp_extname,
+       huffman_queue) New variables.
+       (do_external_sort) Moved most code to new functions.
+       Creates huffman_queue.
+       (allocate_file_handles, allocate_cases) New functions.
+       (static vars run_no, run_length, file_index, case_count) New
+       variables. 
+       (output_record) Returns success.  Now really writes to the output
+       file.
+       (begin_run, end_run) New functions.
+       (write_initial_runs) Returns success.  Initializes run_no to -1.
+       Calls begin_run(), end_run() at appropriate times.  Outputs debug
+       messages.
+       (write_to_sort_cases) Calls begin_run(), end_run() at appropriate
+       times.
+       (merge) New function.
+
+       * heap.c, heap.h: New files.  Hopefully in near-final form.
+
+Sat Dec 21 21:51:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       * glob.c: Added write_active_file to global vars.
+
+       * sort.c: Several new miscellaneous static variables.
+       (cmd_sort_cases) Big comment fix.
+       (perform_case_2) Renamed `do_external_sort' and completely
+       rewritten.
+       (case_2_proc_func) Removed.
+       (output_record, write_initial_runs, write_to_sort_cases,
+       compare_record) New functions.
+
+       * vfm.c: [DEBUGGING] (index_to_varname) Excised bit rot.
+
+Tue Dec 17 18:57:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: (perform_case_2) Changed the method for allocation of
+       lots of memory--now allocates one case at a time in hopes that
+       more cases can be allocated with heavily fragmented memory.
+
+       * var.h: (write_active_file) New global var.
+
+       * vfm.c: (procedure, close_active_file, write_case,
+       SPLIT_FILE_procfunc) Now allow beginfunc, procfunc, and endfunc
+       arguments to procedure() to be NULL.  All references to
+       procedure() that made use of dummy functions were changed to NULL
+       functions.
+       (open_active_file) If write_active_file is non-NULL, the output
+       device becomes DEV_PGM (a new enum).
+       (close_active_file) Sets write_active_file to NULL.
+       (read_from_memory) Comment fix.
+       (record_case) Calls write_active_file() when the output device is
+       DEV_PGM.
+
+Sun Dec 15 15:32:16 1996  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c: New file.
+
+       * autorecode.c: (cmd_autorecode) Fixed parsing of options.
+       Fixed checking for duplicate varnames.
+       (recode) xmalloc()'s the transformation instead of arena_alloc()'ing
+       it.
+       (autorecode_trns_free) Destroys hash tables for each recoding
+       specification.
+       (autorecode_proc_func) Compares NULL to *vpp instead of vpp.
+
+       * command.c: Added SORT CASES to cmd_table.
+       (null_func, null_int_func) Prototyped.
+
+       * descript.g: (calc_weight, calc_noweight) Computes own case
+       number now.
+       
+       * frequencies.q: (dump_statistics) Fixed problem with
+       too-few-cases warning message.
+
+       * get.c: (cmd_save_internal) Handles weighting properly.
+
+       * hash.c: (hsh_dump) Output format changed.
+       (force_hsh_insert) Actually works now, prototype changed.
+
+       * list.q: (static var case_num) New variable.
+       (cmd_list) Initializes case_num.
+       (list_cases) Increments case_num.
+
+       * var.h: Added definitions for SORT CASES.  Comment fixes.
+
+       * vfm.c: Some definitions moved to new file vfmP.h.  Comment
+       fixes.  `active' renamed vfm_active, `rep' renamed
+       vfm_replacement, all references changed.
+       (procedure) The procfunc no longer receives a case number.  All
+       references changed.
+       (write_case) Subtle reordering.
+       (SPLIT_FILE_procfunc) Counts cases differently.  Slightly less
+       redundant.
+
+       * weight.c: (get_weighting_variable) New function.
+
+       * vfmP.h: New file with definitions from vfm.c.
+
+Sat Dec 14 10:35:30 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (FILE_TYPE_okay) Commented out some tests because
+       they're clumsy and not yet needed.
+
+       * var.h: Most *_trns structures moved to their respective source
+       files.  Some were moved into a new file, do-ifP.h.  Comment fixes.
+       (union any_trns) Changed to a typedef for trns_header.
+       (struct input_program_pgm) Removed.
+
+       * vars-prs.c: (parse_variables) Only local_free()'s bits if it
+       was allocated in the first place.
+
+Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.c: New file.
+       
+       * command.c: Added AUTORECODE to command table; re-enabled SET.
+
+       * data-out.c: (convert_F) Handles infinities and NaNs properly.
+
+       * error.c: (vmsg) Comment fixes.
+
+       * hash.c: Comment fix.
+       (hashpjw_d) New function.
+       (hashpjw) Reimplemented as call to more general function
+       hashpjw_d().
+       (internal_comparison_fn) Initializes pointers properly.
+       (hsh_sort) [GLOBAL_DEBUGGING] New debugging code.
+       (force_hsh_insert, force_hsh_find) New debugging wrapper
+       functions.
+
+       * main.c: (main) Message fix.
+
+       * output.c: (outp_read_devices) Message fix.
+
+       * set.q: Comment fixes.
+       (custom_results) Implemented Wnd/X form of subcommand.
+       (set_routing) New function.
+       (internal_cmd_set) Implemented ERRORS, MESSAGES.
+
+       * settings.h: (SET_ROUTE_*) New enum series.
+       (set_results) Renamed set_results_file, all references changed.
+       (set_messages) Removed.
+       (glob vars set_errors, set_messages, set_results) New vars.
+
+       * title.c: (get_title) Remembers to xstrdup() the result of
+       get_rest_of_line().
+
+       * var.h: (arc_item, arc_spec, autorecode_trns) New structures for
+       use by AUTORECODE.
+       (union any_trns) New element `arc'.
+
+Fri Dec  6 23:53:47 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (output_line) Removed references to set_screen.
+
+       * error.c: (static var terminating) New var.
+       (hcf) Sets terminating to 1.
+       (vmsg) If terminating is nonzero, does not attempt to call hcf().
+       This prevents an infinite loop if an error occurs within hcf().
+
+       * expr-evl.c: (evaluate_expression) [__CHECKER__] Replaced case
+       statement circumlocution with `case 42000' trick.
+       (evaluate_expression) New support for OP_STR_MIS.
+
+       * expr-opt.c: (evaluate_expression) [__CHECKER__] Replaced case
+       statement circumlocution with `case 42000' trick.
+       (dump_node) Handles OP_STR_MIS.
+
+       * expr-prs.c: (MISSING_func, SYSMIS_func) Rewrote to handle string
+       variables exceptions.
+       (parse_function) Message fix.
+       (ops[]) Added OP_STR_MIS.
+
+       * expr.h: Added OP_STR_MIS to OP_* enum.  Comment fixes.
+
+       * exprP.h: [__CHECKER__] Removed case statement circumlocution.
+
+       * glob.c: Removed set_scrnfile glob var.
+       (init_glob) set_errorbreak set to 0 by default.
+
+       * groff-font.c: Changed included files.
+       (groff_read_font) Initializes font_arena local var correctly.
+       (default_font) New function.
+
+       * output.c: Comment fixes.
+       (glob var disabled_devices) New variable.
+       [GLOBAL_DEBUGGING] (static var iterating_driver_list) New
+       variable.
+       [GLOBAL_DEBUGGING] (reentrancy) New function.
+       [GLOBAL_DEBUGGING] (outp_read_devices, outp_done, find_driver,
+       outp_iterate_enabled_drivers) Calls to reentrancy().
+       (destroy_list) New function.
+       (outp_done) Moved code to destroy_list().
+       (parse_options) Parses `listing', `screen', `printer' options
+       internally.
+       (configure_driver) Sets new `device' member of driver.
+       (outp_iterate_enabled_drivers, outp_enable_device) New functions.
+
+       * output.h: Comment fixes.  New enum series OUTP_DEV_*.
+       (struct outp_driver_struct) New member `device'.
+
+       * postscript.c: (find_encoding_file) Doesn't display its own error
+       messages.
+       (default_encoding) New function.
+       (switch_font) Calls default_encoding() if no encoding can be
+       found.
+       (text) Makes up a character metric if none exists for the desired
+       character.
+       (load_font) Properly copies a fallback filename.  Calls
+       default_font() for a font if none at all are known.
+
+       * set.q: Comment fixes.  Removed OUTPUT subcommand.
+       (custom_listing) Calls outp_enable_device() to enable/disable
+       listing device.
+       (turn_screen_on) Removed.
+       (internal_cmd_set) Calls outp_enable_device() to enable/disable
+       screen, printer devices.
+
+       * settings.h: Comment fixes.
+       (glob vars set_output, set_printer, set_screen, set_scrnfile)
+       Removed.
+
+       * som-high.c: (som_submit_table, som_eject_page) Use
+       outp_iterate_enabled_drivers() instead of iterating
+       outp_driver_list directly.
+
+Wed Dec  4 21:34:17 1996  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: (parse_EDATE, parse_SDATE) New functions.
+       (parse_string_as_format) Handles new formats.
+       (parse_numeric) Now handles DOT and PCT formats.
+
+       * data-out.c: (convert_E, convert_F, insert_commas) Handle DOT
+       format now.
+       (convert_date) Handle EDATE and SDATE formats.
+       (convert_CCx) Now if there's not room for the currency characters,
+       converts it as F format if it's positive instead of giving up
+       quickly.  Also fixed save-and-restore bug with decimal point
+       characters.  
+       (convert_format_to_string) Handles new formats.
+
+       * misc.c: (formats[]) Added new formats.
+       (convert_fmt_ItoO) Supports new formats.
+
+       * sfm-read.c: (parse_format_spec) Supports new formats.  Better
+       data checking.  New argument, all references changed.
+
+       * sfm-write.c: (write_format_spec) Supports new formats.
+
+       * var.h: New formats FMT_DOT, FMT_PCT, FMT_EDATE, FMT_SDATE.
+       Comment fixes.
+
+Sun Dec  1 17:19:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: Comment fixes.
+       (parse_command_line) Changed return type to void.
+
+       * data-in.c: (parse_string_as_format) Added FMT_CCA...FMT_CCE to
+       switch.
+       (parse_numeric) Handles international numbers (comma as decimal
+       point).  Some reformatting.
+
+       * data-list.c: (parse_free) Default output format is now
+       set_format instead of hard-coded F8.2.
+       (read_from_data_list_list) Emits error message on undefined data
+       only if set_undefined is nonzero.
+
+       * data-out.c: (convert_E) Changes decimal point from period to
+       comma if appropriate.  Restructured.  Better comments.
+       (convert_F) Changes decimal point from period to comma if
+       appropriate.
+       (insert_commas) Major bug with handling of negative values fixed.
+       Also, inserts periods instead of commas if appropriate.
+       (convert_CCx) New function.
+       (convert_format_to_string) Added FMT_CCA...FMT_CCE to switch.
+       (num_to_string) Changed `.' to set_decimal.
+
+       * dfm.c: Comment fixes.
+       (dfm_close) Frees ext->line even in inline_file.
+       (open_inline_file) New function.
+       (open_file_r) When opening the inline file: now properly
+       recognizes `BEGIN DATA.' line, and calls open_inline_file() to
+       finish up.
+       (read_record) Calls fh_close_handle() instead of dfm_close() to
+       close the inline file.  Makes a copy of the line getl_buf to avoid
+       interlock problems.
+       (dfm_get_record) Restructured.  Now checks the return value of
+       open_file_r().
+       (cmd_begin_data) Moved open code into open_inline_file().  Relaxed
+       checking for use of inline file.  No longer tries to close inline
+       file.
+
+       * error.c: (glob var error_already_flagged) New var.
+       (vmsg) Message change.  Now checks max number of errors/warnings,
+       acts on it.
+
+       * file-handle.q: (fh_handle_name) Now allows closing of
+       inline_file.
+       (fh_init_files) Reformatted.
+
+       * get.c: (trim_dictionary) Checks SCOMP option instead of COMP.
+
+       * getline.c: (getl_include) Fixed bug that popped up when called
+       when file queue was empty.
+       (read_console) Resets error_count, warning_count,
+       error_already_flagged to zero.
+
+       * glob.c: Many changes to update list of variables.
+       (init_compat_dependent) Now this function is called whenever
+       `compat' changes.  It now sets set_seed only if it hasn't
+       previously been referenced.  It now calls
+       lex_init_compat_dependent().
+
+       * include.c: (cmd_include_at) Frees temporary buffer instead of
+       line buffer.  
+       (cmd_include) Doesn't make copy of include file name.
+
+       * lexer.c: Comment fixes.
+       (init_lex) Moved some code into new function
+       lex_init_compat_dependent().
+       (lex_init_compat_dependent) New function.
+       (hex_val) Simplified.
+       (preprocess_line) Uses set_endcmd instead of hardcoding `.'.
+
+       * main.c: Comment fixes.
+       (main) Reformatted.
+
+       * misc.c: (formats[]) Added FMT_CCA...FMT_CCE.
+       (check_input_specifier) Disallows FMT_CCA...FMT_CCE.
+       (convert_fmt_ItoO) Detects FMT_CCA...FMT_CCE.
+       (setup_randomize) Sets set_seed_used.
+
+       * set.q: Comment fixes.
+       (custom_results) Conditionalizes on `compat'.
+       (custom_log) Calls custom_journal().
+       (set_ccx) New function.
+       (cmd_set) Calls init_compat_dependent() when `compat' changes.
+       Calls set_ccx() to handle CCA...CCE.  Sets set_grouping
+       when set_decimal changes.  Range-checks values for MITERATE,
+       MNEST.  Message fixes.
+
+       * settings.h: Comment fixes.
+       (struct set_cust_currency) New struct.
+       (set_cc[], set_grouping, set_seed_used) New global vars.
+
+       * var.h: (FMT_CCA...FMT_CCE) New output formats.
+       (FCAT_OUTPUT_ONLY) New FCAT_* constant.
+
+Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
+
+       * glob.c: Revised variables to correspond to settings.h.
+       (init_glob) Initializes variables from settings.h properly.
+
+       * set.q: Began long-overdue major revision to correspond to new
+       philosophy.  Most code changed. 
+
+       * settings.h: Mostly changed; reorganized, reordered, large new
+       comment.
+
+Thu Nov 28 19:46:10 1996  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (cmd_save_internal) No longer forces compression off.
+
+       * sfm-read.c: (read_compressed_data) If eof is reached when
+       reading a new instruction octet, only signal error if we're in the
+       middle of a case.
+
+       * sfm-write.c: (COMPRESSION_BIAS) New #define.
+       (struct sfm_fhuser_ext) New member `end'.
+       (write_header) Refers to COMPRESSION_BIAS instead of magic 100.0.
+       (ensure_buf_space) New function.
+       (sfm_write_case) Reimplemented in order to support compression.
+       (sfm_close) Writes out the remaining contents of the compression
+       buffer if any.
+
+Wed Nov 27 23:18:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Defined SAVE and XSAVE commands in command table.
+
+       * common.h: second_lowest_value is of type flt64, not double.
+
+       * file-handle.h: Comment fix.
+
+       * get.c: Comment fixes.
+       (static var `trns') New.
+       (save_write_case_func, save_trns_proc, save_trns_free, null_func,
+       cmd_save_internal, cmd_save, cmd_xsave) New functions.
+       (dict_delete_run) Clears the variables and frees them now.
+       (trim_dictionary) Sets default for compression.
+       On KEEP subcommand, frees deleted variables as well as clearing
+       them.  Finally got the sense of the test for deleting all
+       variables correct.
+       [DEBUGGING] (dump_dict_variables) Message fix.
+
+       * glob.c: (init_glob) set_compression set to 1 by default.
+
+       * list.q: Properly #includes config.h.
+
+       * misc.h: New macro REM_RND_UP.
+
+       * settings.h: Comment fix.
+
+       * sfm-read.c: (structs sysfile_header, sysfile_format,
+       sysfile_variable; inline function bswap_int32) Moved to new file
+       sfmP.h.
+       (corrupt_msg) [__CHECKER__] No longer induces segfault.
+       (sfm_read_dictionary) Fixed bug caused by failing to initialize
+       var_by_index.
+       (read_machine_flt64_info) Fixed some problems caused by confusion
+       between flt64 and double types.
+       (read_header) Message fix.
+       (read_variables) Fixed set of cases in which we byte-swap sv.print
+       and sv.write.  Fixed confusion of flt64 and double.
+
+       * sfm.h: (struct sfm_write_info) New.
+
+       * som-high.c: (som_draw_title) Properly frees `s'.
+
+       * temporary.c: (save_dictionary) Comment fix.
+
+       * var.h: Comment fixes.  New FMT_* enum, FMT_NUMBER_OF_FORMATS.
+       (struct trns_header) Formatting fix.
+       (struct save_trns) New.
+
+       * vars-atr.c: (discard_variables) Comment fix.
+
+       * sfm-write.c: New file, baseline release.
+
+       * sfmP.h: New file, baseline release.
+
+Sun Nov 24 14:53:53 1996  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: (parse_command_line) `--version' output updated.
+       (glob var syntax_message[]) Added my e-mail address.
+
+       * file-handle.q, lexer.c, vfm.c: Changed many instances of
+       `illegal' to `invalid'.
+
+       * sfm-read.c: (struct sfm_fhuser_ext) New fields used as
+       uncompression buffer.
+       (sfm_close) Frees decompression buffer.
+       (sfm_read_dictionary) Initializes decompression buffer.
+       (buffer_input, read_compressed_data) New functions.
+       (sfm_read_case) Restructured; now calls read_compressed_data() to
+       handle compressed system file data.
+
+       * var.h: Comment fix.
+
+Mon Nov 11 15:34:09 1996  Ben Pfaff  <blp@gnu.org>
+
+       * dfm.c: (dfm_close) Does not set h->{ext,class} because the
+       caller handles it.
+        
+       * get.c: New comments.  New static var `get_file'.
+       (cmd_get) Now fully implemented.  Calls discard_variables();
+       initializes fv and lv for all variables; new debug code; sets
+       up the dictionary; sets up the input program.
+       (read_from_get, cancel_get) New functions.
+
+       * sfm-read.c: Comment fixes.
+       (sfm_close) New static function.
+       (sfm_read_dictionary) Properly sets up the class of the
+       file_handle.  No longer cares what size the data is in records of
+       type 7.  Also, on failure, properly cleans up the file_handle and
+       free()s some stuff.
+       (read_variables) No longer thinks it knows `nval' of the
+       dictionary.  Now sets p.get.fv, etc., instead of speculatively
+       setting fv itself.
+       (read_value_labels) Fixed off-by-one error in indexing of
+       var_by_index[].
+       (sfm_read_case) New function.
+       (sfm_r_class) New static var.
+
+       * var.h: (get_proc) New struct.
+       (struct variable) New member p.get.
+
+Thu Nov  7 20:52:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Removed GTSV_OPT_MAP because of a misinterpretation of
+       the manual's meaning.
+       (rename_variables) New function.
+       (trim_variables) Doesn't try to parse MAP any more.  Removed debug
+       code.  Now properly reorders the dictionary on the KEEP keyword.
+
+       * sfm-read.c: (read_value_labels) Fixed some bugs regarding
+       garbage collection.
+
+       * vars-atr.c: (clear_variable) New argument `dictionary *'.
+       (rename_variable) New function.
+       (free_val_lab) Reformatted.
+
+Thu Nov  7 17:29:16 1996  Ben Pfaff  <blp@gnu.org>
+
+       * var.h: Reindented entire file.  Comment fixes.
+       (glob vars var, var_by_name, nvar, N, nval, n_splits, splits)
+       Removed.
+       (glob var default_dict) New.
+       (struct indirect_dictionary) Removed.
+
+       * Many other source files were changed to add `default_dict.'
+       before all references to the dictionary of the active file.
+       
+       * vars-atr.c: (make_indirect_dictionary) Removed.
+
+       * glob.c: Reindented all variable declarations.  Updated for
+       changed var.h.  Comment fixes.
+
+       * temporary.c: (restore_dictionary, save_dictionary) Simplified
+       because now we can mainly copy dictionary structs.
+
+       * vars-prs.c: (is_dict_varname, parse_dict_variable,
+       parse_variables) Takes dictionary instead of indirect_dictionary
+       first argument.
+       (parse_variables) Instead of calling make_indirect_dictionary,
+       just sets DICT to &default_dict if DICT is NULL.  Of course, lots
+       of `*dict.' references had to be changed to `dict->'.  Removed
+       debug code.
+
+Thu Nov  7 15:48:52 1996  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Added GTSV_OPT_* series of enums.
+       (trim_dictionary, dict_delete_run) New functions.
+       [DEBUGGING] (dump_dict_variables) New function.
+       (cmd_get) Calls trim_dictionary() to get dictionary fully set-up.
+       [DEBUGGING] Calls dump_dict_variables() to display results.
+
+       * glob.c: (cmp_variable) Now a public function declared in var.h.
+
+       * sfm-read.c: Turned off debug code.  Comment fixes.
+       (read_machine_int32_info, read_machine_flt64_info) New functions
+       to parse type 7 records.
+       (sfm_read_dictionary) Properly byteswaps several fields now.
+       Calls read_machine_*_info() to parse type 7 subtypes 3 and 4
+       records.  [DEBUGGING] Dumps dictionary.
+       (read_variables) Sets `index' field of variables created properly.
+       Constructs avl tree of variables in dictionary.  [DEBUGGING] No
+       longer dumps dictionary.
+       (read_value_labels) Properly byteswaps fields.  [DEBUGGING] New
+       debug code.
+       [DEBUGGING] (dump_dictionary) No longer stubbed out.
+
+       * temporary.c: (restore_dictionary) Destroys `var_by_name' glob
+       var before destroying any variables just to save a little time.
+
+       * var.h: (struct variable) Reordered in order to make name[] the
+       first member; this makes pointers to `variable' pointers to the
+       variable name, simplifying avl trees, etc.
+       (struct indirect_dictionary) New struct.
+
+       * vars-atr.c: (find_variable) Rewritten for efficiency.
+       (make_indirect_dictionary, is_dict_varname, parse_dict_variable)
+       New functions.
+       (is_varname) Rewritten for efficiency.
+       (parse_variables) New argument, which is a `dictionary *'.  All
+       references changed.  This function now reads variable names from
+       the dictionary passed, or from the default dictionary if NULL.
+
+Tue Nov  5 18:34:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * misc.h: Added new macro DIV_RND_UP to perform integer division,
+       rounding up.  Changed many references to ROUND_UP to use this
+       instead.
+
+       * sfm-read.c: Includes avl.h.
+       (corrupt_msg) Induces a segfault under Checker.
+       (macro assertive_bufread) New.  Many references to bufread() now
+       use this instead.
+       (sfm_read_dictionary) Split up into several functions.  Added code
+       to read dictionary records following the the type 2 records.  Not
+       quite complete.  New variable `var_by_index'.
+       (read_header, read_variables) New functions extracted from
+       sfm_read_dictionary().
+       (read_value_labels) New function.
+       (bufread) Checks ferror() if fread() doesn't return the expected
+       value; if ferror() is zero it's just EOF.
+       (dump_dictionary) Stubbed out.
+
+       * BTW: The source code now exceeds 50000 lines!
+       
+Mon Nov  4 22:03:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added GET to cmd_table[].
+
+       * list.q: Removed reference to alloca headers.
+       (cmd_list) Gave prototype.
+
+       * sfm-read.c: Added DEBUGGING comments.
+       (sfm_read_dictionary) Checks bias correctly.  Sets
+       dict->var_by_name to NULL.  Calculates long_string_count
+       correctly.  realloc's dict->var[] array to minimum size.
+       [DEBUGGING] Calls dump_dictionary.
+       [DEBUGGING] (dump_dictionary) New function.
+
+       * temporary.c: (save_dictionary) Sets var_by_name to NULL.
+       (restore_dictionary) If the dictionary contains a non-NULL
+       var_by_name, uses that instead of generating one.
+       (free_dictionary) Destroys var_by_name.
+
+       * var.h: (struct dictionary) Added field `var_by_name'.
+
+       * get.c: New file, not complete.
+
+Sun Nov  3 12:24:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * mis-val.c: New enums MV_NOR_*.  New struct num_or_range.
+       (parse_num_or_range) New function.
+       (parse_numeric) Reimplemented in order to support LOW THRU <n> and
+       <n> THRU HIGH missing values.
+
+       * output.h: [__GNUC__>1 && __OPTIMIZE__] (width, height) Made
+       __attribute__((const)).
+
+       * q2c.c: (get_token) Merged isdigit || isalpha into isalnum.
+
+       * sfm-read.c: Finished reference implementation.
+
+       * sfm.h: Includes var.h.
+
+       * var.h: Comment fixes.
+       (struct `variable') Reordered some fields.
+
+       * vars-atr.c: (is_num_user_missing) Added support for MISSING_*
+       constants added previously.
+
+Wed Oct 30 17:13:08 1996  Ben Pfaff  <blp@gnu.org>
+
+       * common.h: Comment fixes.  Added declaration of
+       `second_lowest_value' as variable or macro.  Made `compat_type',
+       `pgm_state_type' into anonymous enums.
+
+       * display.c: Comment fix.
+
+       * glob.c: [ENDIAN==UNKNOWN] Added definition for `endian' global
+       var.
+       [!defined SECOND_LOWEST_VALUE] Added definition for
+       `second_lowest_value' global var.
+       (compat, pgm_state global vars) Changed types to `int'.
+       (init_glob) Initializes `second_lowest_value'.
+
+       * sfm-read.c: Continued work, not complete.
+
+       * var.h: Added new MISSING_* constants to handle LOWEST and
+       HIGHEST.
+
+Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
+
+       * sfm-read.c: New file, not complete.
+
+       * cases.c: (vec_insert) Changed vector expansion algorithm.
+       (vec_delete) Fixed bug that screwed up deletion sometimes, it was
+       mucking up the RECODE transformation in particular.
+       (envector) Harmless change in notation.
+
+       dfm is now fairly well tested again.  
+       * dfm.c: (dfm_get_record) Only returns ext->ptr if ext is
+       non-NULL--duh.
+       (cmd_begin_data) if(ext->line) replaced by if(ext && ext->line).
+
+       * recode.c: Comment fix.
+
+       * sfm.h: Interface should be fairly final now, or at least for a
+       day or so...
+
+       * vfm.c: [DEBUGGING] (index_to_varname) New function.
+       (open_active_file) [DEBUGGING] Translates ccase indices into
+       variable names now to make it easier to understand what's really
+       going on.
+
+Sat Oct 26 20:46:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: Comment fix.
+
+       * data-list.c: Includes dfm.h.
+       (do_reading) Uses new function dfm_push_cust().
+
+       * data-out.c: (convert_time, convert_WKDAY, convert_MONTH) Added
+       `return 1;' at end.
+
+       * file-handle.h: Completely changed.  Some parts split off into
+       new file dfm.h.  Implemented in file-handle.q.
+       (enum FH_*) Removed.
+       (struct fh_ext_class) New struct.
+       (struct file_handle) Retained only these fields: name, norm_fn,
+       fn, recform, lrecl, mode.  New fields class, ext.
+       (get_handle_by_name, get_handle_by_filename, parse_file_handle,
+       close_handle, handle_name) Added `fh_' prefix to name, all
+       references changed.
+
+       * dfm.h: New file, implemented in dfm.c.
+       (get_record, put_record, fwd_record, bkwd_record, set_record,
+       get_cur_col) Functions moved from file-handle.h, now prefixed with
+       `dfm_'.
+       (dfm_push_cust) New function.
+
+       * sfm.h: New file.  Incomplete.
+
+       * dfm.c: All functions adjusted/rewritten for new dfm/fhp
+       interface.  Functions reordered, comments changed.  Not well
+       tested, probably full of bugs.
+       (struct dfm_fhuser_ext) New struct.
+       (dfm_close) New function.
+       (open_file_r) Pickier about finding `BEGIN DATA.' line.
+       (open_file_w) User messages changed.
+       (get_record) Comment fixed.
+       (read_record) Increments ext->ln even for inline_file.  Calls
+       dfm_close() for inline_file when `END DATA.' encountered.
+       (dfm_get_record) Experimental restructuring.
+       (dfm_push_cust) New function.
+       (cmd_begin_data) Detects whether the inline file was fully read by
+       checking whether it is still open; detects whether it was read at
+       all by checking whether the line number is greater than zero.
+
+       * file-handle.q: All functions adjust/rewritten for new dfm/fhp
+       interface.  Functions reordered, comments changed.  Not well
+       tested, probably full of bugs.
+       (init_file_handle) Removed initializers for obsolete fields, added
+       new fields.
+       (fh_close_handle) Much simpler, now mainly calls the class
+       function.
+       (fh_init_files) Renamed inline file internal filename.
+
+       * file-type.c: Includes dfm.h.
+       (read_from_file_type) Doesn't use dfm internal state anymore.
+
+       * inpt-pgm.c, print.c: Include dfm.h.
+
+       * recode.c: (internal_cmd_recode) Casts strlen() return value to
+       int in comparison with other int.
+
+       * som-high.c: (build_target) Fixed operator precedence problem in
+       if statement (& versus ==).
+
+Sat Oct 26 10:39:25 1996  Ben Pfaff  <blp@gnu.org>
+
+       * dfm.c: (read_record) Can now read fixed-length records; not
+       tested.
+       (put_record) Can now write fixed-length records; not tested.
+
+       * file-handle.h: FH_* defines changed to enums.  New enum series
+       FH_RF_*, FH_MD_*.
+       (struct file_handle) New members recform, lrecl, mode.
+
+       * file-handle.q: Parser changed.
+       (internal_cmd_file_handle) Added support for new /RECFORM, /MODE,
+       /LRECL subcommands.  These are compatible with Windows.
+       (init_file_handle) Initializes recform, mode fields.
+
+       * q2c.c: (get_line) When outputting `!' comment lines, now
+       increments the output file line number so that `#line' directives
+       are correct.
+       (make_identifier) New function that converts an arbitrary string
+       into a valid C identifier.
+       (dump_vars) Calls make_identifier() in two places in order to
+       suppress some errors for bad identifiers.
+       (make_match) Allows TRUE as synonym for YES and FALSE as synonym
+       for NO.  Allows numbers to be prefixed by underscores to make them
+       acceptable C identifiers but still to be parsed as numbers by the
+       Fiasco lexer.
+
+Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Re-enabled RECODE, SAMPLE, SELECT IF.
+       
+       * dfm.c: Comment fixes. (get_record) Gives error if file handle
+       was opened for writing.
+       (open_file_w) New function.
+       (read_record) Uses strncasecmp if available.  Improved error
+       messages, comments.
+       (put_record) New function.
+
+       * file-handle.h: Moved function comments into dfm.c and
+       file-handle.q.  Comment fixes.  Removed declarations of
+       tilde_expand() and normalize_filename().
+       (struct file_handle) Changed `open' from boolean to enumerated
+       field to allow for three states--closed, open for reading, open
+       for writing--all references changed.
+
+       * file-handle.q: Includes filename.h.
+
+       * print.c: (CMD_* enums) Renamed PRT_* and moved into var.h; all
+       references changed.
+       (alloc_line) Makes allowance for line terminator characters in
+       calculations.
+       (print_trns_proc) Now handles OUTFILE, WRITE differences.
+       (print_space_trns_proc) Handles OUTFILE differences.
+
+       * recode.c, sample.c: Comment fixes.
+
+       * var.h: (struct print_trns) Changed boolean field `eject' to
+       bitmapped field `options'; all references changed.  New enums
+       PRT_* for use with this field.
+
+       * exception.h, test-exception.c: Removed.
+
+Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (delineate) Turned off debug output.
+
+       * common.c: [Checker and Linux] (__assert_fail, __eprintf) Moved
+       to error.c.
+
+       * data-in.c: (parse_string_as_format) Sets the entire string value
+       to spaces, not just the short string part of it.  Is this correct
+       now? 
+
+       * data-out.c: (convert_date) Fixed DATETIME format problems with
+       decimal places, removed debug code.
+
+       * dfm.c: (open_file_r) Fixed bug where an error would occur in the
+       middle of parsing BEGIN DATA that would cause the lexer to read
+       from a wild pointer `prog'; now calls new function
+       preprocess_line() in lexer.c.
+
+       * error.c: [__CHECKER__] (hcf) Calls induce_segfault() on improper
+       termination.
+       [Checker and Linux] (__assert_fail, _eprintf) Moved from common.c.
+       Now call induce_segfault() to induce the segfault.
+       (induce_segfault) New function.
+
+       * expr-opt.c: Comment fix.
+       (parse_sysvar) New function.
+       (parse_primary) Added system variable support--calls
+       parse_sysvar().
+       (global var ops) Added OP_CASENUM operator.
+
+       * expr.h: Comment fixes.
+       (OP_* enum) added OP_CASENUM operator.
+       (struct casenum_node) New struct.
+       (union any_union_union) New member `cas' of type `casenum_node'.
+
+       * glob.c: (global var last_vfm_invocation) New var.
+       (init_glob) Initializes last_vfm_invocation.
+
+       * lexer.c: (lookahead) Fixed reversed condition on if statement.
+
+       * getline.c: (get_line) Split into get_line() and preprocess_line().
+       (preprocess_line) New function.
+
+       * var.h: Declares last_vfm_invocation.
+
+       * vfm.c: (procedure) Sets last_vfm_invocation.
+
+Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (parse_cmd) Fixed bad assertion related to
+       lookahead().
+
+       * data-in.c: (parse_month) Implemented to parse months according
+       to full interpretation of standard.
+       (to_roman) New function.
+       (parse_wk_delimiter) Bug fix (forgot to skip `WK' in string).
+       (parse_weekday) Bug fix (forgot to skip all the day name).
+
+       * data-list.c: (read_from_data_list_fixed) Fixed bug that screwed
+       up parsing of multirecord data items.  Also fixed user message.
+
+       * data-out.c: Comment fix.
+       (year2, year4, convert_date, convert_time, convert_WKDAY,
+       convert_MONTH) New functions to support time & date output.
+       (convert_format_to_string) Calls new time & date output routines.
+
+       * expr-prs.c: (nary_num_func) Found a bug, but didn't fix it yet.
+
+       * lexer.c: (lookahead) Noted a previously unnoticed caveat in
+       comment.
+
+       * main.c: [DEBUGGING] (dump_token) Updated to handle getline.h.
+
+       * misc.c: (global var formats) Fixed declarations of DATETIME,
+       TIME, DTIME.
+
+       * postscript.c: (text) Fixed a pair of bugs in the reallocation of
+       the output_char buffer.
+
+       * vars-prs.c: (parse_DATA_LIST_vars) Fixed a failure to free
+       memory bug.  Fixed user messages.
+
+Tue Oct 22 17:27:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Removed #pragma argsused from lots of places.
+       
+       * data-in.c: Implemented zoned decimal and time-date formats.
+       Untested.  This is a huge chunk of code--maybe 1000 lines and 50
+       new functions.
+
+       * data-out.c: Implemented zoned decimal format.
+
+       * expr.h: Moved yrmoda() declaration here from exprP.h.
+
+       * misc.c: (global var formats) Minor fixes--added
+       FCAT_SHIFT_DECIMAL to formats N and Z.
+       (convert_fmt_ItoO) Added support for format Z.
+
+       * som-frnt.c: (som_set_value) Fixed bug regarding string values.
+
+Mon Oct 21 20:39:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (parse_cmd) [GLOBAL_DEBUGGING] Inserted call to
+       som_check_workspace() that is activated between commands.
+
+       * data-list.c: (dump_fixed_table, dump_free_table) Finished these
+       for good, I hope.
+
+       * list.q: (begin_row) Changed title expansion style from
+       SOPT_X_VERT to SOPT_X_SHSP.
+
+       * som-frnt.c: Now includes `somP.h'.
+       (som_push_workspace, som_pop_workspace) New functions that, taken
+       together, form a solution to the recursive table building problem
+       mentioned yesterday.  Surrounded every table output routine
+       throughout the program with calls to these functions.
+       [GLOBAL_DEBUGGING] (som_check_workspace) New function.
+       (som_create_table) Checks that there's an active workspace.
+       (som_destroy_all_tables, som_crush) Removed.
+
+       * som-high.c: (global var som_preserve_tables) Removed, all
+       references deleted.
+       (som_submit_table) Checks that there's an active workspace.
+       (dump_columnated_table) Doesn't columnate tables that would have
+       just one row per column.
+       (dump_crush_page, som_dump_crush_page) Removed debugging code.
+       (som_dump_crush_page) Moved row number labels from left side of
+       tables to right side.
+       (som_get_table_size) Added support for SOPT_X_SHSP.
+
+       * som.h: New cell expansion type SOPT_X_SHSP.
+
+       * somP.h: (global vars arena_stack, n_arena_stack, m_arena_stack)
+       New vars.
+       (global var curtab_arena) Moved from som-frnt.c.
+
+Sun Oct 20 13:45:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: [GLOBAL_DEBUGGING] (SUPPRESS_WARNINGS) New debug option
+       that causes bad location warnings to be suppressed.
+       (delineate) Saves current font when calling draw_text(); fixed
+       handling of NULLs when backing up.  Also fixed line-wrapping bug.
+
+       * command.c: Re-enabled `LEAVE', `NUMERIC', `PRINT', `PRINT EJECT',
+       `PRINT FORMATS', `PRINT SPACE', `STRING', `TITLE', `WRITE'.
+
+       * common.c: Added code to cause assertion failure to dump core
+       when run under Checker.
+
+       * data-list.c: (dump_fixed_table) Fixed some inconsistencies, but
+       there are still bugs.
+
+       * glob.c: (__eprintf) Removed.
+
+       * list.q: Inserted som_preserve_tables kluge that prevents tables
+       from being thrown away due to recursive table building through
+       som_output_line being called from a transformation during the LIST
+       procedure invocation.  This is a general problem that must be
+       solved in a better way since it applies to all procedures in
+       general.
+       (begin_row) Changed title options to SOM_X_VERT from SOM_X_BOTH.
+       (flush_table) Removed SOM_TOPT_PRESERVE from submission options.
+
+       * numeric.c: Fixed several errors in the form of msg() calls.
+
+       * print.c: Updated for use of som.
+       (dump_table) Reimplemented.
+       (print_trns_proc) Calls som_eject_page() instead of eject_page().
+       Calls som_output_text() instead of outs_line().
+
+       * som-frnt.c: (som_destroy_all_tables) Sets som_preserve_tables to
+       0.
+       (som_output_text) Function moved from som-low.c.  Interface
+       changed.
+
+       * som-high.c: (som_preserve_tables) New global public variable
+       declared in som.h.
+       (som_submit_table) Destroys the tables only if som_preserve_tables
+       is 0.
+       (paginate_horizontally) Bugfix: sets som.mpw even if there's only
+       one subrow per row.  Now labels subrows if there's more than one
+       subrow per row.
+       (dump_crush_table) Added wishlist comment.
+       (som_eject_page) New public function declared in som.h.
+
+       * som-low.c: (som_dump_crush_page) Draws row labels if there's
+       more than one subrow per row.
+       (som_output_text) Moved to som-frnt.c.
+
+       * som.h: (SOM_TOPT_PRESERVE) Removed.
+
+       * title.c: (get_title) Changed interface.
+       (cmd_title) Changed `title' to `outp_title'.
+       (cmd_subtitle) Changed `subtitle' to `outp_subtitle'.
+
+Sun Oct 20 09:04:15 1996  Ben Pfaff  <blp@gnu.org>
+
+       * list.q: (flush_table) Conforms to new partial options in
+       som_submission_form.
+
+       * som-high.c: (paginate_horizontally) Changed form of subrow
+       number labels.
+       (build_target) Omits spacing before table if
+       SOM_TOPT_PARTIAL_OMIT_TOP is selected.
+       (dump_crush_page) Changed interface.  Only trims bottom rule if
+       SOM_TOPT_PARTIAL_OMIT_BTM is not selected.
+       (dump_crush_table) Handles partial tables.
+       (output_row_label) New function.
+       (som_dump_crush_page) Emits subrow number labels.  Draws vertical
+       rule on the right edge of narrow subrows.
+
+       * som.h: Changed SOM_SUB_PARTIAL_* series of submission type
+       constants to a series of SOM_TOPT_PARTIAL_* submission options.
+       All references updated.
+
+Fri Oct 18 19:46:49 1996  Ben Pfaff  <blp@gnu.org>
+
+       * misc.c: Comment fix.
+
+       * som-high.c: (examine_table) Treats crushed tables separates for
+       purpose of determining header size.
+       (paginate_horizontally) Allots space for line numbers in crushed
+       tables with lots of subrows per row.  Calculates the `maximum page
+       width', the width of the widest horizontal page.
+       (build_target) Removed trim argument; all references changed.
+       Stricter assertions.  (dump_crush_page) New function.
+       (dump_crush_table) Reimplemented.
+
+       * som-low.c: (som_dump_page) Uses new RULE_ROW &c. constants.
+       (som_dump_crush_page) Reimplemented, interface changed.
+
+       * somP.h: Many many new helper macros for use with crushed tables.
+       (global var som) Removed `tv', `cum_y' members; all references
+       removed.  New members `mpw', `digit_space'.
+
+Sun Sep 29 19:37:03 1996  Ben Pfaff  <blp@gnu.org>
+
+       * arena.c: (arena_alloc) [!DISCRETE_BLOCKS] Removed `size'
+       variable, changed to constant 1024.
+       (arena_ca_strdup) Changed `sizeof(a_string)' to
+       `sizeof(c_string)'.
+       (arena_ca_strdup) [!DISCRETE_BLOCKS] Changed bad cast from
+       `(c_string *)' to `(char *)'; this fixed some offset problems.
+
+       * filename.c: (readlink_malloc) Changed initial allocation from
+       100 bytes to 128.
+       (good_getcwd) Changed from xmalloc() to local_alloc(); removed
+       comment.
+
+       * postscript.c: (read_fontmap) Fixed leak by changing &owner to
+       &fm->owner in several places.
+
+       * som-high.c: (output_table) Changed interface to rest of world.
+       (examine_crush_table) Removed.  Crushed tables are re-broken now,
+       in preparation for rewrite.
+
+       * som.h: Comment fix.
+
+Sat Sep 28 21:28:07 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_init_driver) Disposes of x->file.filename and x
+       itself in the cleanup stage.
+
+       * descript.q: (display) At least temporarily, changed the table
+       format to a crushed table.
+
+       * list.q: (begin_row) At least temporarily, added horizontal lines
+       between cases.
+
+       * som-high.c: (examine_crush_table) Sets som.hh to the width of
+       the horizontal "headers," that is, to the width of the far left
+       and far right rules.
+       (justify_pagination) Sets som.th to the width of the widest row
+       in the crushed table.  Fixed inner loop off-by-one error.
+
+       * som-low.c: (som_dump_crush_page) Added code to draw horizontal
+       rules.
+
+       * somP.h: Comment fix.
+
+Fri Sep 27 20:08:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * filename.c: (open_file_ext) Now, doesn't set f->file to NULL
+       before closing it; also, opens the constructed filename `s'
+       instead of f->filename.
+
+       * postscript.c: Moved initialization of x->loaded, x->prop,
+       x->fixed, x->current, also the add_encoding() calls, into
+       postopen().
+       (preclose) Destroys x->combos; sets x->loaded, x->combos to NULL;
+       sets x->last_font to NULL; sets x->next_combo to zero.
+
+       * som-high.c: (crushed_row_height) Moved definition farther up.
+       (som_submit_table) Doesn't calculate line width, font size until
+       after calling open_page(), to accomodate changes to PostScript
+       driver.
+       (vert_headers) Removed; equivalent functionality moved to
+       examine_table(), examine_crush_table().
+       (justify_pagination) Replaced with different algorithm.
+       (dump_crush_table) Bugfix that caused tables to fail to be clipped
+       at the bottom of the page.
+
+Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Added cmd_list back into cmd_table.
+
+       * freq.c, frequencies.q, repeat.c, list.q, vars-atr.c, vfm.c:
+       Comment fix: `#define DEBUGGING' --> `#define DEBUGGING 1'.
+
+       * list.q: (flush_table) Updated to new som_submission_form format.
+
+       * som-frnt.c: Comment fix.
+
+       * som-high.c: Changed `#endif' to `#undef EXTERN'.
+       (output_table) Calls som_get_table_size() directly; handles
+       crushed tables.
+       (examine_crush_table) New function; calls vert_headers().
+       (examine_table) Moved some code into new function, vert_headers().
+       (justify_pagination) New function.
+       (dump_plain_table) Removed `static' from `cy'.
+       (dump_crush_table) New function.
+
+       * som-low.c: (som_dump_crush_page) New function.
+
+       * som.h: Comment fixes.
+       (enum SOM_TOPT_CRUSH) New.
+       (SOM_SUB_PARTIAL_BEG, SOM_SUB_PARTIAL_MID, SOM_SUB_PARTIAL_END)
+       Temporarily set to zero to make do with LIST procedure.
+
+       * somP.h: Re-ordering.
+
+Wed Sep 25 19:36:11 1996  Ben Pfaff  <blp@gnu.org>
+
+       * som.c: Split into som-frnt.c, som-high.c, som-low.c.
+
+       * somP.h: New file for use by som-high.c, som-low.c.
+
+       * q2c.c: Added definition for VME.
+       (get_line) Now dumps `!' comment lines to the output file
+       verbatim.
+
+       * crosstabs.q, descript.q, file-handle.q, frequencies.q, list.q,
+       set.q: Changed format of `!' comment lines.
+
+Tue Sep 24 18:39:09 1996  Ben Pfaff  <blp@gnu.org>
+
+       * All source files: Added copyright notice.
+
+       * common.c: (xmalloc, xrealloc, xstrdup) Cast size_t's to unsigned
+       longs in msg() calls.
+
+       * con32s.c: (xmalloc, xrealloc) Updated from common.c.
+
+       * q2c.c: (xmalloc, xrealloc, xstrdup) Updated from common.c.
+
+Sat Sep 21 23:16:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * output.c: (outp_read_devices) Changed criteria for
+       distinguishing different types of lines.
+
+Fri Sep 20 22:52:28 1996  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: Changed syntax message.
+
+       * filename.c: (good_getcwd) Bug fix (?).
+       (normalize_filename) [__BORLANDC__] Uses _fullpath() library
+       function.
+       (search_path) Appends DIR_SEPARATOR to directory name only if it
+       does not already end with one.
+
+       * glob.c: Checks STAT_PAGER envvar before PAGER.
+
+       * output.c: Checks environment variables instead of just local
+       macros.
+
+Tue Sep 10 21:39:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * arena.c: (arena_destroy) Swatted a subtle bug that cropped up
+       when the pointer passed to the function was within the arena
+       itself, so that it couldn't properly be set to NULL _after the
+       arena was freed_.
+
+       * command.c: Re-enabled DISPLAY.
+
+       * display.c: Rewritten to handle tables.  Untested.
+
+       * filename.c: (search_path) Fixed memory leak.
+
+       * frequencies.q: (cmd_frequencies) Frees v_variables.
+       (postcalc) Calls cleanup_freq_tab() after displaying statistics.
+       (cleanup_freq_tab) New function to garbage collect.
+       (dump_full) Elegantized.
+
+       * main.c: New comment.
+
+       * output.h: New tag for tagged quotes: TAG_NEWLINE.
+
+       * postscript.c: Comment fix.
+       (release_fontmap, free_font_entry) New functions.
+       (ps_init_driver) Sets free_font_entry() as the freefunc for
+       hashtable `loaded'.  Calls release_fontmap() when destroying a
+       driver; also frees the output filename; also frees the
+       ps_driver_ext block.
+       (free_ps_encoding) Frees the filename as well as the encoding
+       block.
+       (output_encodings) Frees the line buffer and pops the msg-filename
+       stack.
+       (read_fontmap) Frees the fontmap filename and the line buffer.
+       (postopen, preclose) Misc. garbage collection fixes.
+       (ps_open_page) Destroys the `combos' hash table; sets `last_font'
+       to NULL; this fixes some output problems.
+       (text) Handles TAG_NEWLINE.  Untested.
+
+       * som.c: (cell_byte_size) Merged SCON_VALUE and SCON_TEXT cases.
+       (som_set_string) Removed.  All references changed to
+       `som_set_text'.
+       (som_set_text) Rewritten.  New interface.  More general.
+
+       * som.h: Minor format changes.
+       (struct som_value_cell) Removed; all references changed to
+       `som_text_cell'.
+       (enums SOT_*) Changed.
+
+Mon Sep  9 21:43:13 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: Re-enabled SPLIT FILE.
+
+       * postscript.c: Comment fix.
+
+       * som.h: Added `SOT_NONE'.
+
+       * split-file.h: (cmd_split_file) Removed superfluous parenthesis.
+
+       * vfm.c: (dump_splits) Reimplemented.
+
+Sat Sep  7 22:35:12 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Compiled the project under gcc 2.7.2, which gave some new
+       warnings.  This led to many additions of casts from unsigned to
+       int sprinkled throughout the code.
+       
+       * arena.c: Many uses of `unsigned' changed to `size_t'.
+
+       * command.c: Added END FILE, END REPEAT to command table.
+       (var cmd_end_repeat) Renamed cmd_end_repeat_p.
+       (find_command, FILE_TYPE_okay) Not commented out anymore.
+       (parse_cmd) Calls FILE_TYPE_okay again.
+       (output_line) Added calls to som_output_text() to put the line
+       in the output files.
+
+       * common.c: (macro VME) Format changes.
+       (xstrdup) Asserts that its argument is not NULL.
+       
+       * data-list.c: Implemented dump_fixed_table().
+       
+       * inpt-pgm.c: Formatting changes.  Comment changes.
+       (end_case_proc) Renamed end_case_trns_proc.
+       (cmd_end_file, end_file_trns_proc) New functions.
+
+       * misc.c: Many uses of `int' and `unsigned' changed to `size_t'.
+
+       * misc.h: (local_strdup) New macro corresponding to strdup() but
+       allocating its data through local_alloc() if possible--that is, if
+       GNU C is in use.
+
+       * postscript.c: Comment changes.
+       (quote_ps_name, quote_ps_string, output_encodings) New functions.
+       (output_line, add_string) New macros supporting
+       output_encodings().
+       (postopen) Fixed contents of ${fixed-font} and ${prop-font}
+       substitution vars.  Calls output_encodings() when a line
+       consisting of `!encodings' is encountered.
+       (preclose) Some code moved into quote_ps_string().
+       (dump_line) Changed into macro supporting dump_fancy_line().
+       (switch_font) Now outputs DSC "%%IncludeResource: font (...)"
+       command when appropriate.
+       (write_text) Fixed `literal_char' array (I think it's fixed, at
+       least.)
+       (text) Fixed bug when width was zero.  Now exits immediately on
+       zero height_left.  Now, when executing `goto restart;', checks
+       that cp<end, so that we don't read beyond end-of-string.  Also,
+       outputs the correct code to the output file by outputting the code
+       from the metric instead of the internal metric index.
+
+       * repeat.c: (cmd_end_repeat) New function.
+
+       * som.c: (var som) `headers' renamed `options' and semantics
+       changed.  All references changed.
+       (draw_title) `if(px!=-1 || px!=-1)' --> `if(px!=-1 || py!=-1)'.
+       (build_target) Only inserts spacing if SOM_TOPT_SPACING not
+       selected.
+       (som_text_table) Removed.
+       (som_output_text) New function.
+
+       * som.h: (struct som_submission_form) Removed `header', `reuse',
+       replaced with bitmapped field `options'.
+       (SOM_TOPT_*) New enum set for som_submission_form.options.
+       (SOT_*) New enum set for som_output_text().
+
+       * temporary.c: (copy_variable) When copying the var label, only
+       calls xstrdup() if it's non-NULL.
+
+       * var.h: (enum type `vartype') Removed; all references changed to
+       `int'.
+
+       * vars-atr.c: (init_variable) Changed local var `nbytes' from
+       `int' to `size_t'.
+
+Thu Sep  5 22:05:56 1996  Ben Pfaff  <blp@gnu.org>
+
+       * font.h: Comment changes.
+
+       * groff-font.c: (groff_read_font) Initializes `name' field to
+       NULL.  Handles `encoding' field.
+
+       * hash.c: (hsh_dump) [GLOBAL_DEBUGGING] Output formatting changes.
+
+       * postscript.c: (struct font_entry) Removed `position' field.
+       (struct ps_font_combo) New struct.
+       (struct ps_driver_ext) Removed field `next_position'.  New fields
+       `combos', `next_combo'.  `last_font' field changed from
+       `font_entry *' to `ps_font_combo *'.
+       (ps_init_driver) Reformatted; handles new fields.  When
+       OPO_AUTO_ENCODE is set, adds the two default fonts' encodings to
+       the encoding list.
+       (get_encoding, find_encoding_file) New functions.
+       (add_encoding) Some code moved out into find_encoding_file().
+       (postopen) Changed value for ${title}.
+       (preclose) Sets `loaded' field to NULL after destroying the hash
+       table.
+       (ps_open_page) Added comment.  Inits the `combos' and `next_combo'
+       fields.
+       (ps_text_set_font_by_position) Figures out the current family if
+       not known.
+       (compare_ps_combo, hash_ps_combo, free_ps_combo) New functions.
+       (switch_font) Implemented.
+       (write_text) Calls switch_font() more often.  Format changes.
+       #undefs its macros after they're no longer useful.
+       (text) Changed `continue' at one point to a jump to the top of the
+       loop because we don't want `separate' reset to 0 at that point.
+       (load_font) No longer sets `position' in the font_entry created.
+
+Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * font.h: (struct font_desc) New member `encoding', which is not
+       properly handled yet.
+
+       * glob.c: (init_glob) Some new i18n code, which is probably
+       screwed up.
+
+       * output.c: (outp_read_devices, outp_get_paper_size) Changed
+       `size' local from `int' to `size_t'.
+
+       * postscript.c: New driver configuration parameter `auto-encode'.
+       New enums OPO_AUTO_ENCODE, ODA_COUNT.
+       (struct font_entry) New member `position'.
+       (struct ps_driver_ext) Reordered.  New hash table member
+       `encodings'; new members `next_position', `next_encoding',
+       `last_font'.  Members `current', `prop', `fixed' changed from type
+       `font_desc *' to `font_entry *'; all references changed.
+       (struct ps_encoding) New struct.
+       (read_ps_encodings, compare_ps_encoding, hash_ps_encoding,
+       free_ps_encoding, add_encoding) New functions.
+       (ps_init_driver) Added OPO_AUTO_ENCODE to default
+       x->output_options.  Initializes new members of ps_driver_ext.
+       Changed default value for prologue_fn, encoding_fn.  Calls
+       read_ps_encodings after loading default fonts.
+       (option_tab[], ps_option) Handle new configuration parameter.
+       (switch_font) New function.
+       (struct output_char) `font' member changed from `font_desc *' to
+       `font_entry *'.  New member `separate'.
+       (read_fontmap) Changed `size' from `int' to `size_t'.
+       (output_line, put_number) New macros for write_text().
+       (write_text) Optimizes text output by consolidating multiple
+       calls to PostScript `show' operator.
+       (text) Keeps track of when text arguments can't be consolidated by
+       write_text(), and marks those spots in the output stream.
+       (load_font) Sets `position' of the allocated font_entry to -1, cuz
+       the font hasn't been switched to by switch_font(), which is where
+       the position is important--the PostScript is what cares about the
+       position.
+
+Sat Aug 31 23:52:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * hash.c: (hsh_destroy) Ignores NULL argument.  Doesn't try to
+       call a NULL free_func.
+       (hsh_rehash) Elegantized.
+       (hsh_probe) Fix bug that manifested when the table was expanded
+       and thus had to change location in memory.  Good thing
+       too--otherwise could have been much more subtle.
+       (hsh_find) [GLOBAL_DEBUGGING] Not stubbed out anymore.
+       (hsh_foreach) New function for hash table iteration.
+
+       * hash.h: (struct hsh_iterator) New.
+
+       * lexer.c: (parse_tagged_quote) Font and family name strings in
+       tags are now null-terminated.
+
+       * output.c: (outp_evaluate_dimension) Fixed over-aggressive unit
+       parsing.
+       (internal_get_paper_size, outp_get_paper_size) Fixed; now work as
+       documented.  (Never before tested?)
+
+       * output.h: Comment changes.
+
+       * postscript.c: New driver options `optimize-text-size',
+       `optimize-line-size', `max-fonts-simult'.  New enum set for
+       specing cached line types.  Comment fixes.
+       (struct line_form) New struct.
+       (struct ps_driver_struct) New members `text_opt', `line_opt',
+       `max_fonts', `lines'.
+       (ps_init_driver) Initializes new members of ps_driver_struct.
+       (user option type enum set) New member `nonneg_int_arg'.
+       (static var option_tab[]) Supports new options.
+       (ps_option) Handles new options.
+       (find_ps_file) Made static.  No longer calls hsh_dump().
+       (ps_get_var) Made static.
+       (preclose) Dumps out proper DSC trailer.
+       (ps_open_page) Elegantized.
+       (ps_close_page) Calls dump_lines() if appropriate.
+       (ps_line_horz, ps_line_vert, ps_line_intersection) Reduced to
+       wrappers around line().
+       (int_2_compare, compare_line, dump_line, dump_fancy_line,
+       dump_lines, hash_line, free_line, line) New functions for support
+       of line caching.
+       (write_text, text) Made static.
+       (text) Added to font support, not finished.
+
+Thu Aug 29 21:36:41 1996  Ben Pfaff  <blp@gnu.org>
+
+       * font.h: (struct font_desc) New members ascent, descent.
+
+       * groff-font.c: (groff_read_font) Calculates font ascent and
+       descent from the ascent and descent of the `d' and `p' characters,
+       respectively, as per a suggestion on comp.fonts.
+
+       * postscript.c: (ps_open_page, ps_close_page, ps_line_horz,
+       ps_line_vert, ps_line_intersection) Rewritten to deal with changed
+       prologue.
+       (write_text) Handles text right-justification and centering (not
+       full justification).  Still very inefficient.  (One output line
+       per character?!)
+       (struct output_char) Added fields for font and font size.
+       (text) Many bugfixes.
+
+Sat Aug 24 23:26:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * cmdline.c: (usage) Calls outp_list_classes().
+
+       * font.h: Comment fix.
+
+       * groff-font.c: New exported global var `space_index'.
+       (groff_init) New function to initialize `space_index'.
+       (hash_kern) Casts result to unsigned.
+       (font_name_to_index) Renamed font_char_name_to_index.  All
+       references changed.  Also, now returns the value of `space_index'
+       when passed an ASCII space character as an argument.  Fixed
+       handling of nulls.
+       (font_get_kern_adjust) Changed i from `int' to `unsigned'.
+       Handles passed NULL pointers properly.
+
+       * lexer.c: (parse_tagged_quote) Comment fix.  Better range
+       checking.
+
+       * output.c: (outp_list_drivers) Removed.  Removed all references.
+       
+       * output.h: Comment fixes.
+
+       * postscript.c: (ps_open_global) Calls groff_init().
+       (output_char) New structure.
+       (write_text) New function.
+       (text) No longer stubbed out!  Now the output is correct--with a
+       few exceptions, one of them being that the page has to be held
+       upside down into a mirror.
+
+Sun Aug 11 21:31:22 1996  Ben Pfaff  <blp@gnu.org>
+
+       * font.h: Comment fix.
+       
+       * font.c: (name_to_index) Renamed font_name_to_index, made extern.
+       All callers changed.
+       (number_to_index) Renamed font_number_to_index, made extern.  All
+       callers changed.
+       (font_get_kern_adjust, font_get_char_metrics) New functions.
+
+       * output.h: New constant OUTP_T_INTERNAL_DRAW.
+
+       * postscript.c: Changed default line width back to 1/2 point.
+       (ps_line_horz, ps_line_vert, ps_line_intersection) Now lines are
+       in the center of the space allotted for them, not just a fixed
+       offset from the edge of the space; this fixes some bugs.
+       (ps_line_intersection) Now supports all command line styles.
+       (ps_text_get_size) Bug fix in computation of em width.
+       (text) New function, the meat behind ps_text_metrics and
+       ps_text_draw.  Not complete.
+       (ps_text_metrics, ps_text_draw) Removed the stub taken from
+       ascii.c; call text().
+
+Sat Aug 10 23:28:17 1996  Ben Pfaff  <blp@gnu.org>
+
+       * arena.c: (arena_free) Assert that the argument is non-NULL.
+       
+       * groff-font.c: (add_kern) Calls arena_free() for old_kern if and
+       only if old_kern is non-NULL.
+
+       * postscript.c: (ps_init_driver) Changed default line width to 1
+       point.
+       (postopen) New prologue variables.
+       (ps_line_horz, ps_line_vert, ps_line_intersection) Implements some
+       more of the common line styles properly, but not all.
+       (ps_text_metrics) Fixed problem with this stubbed out version that
+       kept it from taking font sizes into account.
+
+Thu Aug  8 22:31:11 1996  Ben Pfaff  <blp@gnu.org>
+
+       * arena.c: (arena_malloc) Bug fix.
+       (arena_dump) [GLOBAL_DEBUGGING] New function.
+
+       * ascii.c: Comment fix.
+       (count_fancy_chars, delineate) Now static functions.
+       
+       * filename.c: (interp_vars) Bug fixes.
+
+       * font.h: Comment fixes.
+
+       * glob.c: (init_glob) Sets set_viewwidth, set_viewlength at
+       beginning in case we have an error message to display before
+       initializing the display.
+
+       * groff-font.c: Comment fix.  Changed rehash threshold from 2/3
+       full to 1/2 full.
+       (groff_read_font) Bug fixes.
+       (name_to_index) Increments hash.used.  Sets `name' field of hash
+       entry properly.
+       (add_kern) Sets kern_max_used after rehashing.  Other bug fixes.
+
+       * hash.c: Return type changed.
+
+       * postscript.c: Continued development.  Now marks lines on the
+       paper, but very buggy.
+
+Sat Aug  3 20:50:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Changed comments in many source files from `/* xxx /* yyy */' to
+       `/* xxx */ /* yyy */' for cleanliness.
+
+       * arena.c: (arena_sd_strdup) New function.
+       
+       * ascii.c: (struct ascii_driver_ext) New member `file'.
+       (ascii_init_driver) Fills out member `file' for initing; uses
+       close_file_ext for closing drivers.
+       (ascii_option) Changed %.*s back to %s because the a_string's are
+       always null-terminated.
+       (postopen, preclose) New functions.
+       (ascii_open_page) Uses new style of open_file_ext.
+       (ascii_option, commit_line_buf, output_lines) Use ext->file.file
+       instead of this->output.
+       (__assert_fail) Removed.
+
+       * cmdline.c: Changed syntax_message[].
+
+       * error.c: #include's <readline/history.h> only if the history
+       library is available, not if just the readline library is
+       available.
+
+       * filename.c: (expand_line) Removed alloca() support.
+       (interp_vars) No longer tilde-expands argument.  Limit on output
+       length removed.
+       (tilde_expand) Now treats argument as path rather than filename.
+       [!unix] Now is a no-op function.
+       (search_path) Better verbose message formatting.
+       (open_file, close_file) Comment fixes.
+       (close_file) [!unix] Doesn't bother with pipes.
+       (open_file_ext) Completely rewritten, interface revamped.
+       (close_file_ext) New function.
+
+       * font.h: Comment changes.
+
+       * frequencies.q: Removed AIX alloca support since it doesn't use
+       alloca.
+
+       * hash.c: Comment changes & additions.
+       (hsh_create) Initializes entire table instead of first M entries.
+       (hsh_probe) Stupid bug fixed.  Now it works.
+       (hsh_dump) [GLOBAL_DEBUGGING] New function.
+
+       * main.c: (parse) Detects EOF properly in token-eating loop.
+       Should the STOP token have its value changed to 0?
+
+       * misc.c: (blp_getdelim) [HAVE_GETDELIM] Now it's a macro.
+       (blp_getline) Now it's a macro.
+
+       * output.h: (struct outp_driver) Removed members output, filename.
+       
+       * output.c: (outp_init) [!NO_POSTSCRIPT] Installs PostScript
+       drivers in driver table.
+       (outp_read_devices) Frees buf.  Warns if there are no active
+       output drivers.
+       (outp_configure_clear) Sets outp_configure_vec to NULL after
+       deleting its elements.
+       (configure_driver, destroy_driver) Removed references to output,
+       filename members of outp_driver.
+       (outp_evaluate_dimension, internal_get_paper_size,
+       outp_get_paper_size) New functions.
+
+       * postscript.c: Continued development.  Now links but doesn't make
+       any marks on the page.  Lotsa bugs I suppose.
+
+       * str.c: (strcasecmp) [!HAVE_STRCASECMP] New function.
+
+       * str.h: Comment changes.
+
+Sat Jul 27 22:32:38 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Removed dependencies on non-nested comments in several files.
+       Also removed references to (unix || __unix__) in #if's since
+       prefh.orig makes those two equivalent.
+       
+       * ascii.c: (ascii_open_global) Creates ascii_arena.
+       (ascii_close_global) Destroys ascii_arena.
+       (ascii_init_driver) Doesn't create ascii_arena.
+       (ascii_copy_driver) Removed.
+       (ascii_option) Possible bugfix regarding %s vs. %.*s with a_string's.
+       (outp_class ascii_class) Removed ascii_copy_driver reference.
+
+       * frequencies.q: Now can display all statistics except median.
+       Still not finished.
+
+       * output.c: Handles outp_class.ref_count so output class
+       destructors are called properly.
+       (add_class) Sets ref_count to 0.
+       (configure_driver) Initializes class if ref_count++ is 0.
+       (destroy_driver) Destructs class if --ref_count is 0.  Frees the
+       class output file name.
+       
+       * output.h: (struct outp_class) Removed copy_driver, inited.
+       Added ref_count.
+
+       * postscript.c: Completely replaced but not finished.
+       
+Tue Jul 23 21:48:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * approx.h: #includes <float.h>.
+
+       * arena.h, arena.c: Many functions changed to take an arena **
+       instead of an arena *, for consistency.  All callers changed.
+       (arena_alloc) Now creates a new arena if passed *A that is NULL.
+       (arena_destroy) Sets *A to NULL.
+       
+       * ascii.c: (delineate) Implements OUTP_T_VERT correctly.  Removed
+       assertion that `width' be positive.
+
+       * command.c: Removed #if's from cmd_table.
+       (walk_cmdtable_func) [0] New function (debug code).
+       (init_cmd_parser) [0] Dumps out cmd_table (debug code).
+       (parse_cmd) Doesn't return failure for unimplemented commands.
+
+       * common.h: (SYSMIS) Changed from DBL_MAX to -DBL_MAX.
+       (SYSCODE) New constant macro.
+
+       * descript.q: Checks for positive n_variables before performing
+       analysis.
+
+       * file-handle.q: (get_handle_by_filename) Bug fix: passes &f to
+       avl_find instead of &fp as arg 2.
+
+       * frequencies.g, frequencies.q: Continued updating; now compiles &
+       works again, but not complete.
+
+       * main.c: Changes to user messages.
+
+       * misc.c: (reverse) [0] New function.
+
+       * settings.h: Comment removed.  #includes "common.h".
+
+       * som.c: (som_set_null) New function.
+       (som_set_value, som_set_string, som_set_text) More detailing
+       assertions.
+       (som_set_float) Implemented function.
+       (dump_columnated_table) Bug fix regarding page breaks.
+       (draw_cell) Bug fix regarding text that spilled out of a cell.
+       (draw_intersection, draw_horz_rule, draw_vert_rule) No longer draw
+       null lines.
+       (get_cell_size) Support SCON_EMPTY cells.
+       (get_table_size) When calculating rules' widths and heights, mask
+       out SLIN_SPACING bit.  Added SOPT_X_HLTL support.
+       
+       * som.h: (som_any_cell) New option SOPT_X_HTLT.  Removed
+       SOPT_X_SHADE.
+       (struct som_submission_form) New member `header'; all users
+       changed.
+
+       * val-labs.c: (get_label) User messages changed.
+
+       * var.h: Changed FREQUENCIES structures.
+
+       * vars-atr.c: (is_num_user_missing, is_str_user_missing) Made
+       inline.
+       
+Fri Jul 19 19:11:13 1996  Ben Pfaff  <blp@gnu.org>
+
+       * approx.h: Definition of EPSILON now depends on system's
+       DBL_EPSILON.  Removed GNU C specific code.
+       (cmpapx) Renamed approx_compare.
+
+       * frequencies.g, frequencies.q: Continued updating; still doesn't
+       compile.
+
+       * groff-font.c: (name_to_index) Fix bug that kept it from
+       compiling.
+
+       * hash.c, hash.h: Completed work.
+
+       * var.h: Changes to freq_tab, frequencies_proc.
+       
+Wed Jul 17 21:23:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       New hashing code.
+       * hash.c, hash.h: New files.  Not completed.
+       * Makefile.am: Added hash.c to source file list.
+       * font.h: (struct font_desc) New member kern_size_p.
+       * groff-font.c: Uses hash.h.
+       (hashpjw) Moved to hash.c.
+       (next_prime_power) Rewrote, renamed hsh_next_prime, moved to
+       hash.c.
+       (static var hash) New member size_p.
+       * var.h: Includes hash.h.
+       (struct freq_tab) Changed AVL_TREE to hash_tab.
+
+       * vars-prs.c: Comment, formatting fixes.
+
+       * frequencies.g, frequencies.q: Continued updating.  Not yet
+       working.
+
+       * formats.c: Bug fix.
+
+Tue Jul 16 22:10:04 1996  Ben Pfaff  <blp@gnu.org>
+
+       Increasing parallelism between DESCRIPTIVES and FREQUENCIES.
+       * descript.g: Comment fixes.
+       * descript.q: Comment fixes.  Moved some declarations into var.h.
+       Made dsc_info a static table.  Updated FIXMEs.
+       (internal_cmd_descriptives) Beautified.
+       
+       * frequencies.q: Started updating into working order.
+       * frequencies.g: New file analogous to descript.g.
+       * var.h: Comment fixes.  Added structures for FREQUENCIES.
+       
+       * som.c: Removed vestiges of crushing and partial table support.
+
+Sun Jul 14 15:45:31 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Many more changes to som.c especially, but these will not be
+       documented as I have resolved to remove them.  This patchlevel is
+       being released solely so that I can fall back to it if I decide
+       that removing the changes is not a good idea.
+
+Sat Jul 13 09:58:44 1996  Ben Pfaff  <blp@gnu.org>
+
+       * som.c: (global var som) New member `cum_y'.
+       (build_target) Properly handles titles for partial tables.
+       (dump_partial_beg, dump_partial_mid, dump_partial_end)
+       Merged into single new function dump_partial().  Fixed problem
+       with titles on partial tables.
+       (dump_table) Calls dump_partial() for all parts of partial tables.
+       (dump_page) Criteria for drawing title changed.
+       
+Fri Jul 12 22:03:36 1996  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (cmd_table) Added LIST, WEIGHT.
+
+       * command.c: (cmd_remark) No longer frees `s' since it's not
+       dynamically allocated.
+       
+       * data-out.c: (convert_f) Now correctly handles the case where
+       abs(v->f)<1 but v->f rounds to a value of 1.00 given the specified
+       number of decimals.
+       (som_destroy_all_tables) Removed argument.  All callers changed.
+       (som_vline, som_hline) Argument validity checking corrected.
+       (som_set_value) Implemented half-heartedly.
+       (replicate_table) Copies tables piece-by-piece when using Checker.
+
+       * som.h: New line style SLIN_1THIN, currently equivalent to
+       SLIN_0.  New enum set SOM_SUB_*.
+       (struct som_submission_form) Removed `seq_no'.  Added `type'.
+       
+       * list.q: Newly working file; uses partial tables.
+       
+       * som.c: (som_reduce_table) Renamed som_set_table_height().
+       (som_crush) Removed argument `group'.
+       (global var som) Removed `nt', `seq_no'.  Added `type'.
+       (som_submit_table) Arguments changed.
+       (output_table) Removed partial table code.
+       (build_target) New arg; partial table support added.  All callers
+       changed.
+       (dump_plain_table) Removed partial table code.
+       (dump_partial_beg, dump_partial_mid, dump_partial_end) New functions.
+       (dump_table) Supports partial tables.
+       (dump_page) New argument to allow not drawing top and/or bottom
+       headers.  All callers changed.  Supports partial tables.
+
+Sat Jul  6 22:22:25 1996  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c: Changed `#include <approx.h>' to `#include
+       "approx.h".
+       (convert_F) Comment fix.  Now won't print `-.000', etc.
+
+       * descript.q: Now Z-scores work, although there appears to
+       be a bug (which might actually be in data-out.c:convert_F()).
+       (descriptives_trns_proc, descriptives_trns_free) New functions.
+       (run_z_pass) Implemented.
+       
+       * var.h: Comment fixes.
+       (dsc_z_score, descriptives_trns) New structs.
+       (descriptives_trns) Added to any_trns as `dsc'.
+
+       * error.c, error.h: New error class, IS (Installation Script
+       error), used in those instances where the error is in the
+       installation, but there is a script file or installation file that
+       can be usefully referred to.
+       
+       * output.c: Change many IE classes to IS classes.
+
+       * cases.c, command.c, common.c, crosstabs.q, expr-evl.c,
+       frequencies.q, list.q, vars-prs.c, vfm.c: Removed reference to
+       HAVE_MALLOC_H because Borland C++ alloca() is broken, so why
+       include the corresponding header?
+       
+       * glob.c: (init_glob) Don't malloc term_buffer under Checker.
+       Don't bail out if termcap can't be read.
+
+       * som.c: (som_destroy_table) Removed.
+       (som_reduce_table, som_destroy_all_tables) New functions.
+       (som_crush) New function, not implemented.
+       
+       * som.h: New table option STAB_CRUSH.  Comment fix.  New struct
+       som_submission_form.  Function prototypes revised.
+
+       Outputting huge tables (1000s of rows) a few rows at a time
+       is supported, though untested.  May even break everything.
+       Actually, the code doesn't even compile right now.
+       * som.c: (struct som) New fields htv, nt, seq_no.
+       (som_submit_table) Multiple arguments changed to a single
+       pointer to struct submission_form.  Only increments subtable_num
+       if seq_no is zero.  Only destroys table if it's not going to
+       be reused.
+       (replicate_table) New function.
+       (output_table) Comment fix.
+       (examine_table) Changed inline code to code calling
+       replicate_table().  Calculates htv.  Supports partial tables.
+       (draw_title) Removed comment.
+       (build_target) Only allows for title on first part of partial
+       tables.
+       (dump_plain_table) Only resets table chunk number on first part
+       of partial tables; FIXME: doesn't work quite right.  Supports
+       partial tables.
+       (dump_page) Titles only on first part of partial tables.
+
+Fri Jul  5 20:16:19 1996  Ben Pfaff  <blp@gnu.org>
+
+       * Thanks to an unreliable IDE hard drive, I have spent the last
+       day reconstructing my Debian GNU/Linux installation and redoing
+       the previous day's changes--somehow I managed to save every file
+       except for output.c and output.h.  So the following changes could
+       really be considered independent of the output.c, output.h changes
+       from Jul 4.
+
+       * output.h, output.c: Moved the outp_configure_vec global var,
+       outp_names struct, and enum set OUTP_S_* from output.h to output.c.
+       outp_configure_vec is now static.
+       
+Thu Jul  4 20:20:24 1996  Ben Pfaff  <blp@gnu.org>
+
+       * The entire philosophy behind configuration of the output drivers
+       changed.  Now there is a termcap-type configuration where drivers
+       to be read are determined beforehand, rather than parsing the
+       entire output init file and storing it in memory & deciding what
+       to actually use later.  Faster & more memory-efficient at the same
+       time, cool.
+       
+       * output.c: Comment fix.  Removed outp_init_drivers global var.
+       Removed all references to synonyms.  New structure outp_defn.  New
+       global vars outp_macros, outp_configure_vec.
+       (search_name, delete_name, add_name, check_configure_vec,
+       expand_name, find_defn_value) New static functions.
+       (outp_configure_clear, outp_configure_add, outp_configure_macro,
+       outp_read_devices) New extern functions.
+       (outp_init) Much functionality moved into outp_read_devices.
+       (outp_read_devices) Format of output init file changed; name of
+       file is `devices' rather than `output' to avoid Makefile
+       conflicts.
+       (outp_clear) Renamed outp_done.
+       (outp_list_classes) Bug fix, cleaned up.
+       (outp_list_drivers) Not implemented anymore.
+       (outp_configure_driver) Now a static function; simplified; now
+       interpolates macros; supports new structure.
+       (outp_enable_driver, match_synonym) Removed; all references
+       removed.
+       (find_driver) First argument removed.
+       
+       * output.h: Global var outp_init_drivers removed; new structure
+       outp_names; new enum set OUTP_S_*; new global var
+       outp_configure_vec; function prototypes for output.c exports
+       updated.
+       
+       * main.c: (main) Calls outp_read_devices() after parsing the
+       command line.
+       
+       * cmdline.c: (parse_command_line) New option -v --verbose;
+       --version changed to -V.  --device option changed syntax to just
+       take a single device name.  Accepts key=value declaration of
+       output init file macros.  Syntax message updated.
+
+       * filename.c: (expand_line) New function.
+       (interp_environ_vars) Renamed interp_vars; no longer uses
+       fixed-size buffer.
+       (blp_getenv) Allows $ARCH and $VER pseudo-environment-vars to be
+       overridden by real environment vars.
+       (search_path) Uses verbose_msg() instead of #ifdef'd printf().
+       * filename.h: interp_environ_vars() renamed interp_vars().
+       
+       * error.c, error.h: Added extern variable `verbosity', message
+       class MM.
+       
+       * error.c: (vmsg) Support message class MM.
+       (verbose_msg) New function.
+
+       * descript.q: (generate_z_varname) Bug fix in generation of
+       Z-score varnames.
+       (dump_z_table) Bug fix in column headers.
+       
+       * ascii.c: (ascii_init_driver) Changed minimum number of lines per
+       page from 29 to 15.  Don't set a default for ops[OPS_INIT,
+       OPS_DONE].  Writes the uninit string when the driver is closed.
+       (ascii_open_page) Write the init string before the first page.
+       (output_shorts) Form of main loop changed from `while' to `for'.
+       Bug fix with overstrikes: the character is printed *after* the
+       backspace.  Eliminated a lot of `& 0xff' modifiers.
+       (advance_to_left_margin) New function.
+       (return_carriage, output_lines) Handle left margin.
+
+Thu Jul  4 00:35:59 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: New option `carriage-return-style'.
+
+       * ascii.c: (count_fancy_chars) New function.
+       (delineate, text_metrics) Use new function; bug fixes regarding
+       rich text strings.
+       (text_draw) Bug fix with rich text.
+       (output_string, output_shorts) Reordered.
+       (output_shorts) Now handles boxchars and some overstrike font
+       changes.
+       (output_char, return_carriage) New functions.
+       (output_lines) Now handles overstriking and font changes properly;
+       some code moved to output_shorts.
+
+Tue Jul  2 22:13:23 1996  Ben Pfaff  <blp@gnu.org>
+
+       [GLOBAL_DEBUGGING]
+       * ascii.c: New member `debug' in ascii_driver_ext.
+       (ascii_init_driver, delineate) Uses new member.
+
+       Now you can set a vertical height on writing text.
+       * ascii.c: (delineate) Keeps track of vertical position.
+       (text_draw) No longer considers fully justified text an internal
+       error.
+       
+       * output.h: New flag OUTP_T_VERT; other OUTP_T_ values changed.
+
+       Tables' titles are drawn; they can have variable height.
+       * som.c: `som' struct has new member, title_height.
+       (draw_title) New argument.  Moved within file.  All caller
+       changed.
+       (build_target) New argument, amount of space needed for first row.
+       Calculates height of title, takes that into account.  All callers
+       changed.
+       (dump_plain_table, dump_columnated_table) Took calculation of y1,
+       y2 out of loop.
+       (dump_columnated_table) [GLOBAL_DEBUGGING] Debugging code
+       improved.
+       (dump_columnated_table) Organized for readability.
+       (dump_page) Makes use of som.title_height.
+
+       * som.c: Many comment bug fixes.
+
+       * descript.q: (try_name, generate_z_name) Bug fix regarding
+       generation of Z-score variable names.
+       * var.h: Removed num from descriptives_proc; all referents removed.
+
+Mon Jul  1 22:13:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c: (ascii_line_horz, ascii_line_vert,
+       ascii_line_intersection) Added debugging code.
+
+       Added a descriptive line above each table to describe it.
+       * command.c: (parse_cmd) Calls som_new_series.
+       
+       * som.c: New static vars table_num, subtable_num.  New `som'
+       member `title'.
+       (dump_page) New arguments.
+       (som_submit_table) Handle new variables.
+       
+       * som.c, som.h: (som_submit_table) New arguments.  All callers
+       changed.
+       (som_new_series) New function.
+       (build_target) Makes room for extra line.
+       (draw_title) New function.
+       (dump_page) Calls draw_title.  Bug fix: doesn't always set
+       som.ext->cp to 0.
+       
+       Columnation of tables support.
+       * som.h: Deleted fr, lr, ri from som_table.  Reorganized.
+       
+       * som.c: Deleted references to fr, lr, ri.
+       (som_columnate) Bux fix: sets group member of table.
+       (som_add_options) Function removed.
+       (dump_table) Split into three functions; extensively reworked.
+       
+       * descript.q: (dump_z_table) Better output table formatting; added
+       title support to correspond to som.h changes.
+       (display) Title support.
+
+       * output.h: Added OUTP_T_NONE.
+       
+Mon Jul  1 13:00:00 1996  Ben Pfaff  <blp@gnu.org>
+
+       * descript.q: Improved handling of Z scores; still not perfect.
+       
+       * output.h, ascii.c: Added hook for getting em width of current
+       font.
+       
+       * som.c: Uses new em-width hook.  Added debugging code to
+       several functions.
+       (som_columnate) New argument.
+       (som_add_options) Removed.
+
+Jun 29 17:40:47 1996  Ben Pfaff  <blp@gnu.org>
+
+       * som.h, som.c, output.c, output.h, ascii.c: Updated to work with
+       rules as a property of the table instead of as a property of the
+       cells.
+       
+       * ascii.c: Added `header' to table of options.
+       
+       * descript.q: Added even shorter statistic names; modified to work
+       with new som interface.
+       
+       * misc.c (blp_getdelim): Bug fix.
+       
+       * version.c: includes 'conf.h'.
+       
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index 7c52887bf884d773171c4b5d3f9fb2e41be6bb44..56f7590410f8d042761b9cdbf64949d219c4c669 100644 (file)
@@ -2,12 +2,42 @@
 
 # PSPP
 
-include $(top_srcdir)/src/math/automake.mk
 include $(top_srcdir)/src/libpspp/automake.mk
 include $(top_srcdir)/src/data/automake.mk
+
+
+
+AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_srcdir)/lib -DPKGDATADIR=\"$(pkgdatadir)\"
+
+
+lib_LTLIBRARIES = src/libpspp-core.la src/libpspp.la
+src_libpspp_core_la_SOURCES = 
+
+
+src_libpspp_core_la_LDFLAGS = -release @VERSION@
+
+src_libpspp_core_la_LIBADD = \
+       src/data/libdata.la \
+       src/libpspp/libpspp.la \
+       $(LIBXML2_LIBS) $(PG_LIBS) \
+       gl/libgl.la
+
+src_libpspp_la_SOURCES = 
+
+src_libpspp_la_LDFLAGS = -release @VERSION@
+
+src_libpspp_la_LIBADD = \
+       src/language/liblanguage.la \
+       src/math/libpspp-math.la \
+       src/output/liboutput.la \
+       gl/libgl.la
+
+
+include $(top_srcdir)/src/math/automake.mk
 include $(top_srcdir)/src/output/automake.mk
 include $(top_srcdir)/src/language/automake.mk
-
 include $(top_srcdir)/src/ui/automake.mk
 
-AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_srcdir)/lib -DPKGDATADIR=\"$(pkgdatadir)\"
+
+
+EXTRA_DIST += src/OChangeLog
diff --git a/src/data/ChangeLog b/src/data/ChangeLog
deleted file mode 100644 (file)
index c047993..0000000
+++ /dev/null
@@ -1,2524 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-
-       * data-out.c (output_infinite): Use gsl_isnan instead of isnan,
-       and gsl_isinf instead of isinf, as a stopgap measure for
-       portability until appropriate gnulib modules are available.
-
-       * por-file-writer.c (format_trig_double): Similarly, use
-       gsl_finite instead of finite.
-
-2008-03-18  John Darrington <john@darrington.wattle.id.au>
-
-       * data-in.c: If category is custom currency, then use
-       numeric format for input.
-
-2008-03-06  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (var_name_is_insertable): New function.
-       (make_hinted_name): Don't accept variable names that match PSPP
-       keywords.  Thanks to Jason Stover for reporting the problem.
-
-2008-03-06  Ben Pfaff  <blp@gnu.org>
-
-       * format-guesser.c (syntax): Require month names to be spelled out
-       as English words, so that single characters that happen to be
-       Roman numerals don't get detected as months.  Thanks to John
-       Darrington for reporting this bug.
-
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6441.  Reviewed by John Darrington.
-
-       * format.c (fmt_fix): New function.
-       (fmt_fix_input): New function.
-       (fmt_fix_output): New function.
-
-       * format.def: Correct minimum width for DATETIME format.  It was
-       7, should have been 17.
-
-       * automake.mk: Add new files.
-
-       * format-guesser.c: New file.
-
-       * format-guesser.h: New file.
-
-2008-02-18  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6426.  Reviewed by John Darrington.
-       
-       * format.c (min_width): Renamed fmt_min_width and made public.
-       Updated all references.
-       (max_width): Renamed fmt_max_width and made public.  Updated all
-       references.
-       (max_decimals): Renamed fmt_max_decimals and made public.  Updated
-       all references.
-       (var_create): Use the new functions for default variable
-       attributes below.
-       (var_default_formats): New function.
-       (var_default_measure): New function.
-       (var_default_alignment): New function.
-
-       * format.h (macro FMT_MAX_NUMERIC_WIDTH): New macro.
-
-2008-02-09  Ben Pfaff  <blp@gnu.org>
-
-       Add a couple of extensions to GET DATA TYPE=TXT.  Patch #6412.
-       Thanks to John Darrington for review.
-
-       * data-in.c (data_in): Add new argument to designate the last
-       column of the data field being parsed, for use in error messages.
-       Update all callers.
-
-       * data-parser (struct data_parser): New member `quote_escape'.
-       (data_parser_create): Initialize quote_escape.
-       (data_parser_set_quotes): New function.
-       (cut_field): Support escaped quotes.
-       (parse_delimited_span): Ditto.
-       (parse_delimited_no_span): Ditto.
-
-       * get-data.c (parse_get_txt): Support ESCAPE extension subcommand
-       in enhanced mode.  Only support multiple quote characters in
-       enhanced mode.
-
-2008-02-06  John Darrington <john@darrington.wattle.id.au>
-
-       psql-reader.c psql-reader.h: Read more than one tuple at
-       once.  Fix bug reading a query which returns no data. Fix bug
-       when transformation followed a reader.
-       Ask the server for the number of records in the query, for the
-       benefit of the gui.
-
-2008-02-05  John Darrington <john@darrington.wattle.id.au>
-
-       psql-reader.c: So yesterday they release postgresql 8.3.0
-       which has money represented with 64 bits.  They must get
-       paid more than me.
-
-2008-02-02  John Darrington <john@darrington.wattle.id.au>
-
-       psql-reader.c psql-reader.h: New files.  Thanks to Ben Pfaff
-       for reviewing this code.
-       
-2008-02-02  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6347.
-
-       * sys-file-reader.c (read_variable_record): Allow missing values
-       to be specified on long string variables, but warn about them
-       because PSPP does not yet support them.
-       (read_extension_record): Ignore extension records 20 and 21, which
-       PSPP does not yet support.
-       (read_header): Fix error message when floating-point format cannot
-       be identified.
-
-2008-02-01  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6386.  Thanks to John Darrington for review and for the
-       updates to gnumeric-reader.c.
-
-       * dictionary.c (make_hinted_name): New function.
-       (make_numeric_name): New function.
-       (dict_make_unique_var_name): New function.
-
-       * gnumeric-reader.c (devise_name): Removed.
-       (munge_name): Removed.
-       (gnumeric_open_reader): Use new function
-       dict_make_unique_var_name.
-
-       * short-names.c (set_var_short_name_suffix): Use new function
-       str_format_26adic.
-
-2008-01-19  John Darrington <john@darrington.wattle.id.au>
-
-       * settings.c settings.h: Moved static variables into a 
-       single struct.  Renamed functions to have a settings_ prefix.
-
-2008-01-14  John Darrington <john@darrington.wattle.id.au>
-
-       * data-out.c (output_AHEX): Corrected number of bytes in
-       call to output_hex.  Closes bug #22011
-
-2008-01-02  John Darrington <john@darrington.wattle.id.au>
-
-       * variable.c variable.h: Replaced var_get_value_name with 
-       var_append_value_name which doesn't use any static data.
-        Thanks to Ben for review.
-
-2007-12-07  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6302.
-
-       * casegrouper.c (casegrouper_get_next_group): Cause a casegrouper
-       made from an empty casereader produce a casegrouper with no
-       groups, instead of one with one group that has no cases.
-
-       * casereader.c (casereader_is_empty): New function.
-
-2007-12-06  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6303.
-
-       * sys-file-reader.c (read_display_parameters): Handle variable
-       display parameters record with only 2 data items per variable.
-       Reported by Guido Gay <gay@irer.it>.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * identifier.c (lex_id_match_n): New function.
-       (lex_id_match): Reimplement in terms of lex_id_match_n.
-
-2007-11-24  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (src_data_libdata_a_SOURCES): Add val-type.h, to fix
-       make distcheck.
-
-2007-11-24  Ben Pfaff  <blp@gnu.org>
-
-       Fix warning reported when reading back system files that include
-       very long string variables.  Thanks to Guido Gay <gay@irer.it> for
-       reporting this bug.
-
-       * short-names.c (short_names_assign): Fix dumb typo, in which `i'
-       was written where `j' was meant.
-
-2007-11-18  Ben Pfaff  <blp@gnu.org>
-
-       Properly write variables that include a range of missing values to
-       system files.  Thanks to Guido Gay <gay@irer.it> for reporting
-       this bug.
-
-       * sys-file-writer.c (write_variable): Correctly calculate
-       n_missing_values field when writing variables that include a range
-       of missing values.
-
-2007-11-10  Ben Pfaff  <blp@gnu.org>
-
-       Cleanups and bug fixes devised while writing up documentation.
-       Patch #6262.
-
-       * automake.mk (src_data_libdata_a_SOURCES): Add new files.
-
-       * dict-class.c: New file.
-       (dict_class_from_id): Move here.
-       (dict_class_to_name): Move here.
-
-       * dict-class.h: New file.
-       (enum dict_class): Move here.  Change from consecutive integers to
-       consecutive bits, to make testing for any of multiple values
-       easier.  Add new DC_ALL constant.
-
-       * dictionary.c (struct dictionary): Change `case_limit' from
-       size_t to casenumber.
-       (dict_get_vars): Make final argument an enum dict_class.
-       (dict_get_vars_mutable): Ditto.
-       (dict_get_case_limit): Change return value to casenumber.
-       (dict_set_case_limit): Change final argument to a casenumber.
-       (dict_unset_split_var): Add assertion.  Rephrase slightly.
-       (dict_set_label): Use xstrndup to simplify.
-
-       * format.c (fmt_step_width): AHEX format also needs 2-byte
-       stepping.
-       (fmt_set_style): Simplify assertions.
-
-       * missing-values.c (mv_add_num_range): Rename mv_add_range.
-       Simplify implementation.
-       (mv_has_value): Simplify implementation.
-       (mv_pop_value): Remove the first value, not the last, to avoid
-       having GET followed by SAVE reverse the order of missing values.
-       (mv_peek_value): Rename mv_get_value.  Simplify assertion.
-       (mv_has_range): Simplify implementation.
-       (mv_peek_range): Rename mv_get_range.
-       (can_resize_string): Removed.
-       (mv_is_resizable): Use value_is_resizable.
-       (mv_resize): Use value_resize.
-
-       * short-names.h (SHORT_NAME_LEN): Move here.
-
-       * val-type.h: New file, for definitions related to type and width
-       of abstract values.  Before, these definitions were mixed among
-       those related to "union value" and those related to variables.
-       (macro SYSMIS): Move here.
-       (macro LOWEST): Move here.
-       (macro HIGHEST): Move here.
-       (macro MAX_STRING); Move here.
-       (enum val_type): New enum with values VAL_NUMERIC and VAL_STRING.
-       Replaces enum var_type that had values VAR_NUMERIC and VAR_STRING.
-       All references updated.
-       (val_type_is_valid): New function.  Replaces var_type_is_valid.
-       All references updated.
-       (val_type_from_width): New function.  Replaces
-       var_type_from_width.  All references updated.
-
-       * value-labels.c (val_labs_copy): Renamed val_labs_clone.  All
-       references updated.
-       (val_labs_can_set_width): Use value_is_resizable.
-       (val_labs_add): Simply return false if the value labels set is too
-       wide, instead of having undefined behavior.
-       (val_labs_replace): Ditto.
-       (val_labs_replace): Ditto.
-       (val_labs_first): Set iterator to null if iteration is complete.
-       (val_labs_first_sorted): Ditto.
-       (val_labs_done): Become a no-op if the iterator is null.
-
-       * value.c (value_is_resizable): New function.
-       (value_resize): New function.
-
-       * variable.c (var_get_dict_class): New function.
-
-       * variable.h (macro LONG_NAME_LEN): Rename VAR_NAME_LEN.  Update
-       all references.
-
-2007-11-08  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c: Make formatted data parsing locale-independent.
-       (parse_number): Use c_strtod instead of strtod, to avoid
-       locale-specific behavior.
-       (parse_Z): Ditto.
-
-2007-11-06  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6256: add support for binary, 360 file formats.  Reviewed
-       by John Darrington.
-
-       * data-in.c (struct data_in): Add `encoding' member.
-       (data_in): Add `encoding' parameter, and re-encode the data passed
-       in where appropriate.  Update all callers to pass it in.
-       (parse_A): Implement EBCDIC recoding wart described in manual.
-       (parse_AHEX): Implement EBCDIC recoding.
-
-       * data-out.c (data_out_legacy): New function.
-       (data_out): Make into a wrapper around data_out_legacy.
-
-       * file-handle-def.c (struct file_handle): New member `encoding'.
-       (fh_create_file): Set encoding.
-       (fh_default_properties): Set default encoding.
-       (fh_get_legacy_encoding): New function.
-
-       * file-handle-def.h (enum fh_mode): New modes FH_MODE_FIXED
-       (that replaces FH_MODE_BINARY), FH_MODE_VARIABLE,
-       FH_MODE_360_VARIABLE, FH_MODE_360_SPANNED.
-       (struct fh_properties): New member `encoding'.
-
-2007-11-05  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6258.  Reviewed by John Darrington.
-
-       * file-handle-def.c (fh_lock): Add comment that TYPE should be
-       marked with N_() in the caller.  Added these markings to each
-       caller too.  Should make i18n easier.
-       Suggested by Chusslove Illich <caslav.ilic@gmx.net>.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * file-handle-def.c: Separate locking of files for input and for
-       output, to allow both to take place at once.  Also, distinguish a
-       file handle from the identity of the underlying file, because the
-       identity of a file changes over time and the file handle can't
-       represent two different identities.
-       (struct file_handle): Remove `next', `open_cnt', `deleted',
-       `type', `open_mode', `aux', `identity' members.  Change `id' from
-       char array to char *.  Add `ref_cnt' member.
-       (file_handle_from_ll) New function.
-       (file_handles) Removed.
-       (named_handles) New variable.
-       (fh_init) Initialize named_handles.
-       (fh_done) Remove name from all named_handles.
-       (free_handle) Updated for modified struct file_handle.
-       (unname_handle) New function.
-       (fh_ref) New function.
-       (fh_from_file_name) Removed.
-       (fh_unref) New function.
-       (fh_unname) New function.
-       (fh_from_id) Rewritten.
-       (create_handle) Updated for modified struct file_handle.
-       (fh_inline_file) Increment the handle's ref count.
-       (fh_create_file) Updated for modified struct file_handle.
-       (fh_create_scratch) Ditto.
-       (fh_free) Removed.
-       (mode_name) Removed.
-       (fh_open) Removed.
-       (fh_close) Removed.
-       (fh_is_open) Removed.
-       (fh_get_id) Updated for modified struct file_handle.
-       (fh_get_default_handle) Increment the handle's ref count.
-       (fh_set_default_handle) Handle ref counts.
-       (struct fh_lock) New structure.
-       (locks) New static var.
-       (fh_lock) New function.
-       (fh_unlock) New function.
-       (fh_lock_get_aux) New function.
-       (fh_lock_set_aux) New function.
-       (fh_is_locked) New function.
-       (make_key) New function.
-       (free_key) New function.
-       (compare_fh_locks) New function.
-       (hash_fh_lock) New function.
-
-       * file-handle-def.h (enum fh_access) New enum.
-
-       * file-name.c: Made file_identity the same in all supported
-       environments.
-       (struct file_identity): New `name' member.
-       (fn_get_identity): For a file that doesn't exist, get the
-       dev/inode of its directory plus its name.  If even the directory
-       doesn't exist, just use its name.  Merge the Windows
-       implementation into the Unix one.
-       (fn_compare_file_identities): Rewritten.  Merge the Windows
-       implementation into the Unix one.
-       (fn_hash_identity): New function.
-
-       * make-file.c (struct replace_file): New structure.
-       (all_files): New static var.
-       (replace_file_start): New function.
-       (replace_file_commit): New function.
-       (replace_file_abort): New function.
-       (free_replace_file): New function.
-       (unlink_replace_files): New function.
-
-       * por-file-reader.c (struct pfm_reader): Add `lock' member.
-       (close_reader): Unlock file.
-       (pfm_open_reader): Lock file.
-
-       * por-file-writer.c (struct pfm_writer): Add fh_lock, replace_file
-       members.
-       (pfm_open_writer): Lock file and prepare for its replacement.
-       (close_writer): Unlock file.
-
-       * scratch-handle.h (struct scratch_handle): Add unique_id so that
-       different generations of a scratch file can be distinguished.
-
-       * scratch-reader.c (scratch_reader_open): Verify that the file is
-       a scratch file.
-
-       * scratch-writer.c (struct scratch_writer): Add `lock' and `dict',
-       remove scratch_handle member.
-       (scratch_writer_open): Lock handle.  Prepare to replace handle
-       data, instead of doing it immediately.
-       (scratch_writer_casewriter_destroy): Replace handle data and
-       unlock handle.
-
-       * sys-file-reader.c (struct sfm_reader): Add `lock' member.
-       (sfm_open_reader): Lock file.
-       (close_reader): Unlock file.
-
-       * sys-file-writer.c (struct sfm_writer): Add fh_lock, replace_file
-       members.
-       (sfm_open_writer): Lock file and prepare for its replacement.
-       (close_writer): Unlock file.
-
-2007-11-02  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c (output_number): Use isfinite (from C99) instead of
-       gsl_isfinite, since we now have universal support for it in
-       gnulib.
-       (output_infinite): Ditto.
-       [!HAVE_ROUND] (round): Remove definition, since we now have a
-       replacement in gnulib.
-
-2007-10-27  John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c: Fixed bug in dict_clone, where the vardict.dict member
-       wasn't initialised correctly. Closes bugs #21330 and 21397
-
-
-2007-10-08  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #21280.  Thanks to John Darrington for review.
-
-       * file-name.c (create_stream): New function.
-
-       * por-file-writer.c (pfm_open_writer): Use fh_open to open the
-       file handle before creating the file, to ensure that we don't
-       truncate a file that we're reading.  Make code easier to read by
-       using create_stream.
-
-       * sys-file-write.c (sfm_open_writer): Ditto.
-
-2007-10-01  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #21192.  Thanks to John Darrington for review.
-
-       * casereader.c (casereader_read): Decrement case_cnt before
-       calling the casereader's "read" member function, so that we
-       interact properly with lazy_casereader.
-
-       * datasheet.c: Add regression test for above bug fix.
-       (clone_datasheet): New function.
-       (lazy_callback): New function.
-       (check_datasheet_casereader): New function.
-       (check_datasheet): Check datasheet contents are reported correctly
-       through an ordinary casereader and a lazy casereader.
-       (clone_model): Use clone_datasheet.
-
-2007-09-24  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6210.  Reviewed by John Darrington.
-       * settings.c: Drop "long view", which is not needed any longer.
-       (static var long_view): Removed.
-       (force_long_view): Removed.
-       (get_viewwidth): Removed.
-       (init_viewport): Removed long_view reference.
-
-2007-09-19  John Darrington <john@darrington.wattle.id.au>
-       
-       * settings.c settings.h: Changed viewport's length and width to be 
-       owned by the user interface which uses the data library.  This allows
-       better abstraction, and makes dynamically adjustable dimensions easier.
-       
-2007-09-18  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c (proc_extract_active_file_data): New function.
-
-       * lazy-casereader.h: New file.
-
-       * lazy-casereader.c: New file.
-
-       * casereader.c (casereader_dynamic_cast): New function.
-
-2007-09-14  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_clone): Copy case indexes from cloned
-       dictionary.  Fixes bug #21061.  Reviewed by John Darrington.
-
-2007-09-13  John Darrington <john@darrington.wattle.id.au>
-
-       * value.c value.h (create_value): New function.
-
-2007-09-12  Ben Pfaff  <blp@gnu.org>
-
-       Make it clear that translator casereader and casewriter translate
-       functions are supposed to destroy their input case.
-       
-       * casereader-translator.c (struct casereader_translator): Change
-       input case parameter of translate member function from const
-       struct ccase * to struct ccase *.
-       (casereader_create_translator): Ditto, for translate parameter.
-
-       * casewriter-translator.c (struct casewriter_translator): Ditto.
-       (casewriter_create_translator): Ditto.
-
-2007-08-27  John Darrington <john@darrington.wattle.id.au>
-       
-       * sys-file-reader.c (read_display_parameters): Force display width 
-       to 8, if the sys file says 0 (like SPSS does).
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_dump): New function.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       Drop dict_compactor in favor of using the new struct case_map.
-
-       * dictionary.c (struct copy_map): Removed.
-       (struct dict_compactor): Removed.
-       (dict_make_compactor): Removed.
-       (dict_compactor_compact): Removed.
-       (dict_compactor_destroy): Removed.
-
-       * procedure.c (struct data_set): Change `compactor' member to be a
-       struct case_map *.
-       (proc_open): Use case_map_to_compact_dict instead of
-       dict_make_compactor.
-       (proc_casereader_read): Use case_map_execute instead of
-       dict_compactor_compact.
-       (proc_commit): Use case_map_destroy instead of
-       dict_compactor_destroy.
-
-       * scratch-writer.c (struct scratch_writer): Change `compactor'
-       member to be a struct case_map *.
-       (scratch_writer_open): Use case_map_to_compact_dict instead of
-       dict_make_compactor.
-       (scratch_writer_casewriter_write): Use case_map_execute instead of
-       dict_compactor_compact.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add case-map.c, case-map.h.
-
-       * case-map.c: New file.
-
-       * case-map.h: New file.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_compact_values): Don't delete scratch
-       variables as well as compacting case indexes.  Update all callers.
-       (dict_get_compacted_value_cnt): Rename dict_count_values and
-       change interface.  Update all callers.
-       (dict_get_compacted_value_cnt): Remove.
-       (dict_compacting_would_shrink): Remove.
-       (dict_compacting_would_change): Remove.
-       (dict_make_compactor): Add new parameter.  Update all callers.
-       
-       * procedure.c (proc_casereader_read): Use casewriter_get_value_cnt
-       instead of dict_count_values, changing an O(N) operation into
-       O(1).
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * casereader.c (casereader_read): Don't require cases read by a
-       casereader to be exactly the expected size: as long as they're big
-       enough, it's OK.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       Make casewriters keep track of the number of `union value's in
-       each case.  This is useful for two reasons: casewriter_write can
-       then check that the case being written is large enough, and later
-       recipients of the casewriter can determine the size of the case.
-       
-       * casewriter-translator.c (casewriter_create_translator): Add
-       value_cnt parameter.
-       
-       * casewriter.c (struct casewriter): Add value_cnt member.
-       (casewriter_write): Check that the case passed in is big enough.
-       (casewriter_get_value_cnt): New function.
-       (casewriter_create): Add value_cnt parameter.
-
-2007-08-09  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug reported by Jason Stover.
-       * settings.c: Move get_termcap_viewport and in particular the
-       #include for <curses.h> to the end of the file.  curses.h
-       redefines bool on some systems (e.g. OpenBSD), which causes
-       disagreement between uses of bool before its inclusion and
-       afterward.
-       Tested by Jason Stover.
-
-2007-07-29  Ben Pfaff  <blp@gnu.org>
-
-       Provisional fix for bug #18692 and bug #20161.  Reviewed by John
-       Darrington.
-
-       * file-name.c (fn_open): Only pass "r" or "w" to popen as mode
-       argument (never "rb" or "wb") because SUSv3 says that only those
-       modes are defined, and glibc in fact rejects other modes.
-
-       Open portable files with fn_open so that they can be read from
-       pipes.  Fix missing fh_close call to go along with fh_open.
-       Report an error if the file close reports an error.
-       * por-file-reader.c (close_reader): New function.
-       (por_file_casereader_destroy): Use close_reader.
-       (pfm_open_reader): Open file with fn_open.
-
-2007-07-28  Ben Pfaff  <blp@gnu.org>
-
-       Make PSPP able to read all the portable files I could find on the
-       web.  Thanks to John Darrington for review.  Bug #17620.
-       * por-file-reader.c (struct pfm_reader): New member `line_length'.
-       (error): Print file offset in hexadecimal.
-       (warning): New function.
-       (advance): Treat lines less than 80 bytes long as padded to 80
-       bytes with spaces.
-       (pfm_open_reader): Call read_documents if we find an "E" record.
-       (convert_format): Convert invalid formats to the default format
-       instead of aborting reading the file.
-       (read_variables): Rename duplicate variable names instead of
-       aborting reading the file.
-       (read_value_label): Allow string variables of different widths to
-       be assigned value labels in the same record.  Replace duplicate
-       value labels instead of aborting.
-       (read_documents): New function.
-
-       * por-file-writer.c (pfm_open_writer): Call write_documents if the
-       dictionary has documents.
-       (write_documents): New function.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Fix bugs related to bug #17213.
-
-       * settings.c: Use HAVE_LIBNCURSES instead of HAVE_LIBTERMCAP,
-       since the former is what config.h has.  Include the needed ncurses
-       headers.
-       (static var echo) Rename to `do_echo' because the original name is
-       the same as an ncurses identifier.
-       (get_termcap_viewport) Use error instead of msg.
-
-       * file-name.c (fn_interp_vars): Fix interpolation of $VARS.
-       (fn_close): Don't close stdin, stdout, stderr.
-
-2007-07-26 John Darrington <john@darrington.wattle.id.au>
-
-       * procedure.c procedure.h: Added callbacks which get invoked whenever 
-       a dataset's transformation chain changes.
-
-2007-07-24  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #6113.
-       * sys-file-writer.c (write_variable_display_parameters): Use new
-       var_default_display_width function to choose display width of
-       segments after the first one in a given variable.
-       * variable.c (var_create): Use var_default_display_width to pick
-       new variable's display width.
-       (var_default_display_width): New function.
-       Reviewed by John Darrington.
-
-2007-07-24  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #20427.
-       * por-file-writer.c (write_variables): Write weight variable.
-       Reviewed by John Darrington.
-
-2007-07-23  Ben Pfaff  <blp@gnu.org>
-
-       Improvements to system file reader and writer.
-       
-        First, move all detailed knowledge of very long strings into
-       sys-file-private.[ch], so that this nasty stuff can be isolated.
-
-       * sys-file-private.c (REAL_VLS_CHUNK): New macro.
-       (EFFECTIVE_VLS_CHUNK): New macro.
-       (min_int): New function.
-       (max_int): New function.
-       (sfm_width_to_bytes): Rewrite.
-       (sfm_width_to_octs): New function.
-       (sfm_segment_alloc_width): New function.
-       (sfm_segment_alloc_bytes): New function.
-       (sfm_segment_used_bytes): New function.
-       (sfm_segment_offset): New function.
-       (sfm_segment_effective_offset): New function.
-       (sfm_dictionary_to_sfm_vars): New function.
-
-       * sys-file-private.h (MIN_VERY_LONG_STRING): Removed.
-       (EFFECTIVE_LONG_STRING_LENGTH): Removed.
-       (struct sfm_var): New structure.
-
-        Next, improvements to the system file reader.
-
-       * sys-file-reader.h (struct sfm_read_info): Changed `case_cnt' to
-       type casenumber.  Added `version_major', `version_minor',
-       `version_revision'.
-
-       * sys-file-reader.c (struct sfm_reader): Replaced `flt64_cnt' by
-       `oct_cnt'.  Rename `vars', `var_cnt' to `sfm_vars', `sfm_var_cnt'.
-       Change `case_cnt' to type casenumber.  Removed `has_vls'.
-       (struct sfm_var): Removed.
-       (sfm_open_reader): Don't warn on wrong case size if the file was
-       written by SPSS 13, which tends to get it wrong.  Use
-       sfm_dictionary_to_sfm_vars.
-       (read_header): Always output system file info.
-       (read_variable_record): Simplify code for reading missing values.
-       (read_machine_int32_info): Save version numbers from system file
-       into info struct passed as new argument.
-       (read_long_string_map): Restructured to use new sys-file-private
-       functions.
-       (read_value_labels): Use size_overflow_p.
-       (sys_file_casereader_read): Get rid of distinction between fast
-       and slow paths.  Use information provided by sys-file-primate's
-       struct sfm_var to simplify code.
-       (skip_whole_strings): New function.
-       (read_int32): Renamed read_int.  Changed return value to int.
-       Updated all callers.
-       (read_flt64): Renamed read_float.  Changed return value to
-       double.  Updated all callers.
-       (int32_to_native): Removed.  Changed callers to use
-       integer_convert.
-       (flt64_to_double): Removed.  Changed callers to use float_convert.
-       
-        Finally, get rid of int32, flt64 terminology and types in system
-       file writer.  The former wasn't very useful since a POSIX "int"
-       can hold the whole range of int32 and we generally didn't have a
-       need for it to be exactly-32-bits, just at-least-32-bits.  The
-       latter was inconvenient because we had to assume that it could be
-       different from double and thereby convert special values SYSMIS,
-       HIGHEST, LOWEST to and from it in multiple places.  Instead, now
-       we just use "int" and "double" in most places, and do conversions,
-       if necessary, very close to where we do I/O.  This change meant
-       that the writer code couldn't represent records in the file as C
-       structs any longer, but that's no great loss.  The code actually
-       seems to be more readable without them.
-
-       Simplify the compression buffering code: only buffer as much as
-       necessary, which is no more than eight 8-byte units at any given
-       time.
-
-       * sys-file-writer.c (typedef flt64): Removed.
-       (macro second_lowest_flt64): Removed.
-       (struct sysfile_header): Removed.
-       (struct sysfile_variable): Removed.
-       (struct sfm_writer): Removed `needs_translation', `has_vls',
-       `flt64_cnt'.  Changed `compress' to type bool and `case_cnt' to
-       type casenumber.  Renamed `vars' to `sfm_vars', `var_cnt' to
-       `sfm_var_cnt'.  Replaced `buf', `end', `ptr', `x', `y' for
-       compression buffering by `opcodes', `opcode_cnt', `data',
-       `data_cnt'.  Renamed `var_cnt_vls' as `segment_cnt'.
-       (sfm_open_writer): Use sfm_dictionary_to_sfm_vars.  Use simple
-       data writer functions instead of structures.
-       (calc_oct_idx): New function.
-       (write_header): Use simple data writer functions instead of
-       structures.
-       (write_format_spec): Renamed write_format.  New argument.
-       (write_variable_continuation_records): New function.
-       (write_variable): Use simple data writer functions instead of
-       structures.  Use write_variable_continuation_records.  Write
-       entire very long string instead of requiring caller to understand
-       them.
-       (write_value_labels): Use simple data writer functions instead of
-       structures.
-       (write_documents): Ditto.
-       (write_variable_display_parameters): Use sys-file-private
-       functions to simplify.  Use simple data writer functions instead
-       of structures.
-       (write_vls_length_table): Use simple data writer functions instead
-       of structures.
-       (write_longvar_table): Ditto.
-       (write_rec_7_34): Break into new functions
-       write_integer_info_record, write_float_info_record.  Use simple
-       data writer functions instead of structures.
-       (buf_write): Removed.
-       (append_string_max): Removed.
-       (ensure_buf_space): Removed.
-       (sys_file_casewriter_write): Get rid of the distinction between
-       fast and slow paths, which didn't seem to be too useful.  Use new
-       functions write_case_uncompressed, write_case_compressed.
-       (put_instruction): Removed.
-       (put_element): Removed.
-       (write_compressed_data): Removed.
-       (close_writer): Use flush_compressed.  Only write case count to
-       system file if it will fit in the field.
-       (write_case_compressed): New function.
-       (write_case_uncompressed): New function.
-       (flush_compressed): New function.
-       (put_cmp_opcode): New function.
-       (put_cmp_number): New function.
-       (write_int): New function.
-       (convert_double_to_output_format): New function.
-       (write_float): New function.
-       (write_value): New function.
-       (write_string): New function.
-       (write_bytes): New function.
-       (write_zeros): New function.
-       (write_spaces): New function.
-
-       Reviewed by John Darrington.
-
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       Don't try to write very long strings to portable files.  The
-       format does not support it.
-
-       * por-file-writer.c (MAX_POR_WIDTH): New macro.
-       (pfm_open_writer): Limit output width to MAX_POR_WIDTH.
-       (write_format): Add arg to take width to resize format to.
-       (write_value): Limit width of value written to MAX_POR_WIDTH.
-       (write_variables): Limit width of variable and its output formats
-       to MAX_POR_WIDTH.
-       Reviewed by John Darrington.
-
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-reader.c (read_variable_to_value_map): Use max_warnings
-       local variable instead of literal 5.
-       Reviewed by John Darrington.
-       
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       Fix problems with uniqueness of short names in system files with
-       very long string variables.  Now a variable may have multiple
-       short names.
-       
-       * automake.mk (src_data_libdata_a_SOURCES): Add new files
-       short-names.c, short-names.h.
-
-       * dictionary.c (dict_clone): Clone all the short names.
-       (compare_strings): Move into short-names.c.
-       (hash_strings): Ditto.
-       (set_var_short_name_suffix): Ditto.
-       (dict_assign_short_names): Ditto, rename short_names_assign,
-       change to assign all short names.
-       
-       * por-file-writer.c (write_variables): Use short_names_assign
-       instead of dict_assign_short_names.
-
-       * short-names.c: New file.
-
-       * short-names.h: New file.
-
-       * sys-file-private.c (sfm_width_to_segments): New function.
-
-       * sys-file-reader.c (read_long_var_name_map): Save and restore all
-       the short names, not just the first one.
-       
-       * sys-file-writer.c (cont_var_name): Removed.
-       (sfm_open_writer): Use short_names_assign instead of
-       dict_assign_short_names.  Use unique short names assigned by
-       short_names_assign instead of those generated by cont_var_name.
-
-       * variable.c (struct variable): Remove `short_name' member,
-       replace by `short_names' and `short_name_cnt'.
-       (var_create) Initialize new members.
-       (var_get_short_name_cnt): New function.
-       (var_get_short_name): Now takes an index argument.  Changed most
-       callers to pass 0.
-       (var_set_short_name): Ditto.
-       (var_clear_short_name): Renamed var_clear_short_names, changed to
-       clear all short names.
-       
-       Reviewed by John Darrington.
-
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       * variable.c (var_set_width): Use new var_set_width function.
-
-       * missing-values.c (mv_n_values): Drop assertion, which was not
-       needed.
-
-       * format.c (fmt_default_for_width): New function.
-       (fmt_resize): New function.
-
-       Reviewed by John Darrington.
-
-2007-07-18 John Darrington <john@darrington.wattle.id.au>
-
-       * datasheet.c (datasheet_delete_columns): Added assertion to check
-       we're not deleting outside the range of the sheet.  
-
-       
-       * dictionary.c dictionary.h variable.c: Added the ability for string
-       variables to be resized.
-       
-       * vardict.h: Added some prototypes (moved from dictionary.h) as
-       these should only be called by variable.c
-
-
-2007-07-14 John Darrington <john@darrington.wattle.id.au>
-
-       * sfm-reader.c: Respect case_cnt field in file header.
-
-2007-07-01 John Darrington <john@darrington.wattle.id.au>
-
-       * transformation.c transformation.h (trns_chain_execute): Changed the 
-       signature (Patch #6057)
-
-2007-06-10  Ben Pfaff  <blp@gnu.org>
-
-       * casereader-filter.c (casereader_filter_destroy): Make sure to
-       write all the remaining excluded cases to the casewriter, if any.
-
-       * caseinit.c (init_list_destroy): Rewrite.
-       (init_list_clear): Ditto.
-
-       * casegrouper.c (casegrouper_get_next_group): Always set *reader
-       to null when returning false.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Actually implement the new procedure code and adapt all of its
-       clients to match.  Also adapt all of the other case sources and
-       sinks in the tree and their clients to use the
-       casereader/casewriter infrastructure.
-
-       * automake.mk: Add and remove files.
-
-       * any-reader.c: Change into a casereader.
-       * por-file-reader.c: Ditto.
-       * scratch-reader.c: Ditto.
-       * sys-file-reader.c: Ditto.
-
-       * any-writer.c: Change into a casewriter.
-       * por-file-writer.c: Ditto.
-       * scratch-writer.c: Ditto.
-       * sys-file-writer.c: Ditto.
-
-       * procedure.c: Change to use casereader, casewriter, caseinit, and
-       other new infrastructure.
-
-       * scratch-handle.c: Adapt to new infrastructure.
-
-       * case-sink.c: Removed, now dead code.
-       * case-sink.h: Ditto.
-       * case-source.c: Ditto.
-       * case-source.h: Ditto.
-       * casefile-factory.c: Ditto.
-       * casefile-private.h: Ditto.
-       * casefile.c: Ditto.
-       * casefile.h: Ditto.
-       * casefilter.c: Ditto.
-       * casefilter.h: Ditto.
-       * fastfile.c: Ditto.
-       * fastfile.h: Ditto.
-       * fastfile-factory.c: Ditto.
-       * fastfile-factory.h: Ditto.
-       * storage-stream.c: Ditto.
-       * storage-stream.h: Ditto.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Add datasheet code.
-
-       * automake.mk: Add new files.
-
-       * datasheet.c: New file.
-
-       * datasheet.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Until now, the procedure code has provided a case to the
-       case_source, which has filled in the data values that come from
-       the active file.  "Left" data values that don't come from the
-       active file naturally stay the same from case to case, because the
-       procedure code keeps using that same case.
-
-       One of the compromises that comes with the new procedure code is
-       that the active file allocates and provides its own case, which
-       the procedure code then has to resize to provide room for any
-       other variables that should go in the case and then fill in the
-       values of "left" variables.  Then, when we're done with that case,
-       we have to save the values of "left" variables to copy into the
-       next case read from the active file.
-
-       The caseinit code helps with this.
-
-       * automake.mk: Add new files.
-
-       * caseinit.c: New file. 
-
-       * caseinit.h: New file. 
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * value.h (value_cnt_from_width): New function.
-
-       * variable.c (var_get_value_cnt): Use new function.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Add casegrouper, to allow cases read from a given casereader to be
-       broken into groups, each of which has its own casereader.
-       Generally cases are grouped based on having equal values for some
-       set of variables.
-
-       * automake.mk: Add new files.
-
-       * casegrouper.c: New file.
-
-       * casegrouper.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Add interface to lexicographical ordering of cases.
-
-       * automake.mk: Add new files.
-
-       * case-ordering.c: New file.
-
-       * case-ordering.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Add casereaders and casewriters, the basis of the new data processing
-       implementation.  A casereader is a uniform interface to reading cases
-       from a data source; a casewriter is a uniform interface to writing
-       cases to a data sink.
-
-       * automake.mk: Add new files.
-       
-       * casereader-filter.c: New file.
-       
-       * casereader-provider.h: New file.
-
-       * casereader-translator.c: New file.
-       
-       * casereader.c: New file.
-       
-       * casereader.h: New file.
-       
-       * casewriter-provider.h: New file.
-       
-       * casewriter-translator.c: New file.
-       
-       * casewriter.c: New file.
-       
-       * casewriter.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       "casewindow" data structure that extends the deque (from libpspp)
-       of cases with the ability to dump cases to disk if we get too many
-       of them in memory.
-
-       * automake.mk: Add new files.
-
-       * casewindow.c: New file.
-
-       * casewindow.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       sparse_cases data structure that augments a sparse_array of cases
-       with the ability to dump cases to disk if we get too many cases in
-       memory.
-
-       * automake.mk: Add new files.
-
-       * sparse-cases.c: New file.
-
-       * sparse-cases.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adds a low-level on-disk case array data structure.
-       
-       * automake.mk: Add new files.
-
-       * case-tmpfile.c: New file.
-
-       * case-tmpfile.h: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       In a couple of places we calculate the maximum number of cases to
-       keep in memory based on the user-defined workspace.  Enable
-       centralizing the calculation through a new function.
-       
-       * settings.c (get_workspace_cases): New function.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       The casenumber type is defined in transformations.h, but case.h is
-       a more sensible place.  Move it.
-
-       * case.h (CASENUMBER_MAX): New macro.
-       (typedef casenumber): Move here, from transformations.h.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       Slightly generalize case_to_values and case_from_values functions.
-
-       * case.c (case_to_values): Rename case_copy_out, change interface.
-       (case_from_values): Rename case_copy_in, change interface.
-
-       * fastfile.c (fastfilereader_get_next_case): Update caller.
-       (write_case_to_disk): Ditto.
-
-2007-06-02  Ben Pfaff  <blp@gnu.org>
-
-       Clean up after a forgotten part of patch #5829.
-       
-       * casedeque.h: Remove unused file.
-
-       * automake.mk: Remove casedeque.h from sources.
-
-2007-05-10  Jason Stover  <jhs@math.gcsu.edu>
-
-       * category.c: Removed redundant #include
-
-2007-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Abstract the documents within a dictionary a little better.
-       Thanks to John Darrington for suggestion, initial version, and
-       review.  Patch #5917.
-
-       * dictionary.c (struct dictionary): Change `documents' member from
-       char * to struct string.
-       (dict_clear): Destroy struct string.
-       (dict_get_documents): Convert struct string to char *.
-       (dict_set_documents): Set struct string.  Pad to 80-character
-       multiple.
-       (dict_clear_documents): New function.
-       (dict_add_document_line): New function.
-       (dict_get_document_line_cnt): New function.
-       (dict_get_document_line): New function.
-
-       * dictionary.h (macro DOC_LINE_LENGTH): New macro.
-
-       * sys-file-reader.c (read_documents): Use new document functions.
-
-2007-04-19 John Darrington <john@darrington.wattle.id.au>
-
-       * sys-file-reader.c: When reading a system file which has no 
-       long name table, automatically create one where the long names 
-       are the lower case versions of the short names.
-       
-2007-04-22  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_set_split_vars): dict_destroy expects that
-       dict_clear will free most data related to the dictionary.
-       dict_clear does a decent job, except that dict_set_split_vars on
-       some systems won't actually free the dict's "split" member.
-       Instead, it'll allocate a 1-byte region.  Fix this.
-
-       * value.c (value_copy): New function.
-       (value_set_missing): Ditto.
-
-2007-04-22 John Darrington <john@darrington.wattle.id.au>
-
-       * Deleted existing category.h and moved cat-routines.h into 
-       category.h  Encapsulated struct cat_vals better.
-
-2007-04-19 John Darrington <john@darrington.wattle.id.au>
-
-       * sys-file-reader.c: When reading a system file which has no 
-       long name table, automatically create one where the long names 
-       are the lower case versions of the short names.
-       
-2007-04-16 John Darrington <john@darrington.wattle.id.au>
-
-       * sys-file-reader.c: Some versions of Other Software seem to 
-        produce system files with string  variables' measure set to 
-       zero.  We'll assume these are supposed to be nominal variables.
-
-2007-03-30  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c: Adapt to new deque data structure.
-
-Mon Feb 19 10:53:21 2007  John McCabe-Dansted <gmatht@gmail.com>
-                         Ben Pfaff <blp@gnu.org>
-
-       * file-name.c: Mingw compatibility fixes.
-       (fn_search_path): Use ISSLASH instead of comparing against '/'
-       directly.
-       (fn_dir_name): Use dir_name from gnulib.
-       (fn_is_absolute): Use IS_ABSOLUTE_FILE_NAME from gnulib.
-       (fn_get_identity): Use GetFullPathName instead of canonicalize
-       from gnulib, because the latter does not fully support
-       Windows-style path names.  Use this implementation based on the
-       detected presence of Windows instead of the absence of Unix, since
-       the new implementation is Windows-specific.
-       (fn_compare_file_identities): In Windows implementation, compare
-       names case-insensitively.
-
-Sun Feb 18 13:28:02 2007  Ben Pfaff  <blp@gnu.org>
-
-       * make-file.c: Don't include mkstemp.h, because gnulib now causes
-       <stdlib.h> to have the same effect.
-
-Sun Feb 18 11:20:24 2007  Ben Pfaff  <blp@gnu.org>
-
-       * por-file-reader.c: Add missing _() around messages.
-
-Sun Feb 11 20:44:13 2007  Ben Pfaff  <blp@gnu.org>
-
-       * make-file.c: Include "mkstemp.h", without which linking on
-       mingw32 fails.
-
-Thu Feb  8 14:59:05 2007  Ben Pfaff  <blp@gnu.org>
-       Reduce platform dependence.
-       * file-name.c (fn_tilde_expand): Removed, and removed calls to it.
-       Everywhere we using this, we really should have just depended on
-       the shell to expand tildes.
-       (fn_search_path): Simplify, given that we don't do tilde expansion
-       any longer.
-       (fn_normalize): Removed.  Caller changed to use the canonicalize
-       module from gnulib.
-       (fn_get_cwd): Removed.  Only user was fn_normalize.
-       (fn_is_absolute): Really only test for absolute names.
-       (fn_is_special): Use pipe files if HAVE_POPEN, not if we're in
-       unix.
-       (fn_readlink): Removed, as it was only used fn_normalize.
-       (fn_exists): Assume the stat function is available; gnulib does.
-       (fn_open): Use pipe files if HAVE_POPEN, not if we're in unix.
-Sat Feb  3 21:52:17 2007  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_create_vector_assert): New function.
-
-Wed Feb  7 21:25:15 2007  Ben Pfaff  <blp@gnu.org>
-
-       * file-name.c (fn_normalize): Correct name of function
-       fn_is_special.  Thanks to John McCabe-Dansted <gmatht@gmail.com>
-       for pointing this out.
-
-Thu Feb  1 16:53:37 2007  Ben Pfaff  <blp@gnu.org>
-
-       We are using a single member in struct file_handle, the "name"
-       field, for more than one purpose.  When it begins with '"', it's a
-       file name; otherwise, it's a token that can be used to identify
-       it.  When that assertion fires, it's because we searched for the
-       name case-sensitively as a file name (so that there was no match),
-       and then we try to insert it case-insensitively as a token, which
-       fails because duplicates aren't allowed.
-
-       Solution: break the two purposes into two separate fields.  This
-       fixes the problem and likely makes the code easier to read too.
-
-       Fixes bug #18922.  Thanks to John Darrington for bug report and
-       review.
-
-       * file-handle-def.c (struct file_handle): New `id' member.
-       (fh_from_name): Rename fh_from_id.  Update all callers.
-       (create_handle): New `id' parameter.  Update all callers.
-       (fh_create_file): Ditto.
-       (fh_get_id): New function.
-
-Mon Jan 15 16:18:10 2007  Ben Pfaff  <blp@gnu.org>
-
-       * case.c (case_is_null): Change return type to bool.
-
-Mon Jan 15 10:57:28 2007  Ben Pfaff  <blp@gnu.org>
-
-       Add debugging code.
-       
-       * case.c (case_clone) [DEBUGGING]: When debugging, don't use
-       reference counting to share data.  This makes it easy for
-       valgrind, etc. to find accesses to cases that have been destroyed
-       but have been kept around by another user's ref-count.  This often
-       happens when the data set is small enough to find in memory; if a
-       bigger data set that would overflow to disk were used, then data
-       corruption would occur.
-
-Mon Jan 15 10:55:18 2007  Ben Pfaff  <blp@gnu.org>
-
-       Simplify code.
-
-       * case.c (case_unshare): Make it check internally whether the
-       ref_cnt is greater than 1, so that the callers don't have to.
-       Update callers not to check.
-
-Mon Jan 15 10:53:01 2007  Ben Pfaff  <blp@gnu.org>
-
-       Before, I was thinking that I might want to get rid of reference
-       counting at some point.  Now, I'm pretty sure that it's here to
-       stay.  Thus, because we have to store the value_cnt anyway for
-       reference-counted cases, we might as well expose it to users.
-
-       * case.c (case_get_value_cnt): New function.
-       (case_resize): Drop OLD_CNT argument.  Update all callers.  Only
-       resize case if its size actually changed.
-
-       * casefile.c (casefile_append_xfer): Use case_get_value_cnt
-       instead of peeking inside struct case directly.
-       (casefile_append): Ditto.
-
-Mon Jan 15 10:50:22 2007  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of the inlines for the case functions, which made the
-       header file hard to read.  (Also, in testing with "-O2 -DNDEBUG",
-       the inlines didn't speed up "make check" at all, which is not a
-       perfect benchmark but seems indicative.)
-       
-       * case.c: Remove #ifdef DEBUGGING...#endif around many function
-       definitions.  Remove some assertions on nonnull pointers that were
-       redundant with a pointer dereference soon after in the function.
-       Also:
-       (struct case_data): Move definition here from case.h.
-       (case_data): Ditto.
-       (case_num): Ditto.
-       (case_str): Ditto.
-       (case_data_wr): Ditto.
-       
-Sun Jan 14 21:41:12 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add casedeque.h to sources.
-       
-       * casedeque.h: New file.
-
-       * procedure.c: (struct dataset) Change lag_count, lag_head,
-       lag_queue member into single struct casedeque member.  Update all
-       users to use the casedeque instead.
-       (lag_case) Removed.
-
-Sun Jan 14 21:43:12 2007  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c: Simplify lagged cases interface.  Updated all
-       clients--well, the only client--to use the simplified interface.
-       (dataset_n_lag) Removed.
-       (dataset_set_n_lag) Removed.
-       (dataset_need_lag) New function.
-
-Tue Jan  9 07:20:05 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c procedure.c: More changes to ensure that callbacks occur
-       whenever appropriate, but only when the dataset/dictionary is in a 
-       consistent state.
-
-Sun Jan  7 08:33:04 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c dictionary.h : Added callbacks for change of filter and 
-       split variables.  Refactored some code to ensure that callbacks get
-       invoked when appropriate.
-
-       * procedure.c (proc_cancel_temporary_transformations): Make sure that 
-       replace_dict callback occurs when permanent_dict replaces the current
-       dictionary.
-
-Wed Jan  3 11:02:11 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c dictionary.h : Added callback for when the weight 
-       variable of a dictionary changes.
-
-Mon Jan  1 10:36:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c dictionary.h : Added replace_source and replace_dict
-       callbacks, and functions to deal with them.
-
-Fri Dec 22 13:56:08 2006  Ben Pfaff  <blp@gnu.org>
-
-       Simplify missing value handling.
-
-       * missing-values.h (enum mv_class): New type.
-       (enum mv_type): Moved definition into missing-values.c and renamed
-       each MV_* to MVT_*, to distinguish them from the exposed mv_class
-       enums.  Updated all uses.
-       (struct missing_values): Changed type of `type' from `enum
-       mv_type' to `int' because the definition is no longer exposed.
-       
-       * missing-values.c (mv_is_value_missing): Add new enum mv_class
-       parameter.  Update all callers.
-       (mv_is_num_missing): Ditto.
-       (mv_is_str_missing): Ditto.
-       (mv_is_value_user_missing): Removed.  Changed callers to use
-       mv_is_value_missing.
-       (mv_is_num_user_missing): Removed.  Changed callers to use
-       mv_is_num_missing.
-       (mv_is_str_user_missing): Removed.  Changed callers to use
-       mv_is_str_missing.
-       (mv_is_value_system_missing): Removed.  Changed callers to use
-       mv_is_value_missing.
-       (mv_set_type): Removed.  Changed callers to use mv_clear.
-       (mv_clear): New function.
-       
-       * variable.c (var_is_value_missing): Add new enum mv_class
-       parameter.  Update all callers.
-       (var_is_num_missing): Ditto.
-       (var_is_str_missing): Ditto.
-       (var_is_value_user_missing): Removed.  Changed callers to use
-       var_is_value_missing.
-       (var_is_num_user_missing): Removed.  Changed callers to use
-       var_is_num_missing.
-       (var_is_str_user_missing): Removed.  Changed callers to use
-       var_is_str_missing.
-       (var_is_value_system_missing): Removed.  Changed callers to use
-       var_is_value_missing.
-       
-       * casefilter.c (struct casefilter): Use enum mv_class in place of
-       bool.
-       (casefilter_variable_missing): Adapt to new member.
-       (casefilter_create): Change signature to take enum mv_class,
-       update callers.
-
-Fri Dec 22 20:08:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile-factory.h fastfile-factory.c fastfile-factory.h: New files.
-
-       * case-sink.c case-sink.h procedure.c procedure.h 
-          storage-stream.c: Now uses the factory.
-       
-Sat Dec 16 22:05:18 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make it possible to pull cases from the active file with a
-       function call, instead of requiring indirection through a callback
-       function.
-
-       * case-source.h (struct case_source_class): Change ->read function
-       to return a single case, instead of calling a callback function
-       for each case.  Change ->destroy function to return an error
-       status.
-
-       * case-source.c (free_case_source): Pass along the value returned
-       by the case_source ->destroy function.
-
-       * procedure.c (struct write_case_data): Removed.
-       (struct dataset): Added some members to track procedure state.
-       (procedure): Optimize the trivial case at this level.
-       (internal_procedure): Re-implement in terms of proc_open,
-       proc_read, proc_close.
-       (proc_open) New function.
-       (proc_read) New function.
-       (proc_close) New function.
-       (write_case) Moved into proc_read.
-       (close_active_file) Moved closing of data source into proc_close.
-
-       * storage-source.c: Rewrote to conform with modified
-       case_source_class interface.
-
-       * transformations.c (trns_chain_execute): Added argument to allow
-       starting execution from an arbitrary transformation.  Updated
-       callers.
-
-       * transformations.h (enum TRNS_NEXT_CASE) Renamed TRNS_END_CASE.
-
-Sat Dec 16 14:09:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-reader.c (read_display_parameters): Don't assume that
-       MEASURE_* and ALIGN_* have the same values found in system files.
-
-       * sys-file-writer.c (write_variable_display_parameters): Ditto.
-
-       * variable.h: Change MEASURE_NOMINAL, MEASURE_ORDINAL,
-       MEASURE_SCALE to be 0-based instead of 1-based.  This also fixes
-       the value of n_MEASURES, which was off by 1 (at least from my
-       point of view).
-
-Sat Dec 16 12:17:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * dictionary.c dictionary.h vardict.h variable.c: Added optional
-               callbacks which are invoked when the dictionary or its 
-               variables are changed.  
-       
-       * missing-values.c missing-values.h value-labels.c: Tidied up
-               consistency checks, and made some of them return false 
-               instead of assert-failing. 
-
-Wed Dec 13 19:30:11 2006  Ben Pfaff  <blp@gnu.org>
-
-       * calendar.c (calendar_days_in_month): New function.
-
-Mon Dec 11 07:53:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.c (hash_int_val_lab): Only hash as many bytes as
-       the value label's width.
-
-Sun Dec 10 14:21:29 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sfm-private.h: Move contents into sys-file-writer.c, which is
-       the only remaining user.  Removed Borland C++-specific directives.
-       
-       * sys-file-reader.c: Clean up and rewrite entire file.  The
-       rewritten version is simpler and better abstracted, and should be
-       easier to maintain and extend.  It avoids using structures to read
-       file data, which is prone to padding variations among compilers.
-       It should also handle non-IEEE 754 system files, although I
-       haven't been able to find any.  It has been tested against many
-       .sav files obtained from the Web and found to produce the same
-       results as the earlier version of the code, or in some cases
-       improved results.  It is more tolerant of format variations found
-       in the wild.
-
-       * sys-file-reader.h (struct sfm_read_info): Removed `big_endian'
-       member, putting an enum integer_format in its place.  New member
-       `float_format'.  Changed `compressed' member to type bool.
-
-Sun Dec 10 13:48:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       * dictionary.c (dict_delete_consecutive_vars): New function.
-
-Sat Dec  9 20:08:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * file-name.c (fn_search_path): Remove prefix arg that was unused
-       by any caller.  Updated all callers.
-
-Sat Dec  9 20:04:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c (fmt_dollar_template): Use user's decimal point
-       character.  Add assertion.
-
-Sat Dec  9 20:02:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c (fmt_dollar_template): New function, based on
-       dollar_format_template from var-type-dialog.c.
-
-Sat Dec  9 18:05:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c (output_scientific): Fix bad assumption that "buf" is
-       null-terminated.
-       
-Sat Dec  9 17:23:23 2006  Ben Pfaff  <blp@gnu.org>
-
-       Finish converting struct variable to an opaque type.  In this
-       phase, we add remaining setter and getter functions, convert the
-       remaining PSPP code to use them, and do a bunch of cleanup.  The
-       resulting changes are pervasive but mostly trivial, and only the
-       notable changes are logged.
-       
-       * automake.mk (src_data_libdata_a_SOURCES): Add the new source
-       files.
-       
-       * case.c (case_data): Renamed case_data_idx.
-       (case_num): Renamed case_num_idx.
-       (case_str): Renamed case_str_idx.
-       (case_data_rw): Renamed case_data_rw_idx.
-
-       * case.h (case_data): New function with old name and an interface
-       that takes a variable instead of an index, which is easier to
-       use.  Updated all callers to use the new interface, or to use the
-       new *_idx function (see above).
-       (case_num): Ditto.
-       (case_str): Ditto.
-       (case_data_rw): Ditto.
-       
-       * category.c (cat_stored_values_destroy): Changed interface to
-       take a struct cat_vals * instead of a struct variable *.
-
-       * dictionary.c (dict_clone): Use new vector_clone function.     
-       (dict_clear) Use new var_destroy function.
-       (add_var) New function.
-       (dict_create_var) Rewrite in terms of dict_create_var_assert.
-       (dict_create_var_assert) Rewrite in terms of add_var.
-       (dict_clone_var) Rewrite in terms of dict_clone_var_assert.
-       (dict_clone_var_assert) Rewrite in terms of var_clone, add_var.
-       (dict_lookup_var) Use new var_create, var_destroy functions.
-       (dict_contains_var) Rewrite in terms of new vardict functionality.
-       (set_var_dict_index) New function.
-       (set_var_case_index) New function.
-       (reindex_vars) New function.
-       (dict_delete_var) Rewrite in terms of new vardict functionality.
-       (dict_reorder_var) Ditto.
-       (dict_reorder_vars) Ditto.
-       (rename_var) New function.
-       (dict_rename_var) Use rename_var.
-       (dict_rename_vars) Use pool to simplify code.  Use rename_var.
-       (dict_get_compacted_idx_to_fv) Rename
-       dict_get_compacted_dict_index_to_case_index, update callers.
-       (dict_create_vector) Use new vector_create function.
-       (dict_clear_vectors) Use new vector_destroy function.
-       (set_var_short_name_suffix) Move here from variable.c, renamed
-       from var_set_short_name_suffix, make static, update caller.
-
-       * sys-file-private.c: New file.  
-       (sfm_width_to_bytes) Moved here from variable.c, renamed from
-       width_to_bytes, update callers.
-
-       * sys-file-private.h: New file.  Later it will supplant
-       sfm-private.h; for now it supplements it.
-       (macro MIN_VERY_LONG_STRING) New macro.
-       (macro EFFECTIVE_LONG_STRING_LENGTH) New macro, from value.h.
-
-       * sys-file-reader.c: Use MIN_VERY_LONG_STRING - 1 where
-       MAX_LONG_STRING was used before.
-
-       * sys-file-writer.c: Ditto.
-
-       * value-labels.c: Change the paradigm here to be that a null
-       pointer is OK for a struct val_labs * in most cases; it just
-       represents an empty set of value labels.
-       (val_labs_copy) A copy of a null set is a null set.
-       (val_labs_count) A null set has 0 labels.
-       (val_labs_replace) Change return type to void.  Rewrite for
-       simplicity.
-       (val_labs_find) A null set does not contain the value.
-       (value_to_string) Moved to variable.c, renamed var_get_value_name,
-       transposed argument order, updated all callers.
-
-       * value.c: New file.
-       (value_dup) Moved here from variable.c.
-       (compare_values) Ditto.
-       (hash_value) Ditto.
-
-       * value.h: (macro MAX_SHORT_STRING) Rewrote for simplicity.
-       (macro MAX_LONG_STRING) Removed, because it was only interesting
-       for system files, not for general code.
-       (macro MAX_VERY_LONG_STRING) Ditto.
-       (macro EFFECTIVE_LONG_STRING_LENGTH) Moved to sys-file-private.h.
-       (macro MAX_ELEMS_PER_VALUE) Removed, as it was unused.
-
-       * vardict.h: New file, for an interface between variables and
-       their dictionaries.
-
-       * variable.c: A lot of functions were moved around, for better
-       organization.
-       (struct variable) Move definition here, from variable.h.
-       (var_type_adj) Removed--makes i18n hard.
-       (var_type_noun) Ditto.
-       (var_create) New function.
-       (var_clone) New function.
-       (var_destroy) New function.
-       (var_set_name) Assert that variable is not in a dictionary.
-       (compare_var_names) Rename compare_vars_by_name and fix a couple
-       of callers who thought the args were strings.
-       (hash_var_name) Rename hash_var_by_name.
-       (compare_var_ptr_names) Rename compare_var_ptrs_by_name.
-       (hash_var_ptr_name) Rename hash_var_ptr_by_name.
-       (var_is_very_long_string) Removed, because it was only interesting
-       to system file code.
-       (var_set_missing_values) Allow the argument to be the wrong width,
-       as long as we can resize it.  Simplify callers who were doing the
-       resizing themselves.
-       (var_get_value_labels) New function.
-       (var_has_value_labels) New function.
-       (var_set_value_labels) New function.
-       (alloc_value_labels) New function.
-       (var_add_value_label) New function.
-       (var_replace_value_label) New function.
-       (var_clear_value_labels) New function.
-       (var_lookup_value_label) New function.
-       (var_get_value_name) Moved here from variable.c, renamed from
-       var_get_value_name, transposed argument order, updated all
-       callers.
-       (var_to_string) Moved here, from variable-label.c.
-       (var_set_leave) New function.
-       (var_get_leave) New function.
-       (var_must_leave) New function.
-       (var_set_short_name_suffix) Moved to dictionary.c, renamed
-       set_var_short_name_suffix.
-       (var_get_dict_index) New function.
-       (var_get_case_index) New function.
-       (var_get_obs_vals) New function.
-       (var_set_obs_vals) New function.
-       (var_has_obs_vals) New function.
-       (var_get_vardict) New function.
-       (var_set_vardict) New function.
-       (var_has_vardict) New function.
-       (var_clear_vardict) New function.
-       (value_dup) Moved to value.c.
-       (compare_values) Ditto.
-       (hash_value) Ditto.
-
-       * variable.h: (enum NUMERIC) Rename VAR_NUMERIC, update all users.
-       (enum ALPHA) Rename VAR_STRING, update all users.
-
-       * vector.c: New file.
-       (struct vector) Moved here, from variable.h.
-       (check_widths) New function.
-       (vector_create) New function.
-       (vector_clone) New function.
-       (vector_destroy) New function.
-       (vector_get_name) New function.
-       (vector_get_var) New function.
-       (vector_get_var_cnt) New function.
-       (compare_vector_ptrs_by_name) New function.
-
-       * vector.h: New file.
-
-Sun Dec 10 11:32:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefilter.c (casefilter_variable_missing): Avoided comparision of
-       string variables to SYSMIS.  Thanks to Ben Pfaff for reporting this
-       problem.
-
-Sat Dec  9 07:18:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * value-labels.c (destroy_atoms): New function.
-       * value-labels.c (atom_create): Call destroy_atoms in atexit handler.
-
-Thu Dec  7 17:38:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Thanks to Jason Stover for pointing out this problem.
-       
-       * data-out.c (output_number): Use gsl_finite from GSL, which is
-       portable, instead of isfinite, which is not.
-       (power256) Ditto.
-
-Thu Dec  7 15:22:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * variable.c variable.h (value_dup): New function.
-
-Mon Dec  4 22:20:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start converting struct variable to an opaque type.  In this
-       phase, we add a bunch of setter and getter functions and convert
-       most of the PSPP code to use them.  The resulting changes are
-       pervasive but mostly trivial, and only the notable changes are
-       logged.
-       
-       * format.c (fmt_equal): New function.
-       
-       * variable.c (var_type_is_valid): New function.
-       (measure_is_valid) Moved here, from format.c.
-       (alignment_is_valid) Moved here, from format.c.
-       (var_get_name) New function.
-       (var_set_name) New function.
-       (width_to_type) New function.
-       (var_get_type) New function.
-       (var_get_width) New function.
-       (var_set_width) New function.
-       (var_is_numeric) New function.
-       (var_is_alpha) New function.
-       (var_is_short_string) New function.
-       (var_is_long_string) New function.
-       (var_is_very_long_string) New function.
-       (var_get_missing_values) New function.
-       (var_set_missing_values) New function.
-       (var_clear_missing_values) New function.
-       (var_has_missing_values) New function.
-       (var_is_value_missing) New function.
-       (var_is_num_missing) New function.
-       (var_is_str_missing) New function.
-       (var_is_value_user_missing) New function.
-       (var_is_num_user_missing) New function.
-       (var_is_str_user_missing) New function.
-       (var_is_value_system_missing) New function.
-       (var_get_print_format) New function.
-       (var_set_print_format) New function.
-       (var_get_write_format) New function.
-       (var_set_write_format) New function.
-       (var_set_both_formats) New function.
-       (var_get_label) New function.
-       (var_set_label) New function.
-       (var_clear_label) New function.
-       (var_has_label) New function.
-       (var_get_measure) New function.
-       (var_set_measure) New function.
-       (var_get_display_width) New function.
-       (var_set_display_width) New function.
-       (var_get_alignment) New function.
-       (var_set_alignment) New function.
-       (var_get_value_cnt) New function.
-       (var_get_leave) New function.
-       (var_get_short_name) New function.
-
-       * variable.h: (struct variable) Removed "type" and "nv" members;
-       they are now computed from "width" where needed.
-
-Mon Dec  4 21:38:40 2006  Ben Pfaff  <blp@gnu.org>
-
-       * missing-values.c (mv_resize): Don't write beyond end of the
-       allocated buffer when resizing a long string.
-
-Sat Dec  2 16:28:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       Clean up identifier code: don't require identifier enumerations to
-       be in a particular order; make better use of string library;
-       expose less of the internals.
-               
-       * identifier.c: (lex_skip_identifier) Rename lex_id_get_length,
-       change interface.  Updated all callers.
-       (lex_id_match) Change interface to use struct substring, update
-       all callers.
-       (lex_id_match_len) Removed.  Update callers to use lex_id_match.
-       (global array keywords[]) Make static, change form.  Update all
-       users to use lex_id_name instead.
-       (lex_is_keyword) New function.
-       (lex_id_to_token) Change interface to use struct substring, update
-       all callers.
-       (lex_id_name) New function.
-
-       * identifier.h: (T_FIRST_KEYWORD) Removed.  Changed users to call
-       lex_is_keyword instead.
-       (T_LAST_KEYWORD) Removed.
-       (T_N_KEYWORDS) Removed.
-       
-Sat Nov 18 20:46:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (fmt_date_template) Distinguish characters for which a
-       space is output and any date delimiter is allowed on input, from
-       those for which a space is output and only a space is allowed on
-       input.  The former is represented by X, the latter by a space.
-       Also, drop distinction between h and H, changing the former to the
-       latter.
-
-       * data-in.c: Completely rewrite internals to conform to SPSS input
-       formats as closely as possible.
-       (data_in) Changed external interface by replacing the structure
-       that was used as a single argument by a set of arguments.  Updated
-       all callers.
-       (data_in_finite_line) Removed.  Converted all callers to use plain
-       data_in.
-       (data_in_get_integer_format) New function.
-       (data_in_set_integer_format) New function.
-       (data_in_get_float_format) New function.
-       (data_in_set_float_format) New function.
-
-       * data-in.h: (enums DI_IGNORE_ERROR, DI_IMPLIED_DECIMALS) Removed.
-       (struct data_in) Removed.
-
-       * data-out.c: (output_date) Drop each component from the input as
-       it is output, to allow us to drop the distinction between h (a
-       count of hours) and H (the hour of day) template characters.
-       Also, handle new X template character.
-       (output_scientific) Follow more rational rule on when to drop
-       fraction introduced between SPSS 13 and 15.  Updated test case to
-       match new behavior.
-
-Sat Nov 11 11:41:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix buffer overflow reported by John Darrington.
-
-       * data-out.c (output_bcd_integer): In case of SYSMIS, etc.,
-       realize that DIGITS is a count of nibbles, not of bytes.
-
-Sat Nov  4 15:59:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * calendar.c (calendar_offset_to_gregorian) Also return the
-       year-of-day.  Change callers to new interface.
-
-       * data-out.c: Completely rewrite internals to conform to SPSS
-       output formats as completely as possible.
-       (data_out) Change interface to put input parameters before output
-       parameters, for consistency with the style I now prefer.  Update
-       all callers.
-       (data_out_get_integer_format) New public function.
-       (data_out_set_integer_format) New public function.
-       (data_out_get_float_format) New public function.
-       (data_out_set_float_format) New public function.
-
-       * data-out.h: New file.  Move prototype for data_out here, from
-       format.h.
-
-       * format.c: (fmt_step_width) Use equality comparison instead of
-       bitwise and, for clarity.
-       (fmt_is_string) Ditto.
-       (fmt_input_to_output) Fix categories that are translated to F
-       format.
-
-Sun Nov  5 08:29:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefilter.c casefilter.h (new files), casefile.c casefile.h 
-       casefile-private.h: Added casefilter to assist commands with missing 
-       values.
-
-Sat Nov  4 11:47:09 2006  Ben Pfaff  <blp@gnu.org>
-
-       Implement SET ERRORS, SHOW ERRORS.  Fixes bug #17609.
-       
-       * settings.c: (route_errors_to_terminal) New variable.
-       (route_errors_to_listing) New variable. 
-       (get_error_routing_to_terminal) New function.
-       (set_error_routing_to_terminal) New function.
-       (get_error_routing_to_listing) New function.
-       (set_error_routing_to_listing) New function.
-
-       * settings.h: (SET_ROUTE_* enums) Removed, because unused.
-
-Tue Oct 31 19:58:27 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: Completely rewrite, to achieve better abstraction.
-       Rewrite all references to formats in other files.
-       
-       * format.def: Rewrite and reorganize.
-
-       * settings.c: Move everything related to custom currency formats
-       into format.[ch], changing them in form, so as to group related
-       code and definitions better.  Changed all references to use the
-       new functions.
-       (static var decimal) Removed.
-       (static var grouping) Removed.
-       (static var cc) Removed.
-       (get_decimal) Removed.
-       (set_decimal) Removed.
-       (get_grouping) Removed.
-       (set_grouping) Removed.
-       (get_cc) Removed.
-       (set_cc) Removed.
-
-       * settings.h: (macro CC_CNT) Removed.
-       (macro CC_WIDTH) Removed.
-       (struct custom_currency) Removed.
-
-Tue Oct 31 19:56:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c (data_in): Use switch statement instead of table, to
-       avoid dependence on the order of the FMT_* enums.
-
-Tue Oct 31 19:35:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-out.c: (num_to_string) Removed, because it was dead code.
-
-Tue Oct 31 18:09:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-in.c (parse_trailer): Fix error message.
-
-Sat Oct 28 11:56:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c (fmt_is_binary): New function.
-
-Thu Oct 19 22:59:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * procedure.c procedure.h: Encapsulated the static data into a single
-       struct.  
-
-Sat Oct 14 16:56:44 2006  Ben Pfaff  <blp@gnu.org>
-
-       * casefile.c (casereader_read_xfer): Always initialize the case,
-       even on an error condition.
-
-Wed Sep 27 09:37:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * procedure.c (case_limit_trns_proc): Fixed buglet which rendered the 
-       entire function useless.
-
-Mon Sep 25 17:11:46 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile-private.h casefile.c casefile.h fastfile.c: Created new
-       casereader method casereader_clone.   
-       
-       * procedure.c pransformations.h: Introduced new type casenum_t
-
-Thu Sep 21 07:00:30 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.c: (width_to_bytes) Rephrase code for clarify.
-
-Sun Jul 16 19:52:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c: (fmt_type_from_string) New function.
-       (fmt_to_string) Include decimals in output if the format has
-       decimals, even if the format type does not.  This way, we can
-       accurately reproduce incorrect formats in user output.
-       (check_common_specifier) Make the check for a bad format type an
-       assertion, so we get bug reports if they show up.  Fix message.
-       Check for decimal places with a format type that doesn't allow
-       them.
-       (check_input_specifier) Remove check for FMT_X, which has been
-       deleted.
-       (check_output_specifier) Ditto. 
-
-       * format.def: Remove FMT_T, FMT_X, FMT_DESCEND, FMT_NEWREC.
-
-       * format.h: (macro FMT_TYPE_LEN_MAX) New macro.
-       (struct fmt_desc) Use FMT_TYPE_LEN_MAX in definition.
-       (enum fmt_parse_flags) Removed.
-
-Mon Jul 17 18:26:21 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile.c casefile.h: Converted to  an abstract base class.
-       * casefile-private.h fastfile.c fastfile.h: New files.
-       * automake.mk procedure.c scratch-writer.c storage-stream.c
-
-Wed Jul 12 21:02:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c (internal_procedure): Create sink_case with only as
-       many values as the compacted dictionary.
-
-Wed Jul 12 21:01:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove "debugging" code that caused plenty of false positives and
-       no true positives.
-       
-       * case.h (struct ccase): [DEBUGGING] Remove `this' member.
-
-       * case.c: Remove all references to `this' member.
-
-Thu Jul  6 19:09:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix link error noted by Jason Stover.
-       
-       * storage-stream.c: Include <assert.h>.
-
-Tue Jul  4 08:47:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
-       ALL) and additional underlying system file issues.
-
-       Thanks to John Darrington for review.
-
-       First problem: var_hash points to variables not owned by the
-       sys-file-reader, which the caller may free or modify.  Use an
-       array of sfm_vars instead, as done earlier (e.g. CVS version
-       1.12).
-       
-       * sys-file-reader.c (struct sfm_reader): Remove var_hash, svars
-       members and remove all code that references it.  Add vars, var_cnt
-       members.  Remove fix_specials member, which was unused.
-       (struct sfm_var) Remove name member, which was unused.
-       (sfm_close_reader) Free vars member instead of var_hash.
-       (compare_var_shortnames) Removed.
-       (hash_var_shortname) Removed.
-       (sfm_open_reader) Fill out vars array.
-       (compare_var_index) Removed.
-       (sfm_read_case) Use vars instead of var_hash.
-       
-       Second problem: we're confused about when we actually have very
-       long strings, causing us to choose incorrectly between slow path
-       and fast path in sfm_read_case.
-
-       * sys-file-reader.c: (sfm_open_reader) Only mark has_vls if we
-       have very long strings, not when we have long variable names,
-       which is an unrelated feature.
-
-Tue Jun 27 12:06:49 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.h: Move var_set and variable parsing declarations to
-       new header, src/language/lexer/variable-parser.h.  Modified lots
-       of files to include the new header.
-
-Sun Jun 25 22:39:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.c (value_to_string): When there's no value label,
-       format the variable according to its print format, instead of
-       always effectively using A or F format.
-
-Mon Jun 19 18:05:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * casefile.c (casefile_get_random_reader): Nasty hack to get around 
-       the mode assertion.
-
-       * format.c: Removed tortological assertion.
-
-Fri Jun  9 12:20:09 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * file-name.c (fn_interp_vars): Change interface to take a
-       substring as input.  Updated all users.
-       
-Fri Jun  9 12:11:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format.c (measure_is_valid): Really return false when m >=
-       n_MEASURES.
-
-Tue Jun  6 18:46:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Implement random access to casefiles, for use in GUI.
-       
-       * casefile.c: (struct casereader) Add `random', `file_ofs',
-       `buffer_ofs' members.
-       (casefile_get_random_reader) New function.
-       (read_open_file) Break part into new function
-       seek_and_fill_buffer().
-       (fill_buffer) Update buffer_ofs, file_ofs.
-       (casereader_seek) New function.
-
-Tue May 30 19:52:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * settings.c: Added call to i18n{done, init}.
-
-Tue May  9 21:09:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.h: Add WARN_UNUSED_RESULT to procedure function
-       prototypes.
-
-Tue May  9 21:08:05 2006  Ben Pfaff  <blp@gnu.org>
-
-       * casefile.c: Convert many uses of `int' to `bool'.
-
-Sat May  6 22:49:43 2006  Ben Pfaff  <blp@gnu.org>
-
-       * transformations.c (trns_chain_destroy): Destroy chain's trns
-       member, to fix memory leak.
-
-Sat May  6 22:48:30 2006  Ben Pfaff  <blp@gnu.org>
-
-       * storage-stream.c (storage_source_decapsulate): Destroy case
-       source to fix memory leak.
-
-Sat May  6 22:46:47 2006  Ben Pfaff  <blp@gnu.org>
-
-       * scratch-reader.c (scratch_reader_read_case): Copy into existing
-       case passed as argument instead of initializing the argument as a
-       case.  Fixes memory leak that showed up in
-       tests/command/aggregate.sh with scratch files.
-
-Sat May  6 22:45:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       * procedure.c (proc_done): Destroy default_dict, to fix memory
-       leak.
-
-Sat May  6 22:44:44 2006  Ben Pfaff  <blp@gnu.org>
-
-       Simplify procedure_with_splits().
-       
-       * procedure.c (struct split_aux_data): Removed case_count member.
-       (procedure_with_splits) Don't initialize case_count.
-       (split_procedure_case_func) Check whether prev_case is null
-       instead of case_count.
-       (split_procedure_end_func) Ditto.
-
-Sat May  6 22:42:23 2006  Ben Pfaff  <blp@gnu.org>
-
-       * case.c (case_move): Do nothing if dst and src are the same
-       object.
-       (case_try_create) Merge two similar cases.
-       (case_copy) Unshare only if data must be actually copied.
-
-Sun May  7 10:04:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-in.c data-out.c dictionary.c sys-file-reader.c
-       sys-file-writer.c variable.c variable.h:  Reworked very long string
-       support for better encapsulation.
-
-Sat May  6 19:02:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.c (val_labs_can_set_width): New function.
-       (val_labs_set_width) Clear labels if increasing width to long
-       string.
-       (val_labs_destroy) Remove unneeded test for null.
-       
-Sat May  6 16:14:08 2006  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.h: Remove unneeded dependency on variable.h.
-
-Sat May  6 15:58:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of `char *c' member in union value, for cleanliness.
-       
-       * value.h: (union value) Remove `c' member.
-
-Sat May  6 15:36:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make dictionary compacting functions a little more general.
-       
-       * sys-file-writer.c (sfm_open_writer): Use
-       dict_compacting_would_change().
-       (does_dict_need_translation) Removed.
-
-Sat May  6 15:35:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make dictionary compacting functions a little more general.
-       
-       * dictionary.c (dict_needs_compaction): Rename
-       dict_compacting_would_shrink().  Update all callers.
-       (dict_compacting_would_change) New function.
-       
-Sat May  6 14:25:49 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-writer.c: (does_dict_need_translation) Fix bug:
-       inverted return value (!).
-
-Sat May  6 13:37:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  
-
-       * procedure.c: Search and replace "vfm" by "proc".  Notably:
-       (static var vfm_source) Rename proc_source.  Update all
-       references.
-       (static var vfm_sink) Rename proc_sink.  Update all references.
-       
-Sat May  6 12:38:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, remove
-       PROCESS IF, which was deprecated anyway and can be easily
-       simulated with TEMPORARY followed by SELECT IF.
-
-       * procedure.c: (open_active_file) Don't call
-       add_process_if_trns().
-       (discard_variables) Get rid of redundant call to
-       proc_cancel_all_transformations().
-       (add_process_if_trns) Removed.
-       (process_if_trns_proc) Removed.
-       (process_if_trns_free) Removed.
-
-Sat May  6 10:58:05 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, add
-       `const' to the case passed to procedure()'s callback.
-
-       Updated all users of procedure() as well.
-       
-       * procedure.c: (struct write_case_data) Add "const" to ccase
-       parameter for case_func member.
-       (procedure) Add "const" to ccase parameter for proc_func
-       parameter.
-       (multipass_case_func) Make ccase parameter const.
-       (internal_procedure) Add "const" to ccase parameter for case_func
-       parameter.
-       (split_procedure_case_func) Make ccase parameter const.
-       (multipass_split_case_func) Make ccase parameter const.
-       
-Sat May  6 10:30:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       the output code for SPLIT FILE groups in procedure.c, which really
-       shouldn't be doing any output.  Move it into the individual
-       procedures instead.  This also adds some flexibility.
-
-       Updated many users of procedure_with_splits() and
-       multipass_procedure_with_splits() to call
-       output_split_file_values() and to deal with increased use of
-       const.
-
-       * procedure.c: (struct split_aux_data) Add "const struct ccase *"
-       parameter to begin_func member.
-       (procedure_with_splits) Add "const struct ccase *" parameter to
-       begin_func parameter.  Make ccase parameter const in proc_func
-       parameter.
-       (split_procedure_case_func) Don't dump split file group.  Pass
-       case to begin_func.
-       (dump_splits) Moved to language/dictionary/split-file.c as
-       output_split_file_values().
-       (struct multipass_split_aux_data) Add "const struct ccase *"
-       parameter to split_func member.
-       (multipass_procedure_with_splits) Add "const struct ccase *"
-       parameter to split_func parameter.
-       (multipass_split_case_func) Save new SPLIT FILE case before
-       outputting case.
-       (multipass_split_output) Pass saved SPLIT FILE case to split_func.
-       
-Fri May  5 22:48:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  Change
-       internal_procedure() so that it calls open_active_file() and
-       close_active_file(), which isolates most of the actual procedure
-       functionality.
-
-       * procedure.c: (struct write_case_data) Rename `proc_func' member
-       to `case_func' and update all references.
-       (procedure) Rewrite as one-line wrapper around
-       internal_procedure().
-       (struct multipass_aux_data) New.
-       (multipass_callback) Renamed multipass_case_func().  Use struct
-       multipass_aux_data as auxiliary data.
-       (multipass_end_func) New function.
-       (multipass_procedure) Rewrite as wrapper for internal_procedure()
-       that uses multipass_case_func, multipass_end_func.
-       (internal_procedure) Add `end_func' argument.  Move optimization
-       of trivial case in here.  Move call to open_active_file() and
-       close_active_file() in here.  Now assert that vfm_source is
-       non-null.
-       (procedure_with_splits_callback) Rename
-       split_procedure_case_func().
-       (split_procedure_end_func) New function.
-       (multipass_split_callback) Rename multipass_split_case_func.
-       (multipass_split_end_func) New function.
-       (discard_variables) No need to test for nonnull vfm_source.
-
-Fri May  5 21:34:02 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  Get rid of unused member.
-
-       * procedure.c: (struct write_case_data) Remove `cases_analyzed'
-       member.
-       (write_case) Don't increment cases_analyzed.
-
-Thu May  4 21:50:11 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, move
-       procedure.c and procedure.h from src to src/data.  Update
-       makefiles and #includes accordingly.
-
-       * procedure.c: Moved here from src/.
-
-       * procedure.h: Moved here from src/.
-
-Wed May  3 22:42:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * automake.mk: (src_data_libdata_a_SOURCES) Add transformations.c,
-       transformations.h.
-
-       * dictionary.c: (global variable default_dict) Move to
-       src/procedure.c.
-
-       * variable.h: (TRNS_*) Move to transformations.h.
-       (struct transformation) Move to transformations.c.
-
-Thu May  4 13:47:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * sys-file-reader.c: Fixed invalid read problems.
-
-Tue May  2 15:57:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       * storage-stream.c: Add missing function comments.
-
-Tue May  2 15:50:21 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, add some
-       new, needed functionality to storage-stream.
-
-       * storage-stream.c: (storage_source_decapsulate) New function.
-
-Tue May  2 15:43:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.c (width_to_bytes): Declarations must precede
-       statements for C90 compliance.
-
-Tue May  2 10:42:05 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-out.c, data-in.c, variable.c, variable.h: New functions 
-       copy_mangle and copy_demangle for reading/writing cases; emulates the 
-       way SPSS deals with strings > 255 bytes.
-
-       * sys-file-reader.c sys-file-writer.c: Added support for Record 7, 
-       subtype 14 needed for strings longer than 255 bytes.
-
-       * dictionary.c, format.def, value.c : Updated to use MAX_STRING 
-        instead of literal values. Also fixed some constness issues.
-
-       * format.h: Constness
-
-       * sfm-private.h: Renamed the case_size identifier, since I discovered 
-        that SPSS's respect for this variable is very nominal.
-
-Mon May  1 15:45:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       Change case limit type from int to size_t.
-
-       * dictionary.c: (struct dictionary) Change type of case_limit
-       member.
-       (dict_get_case_limit) Change return type.
-       (dict_set_case_limit) Change parameter type.
-
-Wed Apr 26 20:01:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.h: (struct variable) Rename `reinit' member as `leave'
-       and invert sense.  Fix up all references.
-
-Wed Apr 26 19:39:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, break
-       procedure.c into multiple files.
-       
-       * automake.mk: (src_data_libdata_a_SOURCES) Add all the new files.
-
-       * case-sink.c: New file.
-
-       * case-sink.h: New file.
-       
-       * case-source.c: New file.
-
-       * case-source.h: New file.
-       
-       * storage-stream.c: New file.
-
-       * storage-stream.h: New file.
-
-Wed Apr 26 14:55:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.h: (struct variable) Remove `init' member and all
-       references to it from other files.  It was initialized in several
-       places, but nothing really ever used it for anything worthwhile.
-       Thanks to Jason Stover for pointing out how confusing this
-       member is.
-
-Sun Apr 23 22:04:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-       
-       * casefile.c: (io_error) Use err_msg() instead of err_vmsg().
-       Format message ourselves.
-
-       * data-in.c: (vdls_error) Ditto.
-
-       * por-file-reader.c: (error) Ditto.
-
-       * sys-file-reader.c: (corrupt_msg) Ditto.
-
-Sun Apr 16 18:49:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       GNU standards require "file name" instead of "filename" in
-       documentation.  It's nice for our code to follow the convention
-       too.
-       
-       * casefile.c: (struct casefile) Rename `filename' member to
-       `file_name'.  Updated all references.
-
-       * file-name.c: [!unix] (struct file_identity) Rename
-       normalized_filename member to normalized_file_name.  Updated all
-       references.
-
-Sun Apr 16 18:35:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       We don't really support anything but Unix-like environments well,
-       so we might as well de-obfuscate by writing directory and path
-       separators explicitly.
-
-       * file-name.h: (macro DIR_SEPARATOR) Removed.  Changed all usages
-       to just '/'.
-       (macro PATH_SEPARATOR) Removed.  Changed all usages to just ':'.
-       (macro DIR_SEPARATOR_STRING) Removed.  Changed all usages to just
-       "/".
-       (macro PATH_SEPARATOR_STRING) Removed.  Changed all usages to just
-       ":"
-
-Sun Apr 16 18:28:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       GNU standards require "file name" instead of "filename" in
-       documentation.  It's nice for our code to follow the convention
-       too.
-       
-       * filename.c: Rename to file-name.c.
-
-       * filename.h: Rename to file-name.h.  Update all inclusions.
-       Update header guards.
-
-       * automake.mk: Update file names.
-
-Sun Apr 16 16:42:47 2006  Ben Pfaff  <blp@gnu.org>
-
-       * filename.c: (fn_dirname) Renamed fn_dir_name(), all references
-       updated.
-       (fn_basename) Removed (dead code).
-       (fn_absolute_p) Renamed fn_is_absolute(), all references updated.
-       (fn_special_p) Renamed fn_is_special(), all references updated.
-       (fn_exists_p) Renamed fn_exists(), all references updated.
-
-Sun Apr 16 16:33:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * filename.c: (fn_tilde_expand) Rewrite for cleaner code.  
-       Also, now it only tilde-expands file names, not paths.
-       (fn_search_path) Tilde-expand one directory at a time.
-
-Sun Apr 16 16:28:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * filename.c: (fn_search_path) rewrite for cleaner code.  Also,
-       get rid of non-Unixlike version of the code, which has probably
-       never been tested.
-       (fn_prepend_dir) Removed (dead code).
-
-       * filename.h: (macro DIR_SEPARATOR_STRING) New.
-       (macro PATH_SEPARATOR_STRING) New.
-Sun Apr 16 16:05:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we get
-       rid of VM() and the other msg() support for "verbosity", replacing
-       it by a new function verbose_msg().
-
-       * filename.c: (fn_search_path) Use verbose_msg() instead of
-       msg(VM(), ...).  
-
-Sat Apr 15 19:53:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sfm-private.h: Get rid of #defines after #error, which makes no
-       sense.
-
-Sat Apr 15 19:48:57 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of our own int32 type in favor of the standard int32_t
-       type.
-       
-       * sfm-private.h: (int32 macro) Don't define this anymore.  Do
-       include <stdint.h>.
-
-       * sys-file-reader.c: Use int32_t instead of int32 throughout.
-       
-       * sys-file-writer.c: Use int32_t instead of int32 throughout.
-
-Sat Apr 15 19:36:47 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove ill-considered file routines that are no longer used.
-       
-       * filename.c: (fn_open_ext) Removed.
-       (fn_close_ext) Removed.
-
-       * filename.h: (struct file_ext) Removed.
-
-Mon Apr  3 13:22:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable.c (var_is_valid_name): Move declarations before code
-       for C90 compliance.
-
-Tue Apr  4 15:28:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * filename.ch (fn_interp_vars): Fixed small buglet.
-
-Tue Mar 28 13:47:16 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * filename.[ch] (fn_interp_vars): Changed the signature and semantics
-       so as to modify the string inline.   Thus makeing it easier to
-       destroy the results when no longer needed.
-       
-2006-03-25  Jason Stover  <jhs@math.gcsu.edu>
-
-       * category.c (cat_stored_values_destroy): Fixed memory leak.
-
-Fri Mar 24 18:15:41 2006  Ben Pfaff  <blp@gnu.org>
-
-       Add some missing frees.  Thanks to John Darrington for reporting
-       these.
-
-       * any-writer.c (any_writer_close): Free writer.
-
-       * any-reader.c (any_reader_close): Free reader.
-
-Mon Mar 20 16:33:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       * por-file-reader.c: (error) Mark as NO_RETURN.
-
-Sat Mar 11 15:06:07 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * settings.c: Changed default value of scompress to true.
-
-Sat Mar  4 13:22:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sfm-private.h: Include variable.h, to get SHORT_NAME_LEN.
-
-       * value.h: Remove check on MAX_SHORT_STRING, which I don't think
-       really applies.
-
-       * variable.h: Move definition of SHORT_NAME_LEN, LONG_NAME_LEN
-       here from pref.h.orig.
-
-Sat Mar  4 12:50:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * sys-file-reader.c: Fixed bug reading compressed files.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * Numerous renames.  See src/ChangeLog for details.
-       
-       * Moved files from src directory
diff --git a/src/data/OChangeLog b/src/data/OChangeLog
new file mode 100644 (file)
index 0000000..ef91902
--- /dev/null
@@ -0,0 +1,2541 @@
+2008-07-25  Ben Pfaff  <blp@gnu.org>
+
+       * casereader-translator.c (struct casereader_arithmetic_sequence):
+       New struct.
+       (casereader_create_arithmetic_sequence): New function.
+       (cas_translate): New function.
+       (cas_destroy): New function.
+
+2008-07-26  John Darrington <john@darrington.wattle.id.au>
+
+       * case-ordering.c case-ordering.h: Removed the value_cnt
+       associated with the ordering structure.
+
+2008-07-16  Jason Stover  <jhs@math.gcsu.edu>
+
+       * category.c (cat_get_category_count): New function.
+
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+
+       * data-out.c (output_infinite): Use gsl_isnan instead of isnan,
+       and gsl_isinf instead of isinf, as a stopgap measure for
+       portability until appropriate gnulib modules are available.
+
+       * por-file-writer.c (format_trig_double): Similarly, use
+       gsl_finite instead of finite.
+
+2008-03-18  John Darrington <john@darrington.wattle.id.au>
+
+       * data-in.c: If category is custom currency, then use
+       numeric format for input.
+
+2008-03-06  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (var_name_is_insertable): New function.
+       (make_hinted_name): Don't accept variable names that match PSPP
+       keywords.  Thanks to Jason Stover for reporting the problem.
+
+2008-03-06  Ben Pfaff  <blp@gnu.org>
+
+       * format-guesser.c (syntax): Require month names to be spelled out
+       as English words, so that single characters that happen to be
+       Roman numerals don't get detected as months.  Thanks to John
+       Darrington for reporting this bug.
+
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6441.  Reviewed by John Darrington.
+
+       * format.c (fmt_fix): New function.
+       (fmt_fix_input): New function.
+       (fmt_fix_output): New function.
+
+       * format.def: Correct minimum width for DATETIME format.  It was
+       7, should have been 17.
+
+       * automake.mk: Add new files.
+
+       * format-guesser.c: New file.
+
+       * format-guesser.h: New file.
+
+2008-02-18  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6426.  Reviewed by John Darrington.
+       
+       * format.c (min_width): Renamed fmt_min_width and made public.
+       Updated all references.
+       (max_width): Renamed fmt_max_width and made public.  Updated all
+       references.
+       (max_decimals): Renamed fmt_max_decimals and made public.  Updated
+       all references.
+       (var_create): Use the new functions for default variable
+       attributes below.
+       (var_default_formats): New function.
+       (var_default_measure): New function.
+       (var_default_alignment): New function.
+
+       * format.h (macro FMT_MAX_NUMERIC_WIDTH): New macro.
+
+2008-02-09  Ben Pfaff  <blp@gnu.org>
+
+       Add a couple of extensions to GET DATA TYPE=TXT.  Patch #6412.
+       Thanks to John Darrington for review.
+
+       * data-in.c (data_in): Add new argument to designate the last
+       column of the data field being parsed, for use in error messages.
+       Update all callers.
+
+       * data-parser (struct data_parser): New member `quote_escape'.
+       (data_parser_create): Initialize quote_escape.
+       (data_parser_set_quotes): New function.
+       (cut_field): Support escaped quotes.
+       (parse_delimited_span): Ditto.
+       (parse_delimited_no_span): Ditto.
+
+       * get-data.c (parse_get_txt): Support ESCAPE extension subcommand
+       in enhanced mode.  Only support multiple quote characters in
+       enhanced mode.
+
+2008-02-06  John Darrington <john@darrington.wattle.id.au>
+
+       psql-reader.c psql-reader.h: Read more than one tuple at
+       once.  Fix bug reading a query which returns no data. Fix bug
+       when transformation followed a reader.
+       Ask the server for the number of records in the query, for the
+       benefit of the gui.
+
+2008-02-05  John Darrington <john@darrington.wattle.id.au>
+
+       psql-reader.c: So yesterday they release postgresql 8.3.0
+       which has money represented with 64 bits.  They must get
+       paid more than me.
+
+2008-02-02  John Darrington <john@darrington.wattle.id.au>
+
+       psql-reader.c psql-reader.h: New files.  Thanks to Ben Pfaff
+       for reviewing this code.
+       
+2008-02-02  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6347.
+
+       * sys-file-reader.c (read_variable_record): Allow missing values
+       to be specified on long string variables, but warn about them
+       because PSPP does not yet support them.
+       (read_extension_record): Ignore extension records 20 and 21, which
+       PSPP does not yet support.
+       (read_header): Fix error message when floating-point format cannot
+       be identified.
+
+2008-02-01  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6386.  Thanks to John Darrington for review and for the
+       updates to gnumeric-reader.c.
+
+       * dictionary.c (make_hinted_name): New function.
+       (make_numeric_name): New function.
+       (dict_make_unique_var_name): New function.
+
+       * gnumeric-reader.c (devise_name): Removed.
+       (munge_name): Removed.
+       (gnumeric_open_reader): Use new function
+       dict_make_unique_var_name.
+
+       * short-names.c (set_var_short_name_suffix): Use new function
+       str_format_26adic.
+
+2008-01-19  John Darrington <john@darrington.wattle.id.au>
+
+       * settings.c settings.h: Moved static variables into a 
+       single struct.  Renamed functions to have a settings_ prefix.
+
+2008-01-14  John Darrington <john@darrington.wattle.id.au>
+
+       * data-out.c (output_AHEX): Corrected number of bytes in
+       call to output_hex.  Closes bug #22011
+
+2008-01-02  John Darrington <john@darrington.wattle.id.au>
+
+       * variable.c variable.h: Replaced var_get_value_name with 
+       var_append_value_name which doesn't use any static data.
+        Thanks to Ben for review.
+
+2007-12-07  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6302.
+
+       * casegrouper.c (casegrouper_get_next_group): Cause a casegrouper
+       made from an empty casereader produce a casegrouper with no
+       groups, instead of one with one group that has no cases.
+
+       * casereader.c (casereader_is_empty): New function.
+
+2007-12-06  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6303.
+
+       * sys-file-reader.c (read_display_parameters): Handle variable
+       display parameters record with only 2 data items per variable.
+       Reported by Guido Gay <gay@irer.it>.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * identifier.c (lex_id_match_n): New function.
+       (lex_id_match): Reimplement in terms of lex_id_match_n.
+
+2007-11-24  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (src_data_libdata_a_SOURCES): Add val-type.h, to fix
+       make distcheck.
+
+2007-11-24  Ben Pfaff  <blp@gnu.org>
+
+       Fix warning reported when reading back system files that include
+       very long string variables.  Thanks to Guido Gay <gay@irer.it> for
+       reporting this bug.
+
+       * short-names.c (short_names_assign): Fix dumb typo, in which `i'
+       was written where `j' was meant.
+
+2007-11-18  Ben Pfaff  <blp@gnu.org>
+
+       Properly write variables that include a range of missing values to
+       system files.  Thanks to Guido Gay <gay@irer.it> for reporting
+       this bug.
+
+       * sys-file-writer.c (write_variable): Correctly calculate
+       n_missing_values field when writing variables that include a range
+       of missing values.
+
+2007-11-10  Ben Pfaff  <blp@gnu.org>
+
+       Cleanups and bug fixes devised while writing up documentation.
+       Patch #6262.
+
+       * automake.mk (src_data_libdata_a_SOURCES): Add new files.
+
+       * dict-class.c: New file.
+       (dict_class_from_id): Move here.
+       (dict_class_to_name): Move here.
+
+       * dict-class.h: New file.
+       (enum dict_class): Move here.  Change from consecutive integers to
+       consecutive bits, to make testing for any of multiple values
+       easier.  Add new DC_ALL constant.
+
+       * dictionary.c (struct dictionary): Change `case_limit' from
+       size_t to casenumber.
+       (dict_get_vars): Make final argument an enum dict_class.
+       (dict_get_vars_mutable): Ditto.
+       (dict_get_case_limit): Change return value to casenumber.
+       (dict_set_case_limit): Change final argument to a casenumber.
+       (dict_unset_split_var): Add assertion.  Rephrase slightly.
+       (dict_set_label): Use xstrndup to simplify.
+
+       * format.c (fmt_step_width): AHEX format also needs 2-byte
+       stepping.
+       (fmt_set_style): Simplify assertions.
+
+       * missing-values.c (mv_add_num_range): Rename mv_add_range.
+       Simplify implementation.
+       (mv_has_value): Simplify implementation.
+       (mv_pop_value): Remove the first value, not the last, to avoid
+       having GET followed by SAVE reverse the order of missing values.
+       (mv_peek_value): Rename mv_get_value.  Simplify assertion.
+       (mv_has_range): Simplify implementation.
+       (mv_peek_range): Rename mv_get_range.
+       (can_resize_string): Removed.
+       (mv_is_resizable): Use value_is_resizable.
+       (mv_resize): Use value_resize.
+
+       * short-names.h (SHORT_NAME_LEN): Move here.
+
+       * val-type.h: New file, for definitions related to type and width
+       of abstract values.  Before, these definitions were mixed among
+       those related to "union value" and those related to variables.
+       (macro SYSMIS): Move here.
+       (macro LOWEST): Move here.
+       (macro HIGHEST): Move here.
+       (macro MAX_STRING); Move here.
+       (enum val_type): New enum with values VAL_NUMERIC and VAL_STRING.
+       Replaces enum var_type that had values VAR_NUMERIC and VAR_STRING.
+       All references updated.
+       (val_type_is_valid): New function.  Replaces var_type_is_valid.
+       All references updated.
+       (val_type_from_width): New function.  Replaces
+       var_type_from_width.  All references updated.
+
+       * value-labels.c (val_labs_copy): Renamed val_labs_clone.  All
+       references updated.
+       (val_labs_can_set_width): Use value_is_resizable.
+       (val_labs_add): Simply return false if the value labels set is too
+       wide, instead of having undefined behavior.
+       (val_labs_replace): Ditto.
+       (val_labs_replace): Ditto.
+       (val_labs_first): Set iterator to null if iteration is complete.
+       (val_labs_first_sorted): Ditto.
+       (val_labs_done): Become a no-op if the iterator is null.
+
+       * value.c (value_is_resizable): New function.
+       (value_resize): New function.
+
+       * variable.c (var_get_dict_class): New function.
+
+       * variable.h (macro LONG_NAME_LEN): Rename VAR_NAME_LEN.  Update
+       all references.
+
+2007-11-08  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c: Make formatted data parsing locale-independent.
+       (parse_number): Use c_strtod instead of strtod, to avoid
+       locale-specific behavior.
+       (parse_Z): Ditto.
+
+2007-11-06  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6256: add support for binary, 360 file formats.  Reviewed
+       by John Darrington.
+
+       * data-in.c (struct data_in): Add `encoding' member.
+       (data_in): Add `encoding' parameter, and re-encode the data passed
+       in where appropriate.  Update all callers to pass it in.
+       (parse_A): Implement EBCDIC recoding wart described in manual.
+       (parse_AHEX): Implement EBCDIC recoding.
+
+       * data-out.c (data_out_legacy): New function.
+       (data_out): Make into a wrapper around data_out_legacy.
+
+       * file-handle-def.c (struct file_handle): New member `encoding'.
+       (fh_create_file): Set encoding.
+       (fh_default_properties): Set default encoding.
+       (fh_get_legacy_encoding): New function.
+
+       * file-handle-def.h (enum fh_mode): New modes FH_MODE_FIXED
+       (that replaces FH_MODE_BINARY), FH_MODE_VARIABLE,
+       FH_MODE_360_VARIABLE, FH_MODE_360_SPANNED.
+       (struct fh_properties): New member `encoding'.
+
+2007-11-05  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6258.  Reviewed by John Darrington.
+
+       * file-handle-def.c (fh_lock): Add comment that TYPE should be
+       marked with N_() in the caller.  Added these markings to each
+       caller too.  Should make i18n easier.
+       Suggested by Chusslove Illich <caslav.ilic@gmx.net>.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * file-handle-def.c: Separate locking of files for input and for
+       output, to allow both to take place at once.  Also, distinguish a
+       file handle from the identity of the underlying file, because the
+       identity of a file changes over time and the file handle can't
+       represent two different identities.
+       (struct file_handle): Remove `next', `open_cnt', `deleted',
+       `type', `open_mode', `aux', `identity' members.  Change `id' from
+       char array to char *.  Add `ref_cnt' member.
+       (file_handle_from_ll) New function.
+       (file_handles) Removed.
+       (named_handles) New variable.
+       (fh_init) Initialize named_handles.
+       (fh_done) Remove name from all named_handles.
+       (free_handle) Updated for modified struct file_handle.
+       (unname_handle) New function.
+       (fh_ref) New function.
+       (fh_from_file_name) Removed.
+       (fh_unref) New function.
+       (fh_unname) New function.
+       (fh_from_id) Rewritten.
+       (create_handle) Updated for modified struct file_handle.
+       (fh_inline_file) Increment the handle's ref count.
+       (fh_create_file) Updated for modified struct file_handle.
+       (fh_create_scratch) Ditto.
+       (fh_free) Removed.
+       (mode_name) Removed.
+       (fh_open) Removed.
+       (fh_close) Removed.
+       (fh_is_open) Removed.
+       (fh_get_id) Updated for modified struct file_handle.
+       (fh_get_default_handle) Increment the handle's ref count.
+       (fh_set_default_handle) Handle ref counts.
+       (struct fh_lock) New structure.
+       (locks) New static var.
+       (fh_lock) New function.
+       (fh_unlock) New function.
+       (fh_lock_get_aux) New function.
+       (fh_lock_set_aux) New function.
+       (fh_is_locked) New function.
+       (make_key) New function.
+       (free_key) New function.
+       (compare_fh_locks) New function.
+       (hash_fh_lock) New function.
+
+       * file-handle-def.h (enum fh_access) New enum.
+
+       * file-name.c: Made file_identity the same in all supported
+       environments.
+       (struct file_identity): New `name' member.
+       (fn_get_identity): For a file that doesn't exist, get the
+       dev/inode of its directory plus its name.  If even the directory
+       doesn't exist, just use its name.  Merge the Windows
+       implementation into the Unix one.
+       (fn_compare_file_identities): Rewritten.  Merge the Windows
+       implementation into the Unix one.
+       (fn_hash_identity): New function.
+
+       * make-file.c (struct replace_file): New structure.
+       (all_files): New static var.
+       (replace_file_start): New function.
+       (replace_file_commit): New function.
+       (replace_file_abort): New function.
+       (free_replace_file): New function.
+       (unlink_replace_files): New function.
+
+       * por-file-reader.c (struct pfm_reader): Add `lock' member.
+       (close_reader): Unlock file.
+       (pfm_open_reader): Lock file.
+
+       * por-file-writer.c (struct pfm_writer): Add fh_lock, replace_file
+       members.
+       (pfm_open_writer): Lock file and prepare for its replacement.
+       (close_writer): Unlock file.
+
+       * scratch-handle.h (struct scratch_handle): Add unique_id so that
+       different generations of a scratch file can be distinguished.
+
+       * scratch-reader.c (scratch_reader_open): Verify that the file is
+       a scratch file.
+
+       * scratch-writer.c (struct scratch_writer): Add `lock' and `dict',
+       remove scratch_handle member.
+       (scratch_writer_open): Lock handle.  Prepare to replace handle
+       data, instead of doing it immediately.
+       (scratch_writer_casewriter_destroy): Replace handle data and
+       unlock handle.
+
+       * sys-file-reader.c (struct sfm_reader): Add `lock' member.
+       (sfm_open_reader): Lock file.
+       (close_reader): Unlock file.
+
+       * sys-file-writer.c (struct sfm_writer): Add fh_lock, replace_file
+       members.
+       (sfm_open_writer): Lock file and prepare for its replacement.
+       (close_writer): Unlock file.
+
+2007-11-02  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c (output_number): Use isfinite (from C99) instead of
+       gsl_isfinite, since we now have universal support for it in
+       gnulib.
+       (output_infinite): Ditto.
+       [!HAVE_ROUND] (round): Remove definition, since we now have a
+       replacement in gnulib.
+
+2007-10-27  John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c: Fixed bug in dict_clone, where the vardict.dict member
+       wasn't initialised correctly. Closes bugs #21330 and 21397
+
+
+2007-10-08  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #21280.  Thanks to John Darrington for review.
+
+       * file-name.c (create_stream): New function.
+
+       * por-file-writer.c (pfm_open_writer): Use fh_open to open the
+       file handle before creating the file, to ensure that we don't
+       truncate a file that we're reading.  Make code easier to read by
+       using create_stream.
+
+       * sys-file-write.c (sfm_open_writer): Ditto.
+
+2007-10-01  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #21192.  Thanks to John Darrington for review.
+
+       * casereader.c (casereader_read): Decrement case_cnt before
+       calling the casereader's "read" member function, so that we
+       interact properly with lazy_casereader.
+
+       * datasheet.c: Add regression test for above bug fix.
+       (clone_datasheet): New function.
+       (lazy_callback): New function.
+       (check_datasheet_casereader): New function.
+       (check_datasheet): Check datasheet contents are reported correctly
+       through an ordinary casereader and a lazy casereader.
+       (clone_model): Use clone_datasheet.
+
+2007-09-24  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6210.  Reviewed by John Darrington.
+       * settings.c: Drop "long view", which is not needed any longer.
+       (static var long_view): Removed.
+       (force_long_view): Removed.
+       (get_viewwidth): Removed.
+       (init_viewport): Removed long_view reference.
+
+2007-09-19  John Darrington <john@darrington.wattle.id.au>
+       
+       * settings.c settings.h: Changed viewport's length and width to be 
+       owned by the user interface which uses the data library.  This allows
+       better abstraction, and makes dynamically adjustable dimensions easier.
+       
+2007-09-18  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c (proc_extract_active_file_data): New function.
+
+       * lazy-casereader.h: New file.
+
+       * lazy-casereader.c: New file.
+
+       * casereader.c (casereader_dynamic_cast): New function.
+
+2007-09-14  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_clone): Copy case indexes from cloned
+       dictionary.  Fixes bug #21061.  Reviewed by John Darrington.
+
+2007-09-13  John Darrington <john@darrington.wattle.id.au>
+
+       * value.c value.h (create_value): New function.
+
+2007-09-12  Ben Pfaff  <blp@gnu.org>
+
+       Make it clear that translator casereader and casewriter translate
+       functions are supposed to destroy their input case.
+       
+       * casereader-translator.c (struct casereader_translator): Change
+       input case parameter of translate member function from const
+       struct ccase * to struct ccase *.
+       (casereader_create_translator): Ditto, for translate parameter.
+
+       * casewriter-translator.c (struct casewriter_translator): Ditto.
+       (casewriter_create_translator): Ditto.
+
+2007-08-27  John Darrington <john@darrington.wattle.id.au>
+       
+       * sys-file-reader.c (read_display_parameters): Force display width 
+       to 8, if the sys file says 0 (like SPSS does).
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_dump): New function.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       Drop dict_compactor in favor of using the new struct case_map.
+
+       * dictionary.c (struct copy_map): Removed.
+       (struct dict_compactor): Removed.
+       (dict_make_compactor): Removed.
+       (dict_compactor_compact): Removed.
+       (dict_compactor_destroy): Removed.
+
+       * procedure.c (struct data_set): Change `compactor' member to be a
+       struct case_map *.
+       (proc_open): Use case_map_to_compact_dict instead of
+       dict_make_compactor.
+       (proc_casereader_read): Use case_map_execute instead of
+       dict_compactor_compact.
+       (proc_commit): Use case_map_destroy instead of
+       dict_compactor_destroy.
+
+       * scratch-writer.c (struct scratch_writer): Change `compactor'
+       member to be a struct case_map *.
+       (scratch_writer_open): Use case_map_to_compact_dict instead of
+       dict_make_compactor.
+       (scratch_writer_casewriter_write): Use case_map_execute instead of
+       dict_compactor_compact.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add case-map.c, case-map.h.
+
+       * case-map.c: New file.
+
+       * case-map.h: New file.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_compact_values): Don't delete scratch
+       variables as well as compacting case indexes.  Update all callers.
+       (dict_get_compacted_value_cnt): Rename dict_count_values and
+       change interface.  Update all callers.
+       (dict_get_compacted_value_cnt): Remove.
+       (dict_compacting_would_shrink): Remove.
+       (dict_compacting_would_change): Remove.
+       (dict_make_compactor): Add new parameter.  Update all callers.
+       
+       * procedure.c (proc_casereader_read): Use casewriter_get_value_cnt
+       instead of dict_count_values, changing an O(N) operation into
+       O(1).
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * casereader.c (casereader_read): Don't require cases read by a
+       casereader to be exactly the expected size: as long as they're big
+       enough, it's OK.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       Make casewriters keep track of the number of `union value's in
+       each case.  This is useful for two reasons: casewriter_write can
+       then check that the case being written is large enough, and later
+       recipients of the casewriter can determine the size of the case.
+       
+       * casewriter-translator.c (casewriter_create_translator): Add
+       value_cnt parameter.
+       
+       * casewriter.c (struct casewriter): Add value_cnt member.
+       (casewriter_write): Check that the case passed in is big enough.
+       (casewriter_get_value_cnt): New function.
+       (casewriter_create): Add value_cnt parameter.
+
+2007-08-09  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug reported by Jason Stover.
+       * settings.c: Move get_termcap_viewport and in particular the
+       #include for <curses.h> to the end of the file.  curses.h
+       redefines bool on some systems (e.g. OpenBSD), which causes
+       disagreement between uses of bool before its inclusion and
+       afterward.
+       Tested by Jason Stover.
+
+2007-07-29  Ben Pfaff  <blp@gnu.org>
+
+       Provisional fix for bug #18692 and bug #20161.  Reviewed by John
+       Darrington.
+
+       * file-name.c (fn_open): Only pass "r" or "w" to popen as mode
+       argument (never "rb" or "wb") because SUSv3 says that only those
+       modes are defined, and glibc in fact rejects other modes.
+
+       Open portable files with fn_open so that they can be read from
+       pipes.  Fix missing fh_close call to go along with fh_open.
+       Report an error if the file close reports an error.
+       * por-file-reader.c (close_reader): New function.
+       (por_file_casereader_destroy): Use close_reader.
+       (pfm_open_reader): Open file with fn_open.
+
+2007-07-28  Ben Pfaff  <blp@gnu.org>
+
+       Make PSPP able to read all the portable files I could find on the
+       web.  Thanks to John Darrington for review.  Bug #17620.
+       * por-file-reader.c (struct pfm_reader): New member `line_length'.
+       (error): Print file offset in hexadecimal.
+       (warning): New function.
+       (advance): Treat lines less than 80 bytes long as padded to 80
+       bytes with spaces.
+       (pfm_open_reader): Call read_documents if we find an "E" record.
+       (convert_format): Convert invalid formats to the default format
+       instead of aborting reading the file.
+       (read_variables): Rename duplicate variable names instead of
+       aborting reading the file.
+       (read_value_label): Allow string variables of different widths to
+       be assigned value labels in the same record.  Replace duplicate
+       value labels instead of aborting.
+       (read_documents): New function.
+
+       * por-file-writer.c (pfm_open_writer): Call write_documents if the
+       dictionary has documents.
+       (write_documents): New function.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Fix bugs related to bug #17213.
+
+       * settings.c: Use HAVE_LIBNCURSES instead of HAVE_LIBTERMCAP,
+       since the former is what config.h has.  Include the needed ncurses
+       headers.
+       (static var echo) Rename to `do_echo' because the original name is
+       the same as an ncurses identifier.
+       (get_termcap_viewport) Use error instead of msg.
+
+       * file-name.c (fn_interp_vars): Fix interpolation of $VARS.
+       (fn_close): Don't close stdin, stdout, stderr.
+
+2007-07-26 John Darrington <john@darrington.wattle.id.au>
+
+       * procedure.c procedure.h: Added callbacks which get invoked whenever 
+       a dataset's transformation chain changes.
+
+2007-07-24  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #6113.
+       * sys-file-writer.c (write_variable_display_parameters): Use new
+       var_default_display_width function to choose display width of
+       segments after the first one in a given variable.
+       * variable.c (var_create): Use var_default_display_width to pick
+       new variable's display width.
+       (var_default_display_width): New function.
+       Reviewed by John Darrington.
+
+2007-07-24  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #20427.
+       * por-file-writer.c (write_variables): Write weight variable.
+       Reviewed by John Darrington.
+
+2007-07-23  Ben Pfaff  <blp@gnu.org>
+
+       Improvements to system file reader and writer.
+       
+        First, move all detailed knowledge of very long strings into
+       sys-file-private.[ch], so that this nasty stuff can be isolated.
+
+       * sys-file-private.c (REAL_VLS_CHUNK): New macro.
+       (EFFECTIVE_VLS_CHUNK): New macro.
+       (min_int): New function.
+       (max_int): New function.
+       (sfm_width_to_bytes): Rewrite.
+       (sfm_width_to_octs): New function.
+       (sfm_segment_alloc_width): New function.
+       (sfm_segment_alloc_bytes): New function.
+       (sfm_segment_used_bytes): New function.
+       (sfm_segment_offset): New function.
+       (sfm_segment_effective_offset): New function.
+       (sfm_dictionary_to_sfm_vars): New function.
+
+       * sys-file-private.h (MIN_VERY_LONG_STRING): Removed.
+       (EFFECTIVE_LONG_STRING_LENGTH): Removed.
+       (struct sfm_var): New structure.
+
+        Next, improvements to the system file reader.
+
+       * sys-file-reader.h (struct sfm_read_info): Changed `case_cnt' to
+       type casenumber.  Added `version_major', `version_minor',
+       `version_revision'.
+
+       * sys-file-reader.c (struct sfm_reader): Replaced `flt64_cnt' by
+       `oct_cnt'.  Rename `vars', `var_cnt' to `sfm_vars', `sfm_var_cnt'.
+       Change `case_cnt' to type casenumber.  Removed `has_vls'.
+       (struct sfm_var): Removed.
+       (sfm_open_reader): Don't warn on wrong case size if the file was
+       written by SPSS 13, which tends to get it wrong.  Use
+       sfm_dictionary_to_sfm_vars.
+       (read_header): Always output system file info.
+       (read_variable_record): Simplify code for reading missing values.
+       (read_machine_int32_info): Save version numbers from system file
+       into info struct passed as new argument.
+       (read_long_string_map): Restructured to use new sys-file-private
+       functions.
+       (read_value_labels): Use size_overflow_p.
+       (sys_file_casereader_read): Get rid of distinction between fast
+       and slow paths.  Use information provided by sys-file-primate's
+       struct sfm_var to simplify code.
+       (skip_whole_strings): New function.
+       (read_int32): Renamed read_int.  Changed return value to int.
+       Updated all callers.
+       (read_flt64): Renamed read_float.  Changed return value to
+       double.  Updated all callers.
+       (int32_to_native): Removed.  Changed callers to use
+       integer_convert.
+       (flt64_to_double): Removed.  Changed callers to use float_convert.
+       
+        Finally, get rid of int32, flt64 terminology and types in system
+       file writer.  The former wasn't very useful since a POSIX "int"
+       can hold the whole range of int32 and we generally didn't have a
+       need for it to be exactly-32-bits, just at-least-32-bits.  The
+       latter was inconvenient because we had to assume that it could be
+       different from double and thereby convert special values SYSMIS,
+       HIGHEST, LOWEST to and from it in multiple places.  Instead, now
+       we just use "int" and "double" in most places, and do conversions,
+       if necessary, very close to where we do I/O.  This change meant
+       that the writer code couldn't represent records in the file as C
+       structs any longer, but that's no great loss.  The code actually
+       seems to be more readable without them.
+
+       Simplify the compression buffering code: only buffer as much as
+       necessary, which is no more than eight 8-byte units at any given
+       time.
+
+       * sys-file-writer.c (typedef flt64): Removed.
+       (macro second_lowest_flt64): Removed.
+       (struct sysfile_header): Removed.
+       (struct sysfile_variable): Removed.
+       (struct sfm_writer): Removed `needs_translation', `has_vls',
+       `flt64_cnt'.  Changed `compress' to type bool and `case_cnt' to
+       type casenumber.  Renamed `vars' to `sfm_vars', `var_cnt' to
+       `sfm_var_cnt'.  Replaced `buf', `end', `ptr', `x', `y' for
+       compression buffering by `opcodes', `opcode_cnt', `data',
+       `data_cnt'.  Renamed `var_cnt_vls' as `segment_cnt'.
+       (sfm_open_writer): Use sfm_dictionary_to_sfm_vars.  Use simple
+       data writer functions instead of structures.
+       (calc_oct_idx): New function.
+       (write_header): Use simple data writer functions instead of
+       structures.
+       (write_format_spec): Renamed write_format.  New argument.
+       (write_variable_continuation_records): New function.
+       (write_variable): Use simple data writer functions instead of
+       structures.  Use write_variable_continuation_records.  Write
+       entire very long string instead of requiring caller to understand
+       them.
+       (write_value_labels): Use simple data writer functions instead of
+       structures.
+       (write_documents): Ditto.
+       (write_variable_display_parameters): Use sys-file-private
+       functions to simplify.  Use simple data writer functions instead
+       of structures.
+       (write_vls_length_table): Use simple data writer functions instead
+       of structures.
+       (write_longvar_table): Ditto.
+       (write_rec_7_34): Break into new functions
+       write_integer_info_record, write_float_info_record.  Use simple
+       data writer functions instead of structures.
+       (buf_write): Removed.
+       (append_string_max): Removed.
+       (ensure_buf_space): Removed.
+       (sys_file_casewriter_write): Get rid of the distinction between
+       fast and slow paths, which didn't seem to be too useful.  Use new
+       functions write_case_uncompressed, write_case_compressed.
+       (put_instruction): Removed.
+       (put_element): Removed.
+       (write_compressed_data): Removed.
+       (close_writer): Use flush_compressed.  Only write case count to
+       system file if it will fit in the field.
+       (write_case_compressed): New function.
+       (write_case_uncompressed): New function.
+       (flush_compressed): New function.
+       (put_cmp_opcode): New function.
+       (put_cmp_number): New function.
+       (write_int): New function.
+       (convert_double_to_output_format): New function.
+       (write_float): New function.
+       (write_value): New function.
+       (write_string): New function.
+       (write_bytes): New function.
+       (write_zeros): New function.
+       (write_spaces): New function.
+
+       Reviewed by John Darrington.
+
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       Don't try to write very long strings to portable files.  The
+       format does not support it.
+
+       * por-file-writer.c (MAX_POR_WIDTH): New macro.
+       (pfm_open_writer): Limit output width to MAX_POR_WIDTH.
+       (write_format): Add arg to take width to resize format to.
+       (write_value): Limit width of value written to MAX_POR_WIDTH.
+       (write_variables): Limit width of variable and its output formats
+       to MAX_POR_WIDTH.
+       Reviewed by John Darrington.
+
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-reader.c (read_variable_to_value_map): Use max_warnings
+       local variable instead of literal 5.
+       Reviewed by John Darrington.
+       
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       Fix problems with uniqueness of short names in system files with
+       very long string variables.  Now a variable may have multiple
+       short names.
+       
+       * automake.mk (src_data_libdata_a_SOURCES): Add new files
+       short-names.c, short-names.h.
+
+       * dictionary.c (dict_clone): Clone all the short names.
+       (compare_strings): Move into short-names.c.
+       (hash_strings): Ditto.
+       (set_var_short_name_suffix): Ditto.
+       (dict_assign_short_names): Ditto, rename short_names_assign,
+       change to assign all short names.
+       
+       * por-file-writer.c (write_variables): Use short_names_assign
+       instead of dict_assign_short_names.
+
+       * short-names.c: New file.
+
+       * short-names.h: New file.
+
+       * sys-file-private.c (sfm_width_to_segments): New function.
+
+       * sys-file-reader.c (read_long_var_name_map): Save and restore all
+       the short names, not just the first one.
+       
+       * sys-file-writer.c (cont_var_name): Removed.
+       (sfm_open_writer): Use short_names_assign instead of
+       dict_assign_short_names.  Use unique short names assigned by
+       short_names_assign instead of those generated by cont_var_name.
+
+       * variable.c (struct variable): Remove `short_name' member,
+       replace by `short_names' and `short_name_cnt'.
+       (var_create) Initialize new members.
+       (var_get_short_name_cnt): New function.
+       (var_get_short_name): Now takes an index argument.  Changed most
+       callers to pass 0.
+       (var_set_short_name): Ditto.
+       (var_clear_short_name): Renamed var_clear_short_names, changed to
+       clear all short names.
+       
+       Reviewed by John Darrington.
+
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       * variable.c (var_set_width): Use new var_set_width function.
+
+       * missing-values.c (mv_n_values): Drop assertion, which was not
+       needed.
+
+       * format.c (fmt_default_for_width): New function.
+       (fmt_resize): New function.
+
+       Reviewed by John Darrington.
+
+2007-07-18 John Darrington <john@darrington.wattle.id.au>
+
+       * datasheet.c (datasheet_delete_columns): Added assertion to check
+       we're not deleting outside the range of the sheet.  
+
+       
+       * dictionary.c dictionary.h variable.c: Added the ability for string
+       variables to be resized.
+       
+       * vardict.h: Added some prototypes (moved from dictionary.h) as
+       these should only be called by variable.c
+
+
+2007-07-14 John Darrington <john@darrington.wattle.id.au>
+
+       * sfm-reader.c: Respect case_cnt field in file header.
+
+2007-07-01 John Darrington <john@darrington.wattle.id.au>
+
+       * transformation.c transformation.h (trns_chain_execute): Changed the 
+       signature (Patch #6057)
+
+2007-06-10  Ben Pfaff  <blp@gnu.org>
+
+       * casereader-filter.c (casereader_filter_destroy): Make sure to
+       write all the remaining excluded cases to the casewriter, if any.
+
+       * caseinit.c (init_list_destroy): Rewrite.
+       (init_list_clear): Ditto.
+
+       * casegrouper.c (casegrouper_get_next_group): Always set *reader
+       to null when returning false.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Actually implement the new procedure code and adapt all of its
+       clients to match.  Also adapt all of the other case sources and
+       sinks in the tree and their clients to use the
+       casereader/casewriter infrastructure.
+
+       * automake.mk: Add and remove files.
+
+       * any-reader.c: Change into a casereader.
+       * por-file-reader.c: Ditto.
+       * scratch-reader.c: Ditto.
+       * sys-file-reader.c: Ditto.
+
+       * any-writer.c: Change into a casewriter.
+       * por-file-writer.c: Ditto.
+       * scratch-writer.c: Ditto.
+       * sys-file-writer.c: Ditto.
+
+       * procedure.c: Change to use casereader, casewriter, caseinit, and
+       other new infrastructure.
+
+       * scratch-handle.c: Adapt to new infrastructure.
+
+       * case-sink.c: Removed, now dead code.
+       * case-sink.h: Ditto.
+       * case-source.c: Ditto.
+       * case-source.h: Ditto.
+       * casefile-factory.c: Ditto.
+       * casefile-private.h: Ditto.
+       * casefile.c: Ditto.
+       * casefile.h: Ditto.
+       * casefilter.c: Ditto.
+       * casefilter.h: Ditto.
+       * fastfile.c: Ditto.
+       * fastfile.h: Ditto.
+       * fastfile-factory.c: Ditto.
+       * fastfile-factory.h: Ditto.
+       * storage-stream.c: Ditto.
+       * storage-stream.h: Ditto.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Add datasheet code.
+
+       * automake.mk: Add new files.
+
+       * datasheet.c: New file.
+
+       * datasheet.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Until now, the procedure code has provided a case to the
+       case_source, which has filled in the data values that come from
+       the active file.  "Left" data values that don't come from the
+       active file naturally stay the same from case to case, because the
+       procedure code keeps using that same case.
+
+       One of the compromises that comes with the new procedure code is
+       that the active file allocates and provides its own case, which
+       the procedure code then has to resize to provide room for any
+       other variables that should go in the case and then fill in the
+       values of "left" variables.  Then, when we're done with that case,
+       we have to save the values of "left" variables to copy into the
+       next case read from the active file.
+
+       The caseinit code helps with this.
+
+       * automake.mk: Add new files.
+
+       * caseinit.c: New file. 
+
+       * caseinit.h: New file. 
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * value.h (value_cnt_from_width): New function.
+
+       * variable.c (var_get_value_cnt): Use new function.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Add casegrouper, to allow cases read from a given casereader to be
+       broken into groups, each of which has its own casereader.
+       Generally cases are grouped based on having equal values for some
+       set of variables.
+
+       * automake.mk: Add new files.
+
+       * casegrouper.c: New file.
+
+       * casegrouper.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Add interface to lexicographical ordering of cases.
+
+       * automake.mk: Add new files.
+
+       * case-ordering.c: New file.
+
+       * case-ordering.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Add casereaders and casewriters, the basis of the new data processing
+       implementation.  A casereader is a uniform interface to reading cases
+       from a data source; a casewriter is a uniform interface to writing
+       cases to a data sink.
+
+       * automake.mk: Add new files.
+       
+       * casereader-filter.c: New file.
+       
+       * casereader-provider.h: New file.
+
+       * casereader-translator.c: New file.
+       
+       * casereader.c: New file.
+       
+       * casereader.h: New file.
+       
+       * casewriter-provider.h: New file.
+       
+       * casewriter-translator.c: New file.
+       
+       * casewriter.c: New file.
+       
+       * casewriter.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       "casewindow" data structure that extends the deque (from libpspp)
+       of cases with the ability to dump cases to disk if we get too many
+       of them in memory.
+
+       * automake.mk: Add new files.
+
+       * casewindow.c: New file.
+
+       * casewindow.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       sparse_cases data structure that augments a sparse_array of cases
+       with the ability to dump cases to disk if we get too many cases in
+       memory.
+
+       * automake.mk: Add new files.
+
+       * sparse-cases.c: New file.
+
+       * sparse-cases.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adds a low-level on-disk case array data structure.
+       
+       * automake.mk: Add new files.
+
+       * case-tmpfile.c: New file.
+
+       * case-tmpfile.h: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       In a couple of places we calculate the maximum number of cases to
+       keep in memory based on the user-defined workspace.  Enable
+       centralizing the calculation through a new function.
+       
+       * settings.c (get_workspace_cases): New function.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       The casenumber type is defined in transformations.h, but case.h is
+       a more sensible place.  Move it.
+
+       * case.h (CASENUMBER_MAX): New macro.
+       (typedef casenumber): Move here, from transformations.h.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       Slightly generalize case_to_values and case_from_values functions.
+
+       * case.c (case_to_values): Rename case_copy_out, change interface.
+       (case_from_values): Rename case_copy_in, change interface.
+
+       * fastfile.c (fastfilereader_get_next_case): Update caller.
+       (write_case_to_disk): Ditto.
+
+2007-06-02  Ben Pfaff  <blp@gnu.org>
+
+       Clean up after a forgotten part of patch #5829.
+       
+       * casedeque.h: Remove unused file.
+
+       * automake.mk: Remove casedeque.h from sources.
+
+2007-05-10  Jason Stover  <jhs@math.gcsu.edu>
+
+       * category.c: Removed redundant #include
+
+2007-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Abstract the documents within a dictionary a little better.
+       Thanks to John Darrington for suggestion, initial version, and
+       review.  Patch #5917.
+
+       * dictionary.c (struct dictionary): Change `documents' member from
+       char * to struct string.
+       (dict_clear): Destroy struct string.
+       (dict_get_documents): Convert struct string to char *.
+       (dict_set_documents): Set struct string.  Pad to 80-character
+       multiple.
+       (dict_clear_documents): New function.
+       (dict_add_document_line): New function.
+       (dict_get_document_line_cnt): New function.
+       (dict_get_document_line): New function.
+
+       * dictionary.h (macro DOC_LINE_LENGTH): New macro.
+
+       * sys-file-reader.c (read_documents): Use new document functions.
+
+2007-04-19 John Darrington <john@darrington.wattle.id.au>
+
+       * sys-file-reader.c: When reading a system file which has no 
+       long name table, automatically create one where the long names 
+       are the lower case versions of the short names.
+       
+2007-04-22  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_set_split_vars): dict_destroy expects that
+       dict_clear will free most data related to the dictionary.
+       dict_clear does a decent job, except that dict_set_split_vars on
+       some systems won't actually free the dict's "split" member.
+       Instead, it'll allocate a 1-byte region.  Fix this.
+
+       * value.c (value_copy): New function.
+       (value_set_missing): Ditto.
+
+2007-04-22 John Darrington <john@darrington.wattle.id.au>
+
+       * Deleted existing category.h and moved cat-routines.h into 
+       category.h  Encapsulated struct cat_vals better.
+
+2007-04-19 John Darrington <john@darrington.wattle.id.au>
+
+       * sys-file-reader.c: When reading a system file which has no 
+       long name table, automatically create one where the long names 
+       are the lower case versions of the short names.
+       
+2007-04-16 John Darrington <john@darrington.wattle.id.au>
+
+       * sys-file-reader.c: Some versions of Other Software seem to 
+        produce system files with string  variables' measure set to 
+       zero.  We'll assume these are supposed to be nominal variables.
+
+2007-03-30  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c: Adapt to new deque data structure.
+
+Mon Feb 19 10:53:21 2007  John McCabe-Dansted <gmatht@gmail.com>
+                         Ben Pfaff <blp@gnu.org>
+
+       * file-name.c: Mingw compatibility fixes.
+       (fn_search_path): Use ISSLASH instead of comparing against '/'
+       directly.
+       (fn_dir_name): Use dir_name from gnulib.
+       (fn_is_absolute): Use IS_ABSOLUTE_FILE_NAME from gnulib.
+       (fn_get_identity): Use GetFullPathName instead of canonicalize
+       from gnulib, because the latter does not fully support
+       Windows-style path names.  Use this implementation based on the
+       detected presence of Windows instead of the absence of Unix, since
+       the new implementation is Windows-specific.
+       (fn_compare_file_identities): In Windows implementation, compare
+       names case-insensitively.
+
+Sun Feb 18 13:28:02 2007  Ben Pfaff  <blp@gnu.org>
+
+       * make-file.c: Don't include mkstemp.h, because gnulib now causes
+       <stdlib.h> to have the same effect.
+
+Sun Feb 18 11:20:24 2007  Ben Pfaff  <blp@gnu.org>
+
+       * por-file-reader.c: Add missing _() around messages.
+
+Sun Feb 11 20:44:13 2007  Ben Pfaff  <blp@gnu.org>
+
+       * make-file.c: Include "mkstemp.h", without which linking on
+       mingw32 fails.
+
+Thu Feb  8 14:59:05 2007  Ben Pfaff  <blp@gnu.org>
+       Reduce platform dependence.
+       * file-name.c (fn_tilde_expand): Removed, and removed calls to it.
+       Everywhere we using this, we really should have just depended on
+       the shell to expand tildes.
+       (fn_search_path): Simplify, given that we don't do tilde expansion
+       any longer.
+       (fn_normalize): Removed.  Caller changed to use the canonicalize
+       module from gnulib.
+       (fn_get_cwd): Removed.  Only user was fn_normalize.
+       (fn_is_absolute): Really only test for absolute names.
+       (fn_is_special): Use pipe files if HAVE_POPEN, not if we're in
+       unix.
+       (fn_readlink): Removed, as it was only used fn_normalize.
+       (fn_exists): Assume the stat function is available; gnulib does.
+       (fn_open): Use pipe files if HAVE_POPEN, not if we're in unix.
+Sat Feb  3 21:52:17 2007  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_create_vector_assert): New function.
+
+Wed Feb  7 21:25:15 2007  Ben Pfaff  <blp@gnu.org>
+
+       * file-name.c (fn_normalize): Correct name of function
+       fn_is_special.  Thanks to John McCabe-Dansted <gmatht@gmail.com>
+       for pointing this out.
+
+Thu Feb  1 16:53:37 2007  Ben Pfaff  <blp@gnu.org>
+
+       We are using a single member in struct file_handle, the "name"
+       field, for more than one purpose.  When it begins with '"', it's a
+       file name; otherwise, it's a token that can be used to identify
+       it.  When that assertion fires, it's because we searched for the
+       name case-sensitively as a file name (so that there was no match),
+       and then we try to insert it case-insensitively as a token, which
+       fails because duplicates aren't allowed.
+
+       Solution: break the two purposes into two separate fields.  This
+       fixes the problem and likely makes the code easier to read too.
+
+       Fixes bug #18922.  Thanks to John Darrington for bug report and
+       review.
+
+       * file-handle-def.c (struct file_handle): New `id' member.
+       (fh_from_name): Rename fh_from_id.  Update all callers.
+       (create_handle): New `id' parameter.  Update all callers.
+       (fh_create_file): Ditto.
+       (fh_get_id): New function.
+
+Mon Jan 15 16:18:10 2007  Ben Pfaff  <blp@gnu.org>
+
+       * case.c (case_is_null): Change return type to bool.
+
+Mon Jan 15 10:57:28 2007  Ben Pfaff  <blp@gnu.org>
+
+       Add debugging code.
+       
+       * case.c (case_clone) [DEBUGGING]: When debugging, don't use
+       reference counting to share data.  This makes it easy for
+       valgrind, etc. to find accesses to cases that have been destroyed
+       but have been kept around by another user's ref-count.  This often
+       happens when the data set is small enough to find in memory; if a
+       bigger data set that would overflow to disk were used, then data
+       corruption would occur.
+
+Mon Jan 15 10:55:18 2007  Ben Pfaff  <blp@gnu.org>
+
+       Simplify code.
+
+       * case.c (case_unshare): Make it check internally whether the
+       ref_cnt is greater than 1, so that the callers don't have to.
+       Update callers not to check.
+
+Mon Jan 15 10:53:01 2007  Ben Pfaff  <blp@gnu.org>
+
+       Before, I was thinking that I might want to get rid of reference
+       counting at some point.  Now, I'm pretty sure that it's here to
+       stay.  Thus, because we have to store the value_cnt anyway for
+       reference-counted cases, we might as well expose it to users.
+
+       * case.c (case_get_value_cnt): New function.
+       (case_resize): Drop OLD_CNT argument.  Update all callers.  Only
+       resize case if its size actually changed.
+
+       * casefile.c (casefile_append_xfer): Use case_get_value_cnt
+       instead of peeking inside struct case directly.
+       (casefile_append): Ditto.
+
+Mon Jan 15 10:50:22 2007  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of the inlines for the case functions, which made the
+       header file hard to read.  (Also, in testing with "-O2 -DNDEBUG",
+       the inlines didn't speed up "make check" at all, which is not a
+       perfect benchmark but seems indicative.)
+       
+       * case.c: Remove #ifdef DEBUGGING...#endif around many function
+       definitions.  Remove some assertions on nonnull pointers that were
+       redundant with a pointer dereference soon after in the function.
+       Also:
+       (struct case_data): Move definition here from case.h.
+       (case_data): Ditto.
+       (case_num): Ditto.
+       (case_str): Ditto.
+       (case_data_wr): Ditto.
+       
+Sun Jan 14 21:41:12 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add casedeque.h to sources.
+       
+       * casedeque.h: New file.
+
+       * procedure.c: (struct dataset) Change lag_count, lag_head,
+       lag_queue member into single struct casedeque member.  Update all
+       users to use the casedeque instead.
+       (lag_case) Removed.
+
+Sun Jan 14 21:43:12 2007  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c: Simplify lagged cases interface.  Updated all
+       clients--well, the only client--to use the simplified interface.
+       (dataset_n_lag) Removed.
+       (dataset_set_n_lag) Removed.
+       (dataset_need_lag) New function.
+
+Tue Jan  9 07:20:05 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c procedure.c: More changes to ensure that callbacks occur
+       whenever appropriate, but only when the dataset/dictionary is in a 
+       consistent state.
+
+Sun Jan  7 08:33:04 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c dictionary.h : Added callbacks for change of filter and 
+       split variables.  Refactored some code to ensure that callbacks get
+       invoked when appropriate.
+
+       * procedure.c (proc_cancel_temporary_transformations): Make sure that 
+       replace_dict callback occurs when permanent_dict replaces the current
+       dictionary.
+
+Wed Jan  3 11:02:11 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c dictionary.h : Added callback for when the weight 
+       variable of a dictionary changes.
+
+Mon Jan  1 10:36:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c dictionary.h : Added replace_source and replace_dict
+       callbacks, and functions to deal with them.
+
+Fri Dec 22 13:56:08 2006  Ben Pfaff  <blp@gnu.org>
+
+       Simplify missing value handling.
+
+       * missing-values.h (enum mv_class): New type.
+       (enum mv_type): Moved definition into missing-values.c and renamed
+       each MV_* to MVT_*, to distinguish them from the exposed mv_class
+       enums.  Updated all uses.
+       (struct missing_values): Changed type of `type' from `enum
+       mv_type' to `int' because the definition is no longer exposed.
+       
+       * missing-values.c (mv_is_value_missing): Add new enum mv_class
+       parameter.  Update all callers.
+       (mv_is_num_missing): Ditto.
+       (mv_is_str_missing): Ditto.
+       (mv_is_value_user_missing): Removed.  Changed callers to use
+       mv_is_value_missing.
+       (mv_is_num_user_missing): Removed.  Changed callers to use
+       mv_is_num_missing.
+       (mv_is_str_user_missing): Removed.  Changed callers to use
+       mv_is_str_missing.
+       (mv_is_value_system_missing): Removed.  Changed callers to use
+       mv_is_value_missing.
+       (mv_set_type): Removed.  Changed callers to use mv_clear.
+       (mv_clear): New function.
+       
+       * variable.c (var_is_value_missing): Add new enum mv_class
+       parameter.  Update all callers.
+       (var_is_num_missing): Ditto.
+       (var_is_str_missing): Ditto.
+       (var_is_value_user_missing): Removed.  Changed callers to use
+       var_is_value_missing.
+       (var_is_num_user_missing): Removed.  Changed callers to use
+       var_is_num_missing.
+       (var_is_str_user_missing): Removed.  Changed callers to use
+       var_is_str_missing.
+       (var_is_value_system_missing): Removed.  Changed callers to use
+       var_is_value_missing.
+       
+       * casefilter.c (struct casefilter): Use enum mv_class in place of
+       bool.
+       (casefilter_variable_missing): Adapt to new member.
+       (casefilter_create): Change signature to take enum mv_class,
+       update callers.
+
+Fri Dec 22 20:08:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile-factory.h fastfile-factory.c fastfile-factory.h: New files.
+
+       * case-sink.c case-sink.h procedure.c procedure.h 
+          storage-stream.c: Now uses the factory.
+       
+Sat Dec 16 22:05:18 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make it possible to pull cases from the active file with a
+       function call, instead of requiring indirection through a callback
+       function.
+
+       * case-source.h (struct case_source_class): Change ->read function
+       to return a single case, instead of calling a callback function
+       for each case.  Change ->destroy function to return an error
+       status.
+
+       * case-source.c (free_case_source): Pass along the value returned
+       by the case_source ->destroy function.
+
+       * procedure.c (struct write_case_data): Removed.
+       (struct dataset): Added some members to track procedure state.
+       (procedure): Optimize the trivial case at this level.
+       (internal_procedure): Re-implement in terms of proc_open,
+       proc_read, proc_close.
+       (proc_open) New function.
+       (proc_read) New function.
+       (proc_close) New function.
+       (write_case) Moved into proc_read.
+       (close_active_file) Moved closing of data source into proc_close.
+
+       * storage-source.c: Rewrote to conform with modified
+       case_source_class interface.
+
+       * transformations.c (trns_chain_execute): Added argument to allow
+       starting execution from an arbitrary transformation.  Updated
+       callers.
+
+       * transformations.h (enum TRNS_NEXT_CASE) Renamed TRNS_END_CASE.
+
+Sat Dec 16 14:09:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-reader.c (read_display_parameters): Don't assume that
+       MEASURE_* and ALIGN_* have the same values found in system files.
+
+       * sys-file-writer.c (write_variable_display_parameters): Ditto.
+
+       * variable.h: Change MEASURE_NOMINAL, MEASURE_ORDINAL,
+       MEASURE_SCALE to be 0-based instead of 1-based.  This also fixes
+       the value of n_MEASURES, which was off by 1 (at least from my
+       point of view).
+
+Sat Dec 16 12:17:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * dictionary.c dictionary.h vardict.h variable.c: Added optional
+               callbacks which are invoked when the dictionary or its 
+               variables are changed.  
+       
+       * missing-values.c missing-values.h value-labels.c: Tidied up
+               consistency checks, and made some of them return false 
+               instead of assert-failing. 
+
+Wed Dec 13 19:30:11 2006  Ben Pfaff  <blp@gnu.org>
+
+       * calendar.c (calendar_days_in_month): New function.
+
+Mon Dec 11 07:53:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c (hash_int_val_lab): Only hash as many bytes as
+       the value label's width.
+
+Sun Dec 10 14:21:29 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sfm-private.h: Move contents into sys-file-writer.c, which is
+       the only remaining user.  Removed Borland C++-specific directives.
+       
+       * sys-file-reader.c: Clean up and rewrite entire file.  The
+       rewritten version is simpler and better abstracted, and should be
+       easier to maintain and extend.  It avoids using structures to read
+       file data, which is prone to padding variations among compilers.
+       It should also handle non-IEEE 754 system files, although I
+       haven't been able to find any.  It has been tested against many
+       .sav files obtained from the Web and found to produce the same
+       results as the earlier version of the code, or in some cases
+       improved results.  It is more tolerant of format variations found
+       in the wild.
+
+       * sys-file-reader.h (struct sfm_read_info): Removed `big_endian'
+       member, putting an enum integer_format in its place.  New member
+       `float_format'.  Changed `compressed' member to type bool.
+
+Sun Dec 10 13:48:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       * dictionary.c (dict_delete_consecutive_vars): New function.
+
+Sat Dec  9 20:08:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * file-name.c (fn_search_path): Remove prefix arg that was unused
+       by any caller.  Updated all callers.
+
+Sat Dec  9 20:04:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c (fmt_dollar_template): Use user's decimal point
+       character.  Add assertion.
+
+Sat Dec  9 20:02:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c (fmt_dollar_template): New function, based on
+       dollar_format_template from var-type-dialog.c.
+
+Sat Dec  9 18:05:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c (output_scientific): Fix bad assumption that "buf" is
+       null-terminated.
+       
+Sat Dec  9 17:23:23 2006  Ben Pfaff  <blp@gnu.org>
+
+       Finish converting struct variable to an opaque type.  In this
+       phase, we add remaining setter and getter functions, convert the
+       remaining PSPP code to use them, and do a bunch of cleanup.  The
+       resulting changes are pervasive but mostly trivial, and only the
+       notable changes are logged.
+       
+       * automake.mk (src_data_libdata_a_SOURCES): Add the new source
+       files.
+       
+       * case.c (case_data): Renamed case_data_idx.
+       (case_num): Renamed case_num_idx.
+       (case_str): Renamed case_str_idx.
+       (case_data_rw): Renamed case_data_rw_idx.
+
+       * case.h (case_data): New function with old name and an interface
+       that takes a variable instead of an index, which is easier to
+       use.  Updated all callers to use the new interface, or to use the
+       new *_idx function (see above).
+       (case_num): Ditto.
+       (case_str): Ditto.
+       (case_data_rw): Ditto.
+       
+       * category.c (cat_stored_values_destroy): Changed interface to
+       take a struct cat_vals * instead of a struct variable *.
+
+       * dictionary.c (dict_clone): Use new vector_clone function.     
+       (dict_clear) Use new var_destroy function.
+       (add_var) New function.
+       (dict_create_var) Rewrite in terms of dict_create_var_assert.
+       (dict_create_var_assert) Rewrite in terms of add_var.
+       (dict_clone_var) Rewrite in terms of dict_clone_var_assert.
+       (dict_clone_var_assert) Rewrite in terms of var_clone, add_var.
+       (dict_lookup_var) Use new var_create, var_destroy functions.
+       (dict_contains_var) Rewrite in terms of new vardict functionality.
+       (set_var_dict_index) New function.
+       (set_var_case_index) New function.
+       (reindex_vars) New function.
+       (dict_delete_var) Rewrite in terms of new vardict functionality.
+       (dict_reorder_var) Ditto.
+       (dict_reorder_vars) Ditto.
+       (rename_var) New function.
+       (dict_rename_var) Use rename_var.
+       (dict_rename_vars) Use pool to simplify code.  Use rename_var.
+       (dict_get_compacted_idx_to_fv) Rename
+       dict_get_compacted_dict_index_to_case_index, update callers.
+       (dict_create_vector) Use new vector_create function.
+       (dict_clear_vectors) Use new vector_destroy function.
+       (set_var_short_name_suffix) Move here from variable.c, renamed
+       from var_set_short_name_suffix, make static, update caller.
+
+       * sys-file-private.c: New file.  
+       (sfm_width_to_bytes) Moved here from variable.c, renamed from
+       width_to_bytes, update callers.
+
+       * sys-file-private.h: New file.  Later it will supplant
+       sfm-private.h; for now it supplements it.
+       (macro MIN_VERY_LONG_STRING) New macro.
+       (macro EFFECTIVE_LONG_STRING_LENGTH) New macro, from value.h.
+
+       * sys-file-reader.c: Use MIN_VERY_LONG_STRING - 1 where
+       MAX_LONG_STRING was used before.
+
+       * sys-file-writer.c: Ditto.
+
+       * value-labels.c: Change the paradigm here to be that a null
+       pointer is OK for a struct val_labs * in most cases; it just
+       represents an empty set of value labels.
+       (val_labs_copy) A copy of a null set is a null set.
+       (val_labs_count) A null set has 0 labels.
+       (val_labs_replace) Change return type to void.  Rewrite for
+       simplicity.
+       (val_labs_find) A null set does not contain the value.
+       (value_to_string) Moved to variable.c, renamed var_get_value_name,
+       transposed argument order, updated all callers.
+
+       * value.c: New file.
+       (value_dup) Moved here from variable.c.
+       (compare_values) Ditto.
+       (hash_value) Ditto.
+
+       * value.h: (macro MAX_SHORT_STRING) Rewrote for simplicity.
+       (macro MAX_LONG_STRING) Removed, because it was only interesting
+       for system files, not for general code.
+       (macro MAX_VERY_LONG_STRING) Ditto.
+       (macro EFFECTIVE_LONG_STRING_LENGTH) Moved to sys-file-private.h.
+       (macro MAX_ELEMS_PER_VALUE) Removed, as it was unused.
+
+       * vardict.h: New file, for an interface between variables and
+       their dictionaries.
+
+       * variable.c: A lot of functions were moved around, for better
+       organization.
+       (struct variable) Move definition here, from variable.h.
+       (var_type_adj) Removed--makes i18n hard.
+       (var_type_noun) Ditto.
+       (var_create) New function.
+       (var_clone) New function.
+       (var_destroy) New function.
+       (var_set_name) Assert that variable is not in a dictionary.
+       (compare_var_names) Rename compare_vars_by_name and fix a couple
+       of callers who thought the args were strings.
+       (hash_var_name) Rename hash_var_by_name.
+       (compare_var_ptr_names) Rename compare_var_ptrs_by_name.
+       (hash_var_ptr_name) Rename hash_var_ptr_by_name.
+       (var_is_very_long_string) Removed, because it was only interesting
+       to system file code.
+       (var_set_missing_values) Allow the argument to be the wrong width,
+       as long as we can resize it.  Simplify callers who were doing the
+       resizing themselves.
+       (var_get_value_labels) New function.
+       (var_has_value_labels) New function.
+       (var_set_value_labels) New function.
+       (alloc_value_labels) New function.
+       (var_add_value_label) New function.
+       (var_replace_value_label) New function.
+       (var_clear_value_labels) New function.
+       (var_lookup_value_label) New function.
+       (var_get_value_name) Moved here from variable.c, renamed from
+       var_get_value_name, transposed argument order, updated all
+       callers.
+       (var_to_string) Moved here, from variable-label.c.
+       (var_set_leave) New function.
+       (var_get_leave) New function.
+       (var_must_leave) New function.
+       (var_set_short_name_suffix) Moved to dictionary.c, renamed
+       set_var_short_name_suffix.
+       (var_get_dict_index) New function.
+       (var_get_case_index) New function.
+       (var_get_obs_vals) New function.
+       (var_set_obs_vals) New function.
+       (var_has_obs_vals) New function.
+       (var_get_vardict) New function.
+       (var_set_vardict) New function.
+       (var_has_vardict) New function.
+       (var_clear_vardict) New function.
+       (value_dup) Moved to value.c.
+       (compare_values) Ditto.
+       (hash_value) Ditto.
+
+       * variable.h: (enum NUMERIC) Rename VAR_NUMERIC, update all users.
+       (enum ALPHA) Rename VAR_STRING, update all users.
+
+       * vector.c: New file.
+       (struct vector) Moved here, from variable.h.
+       (check_widths) New function.
+       (vector_create) New function.
+       (vector_clone) New function.
+       (vector_destroy) New function.
+       (vector_get_name) New function.
+       (vector_get_var) New function.
+       (vector_get_var_cnt) New function.
+       (compare_vector_ptrs_by_name) New function.
+
+       * vector.h: New file.
+
+Sun Dec 10 11:32:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefilter.c (casefilter_variable_missing): Avoided comparision of
+       string variables to SYSMIS.  Thanks to Ben Pfaff for reporting this
+       problem.
+
+Sat Dec  9 07:18:03 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * value-labels.c (destroy_atoms): New function.
+       * value-labels.c (atom_create): Call destroy_atoms in atexit handler.
+
+Thu Dec  7 17:38:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Thanks to Jason Stover for pointing out this problem.
+       
+       * data-out.c (output_number): Use gsl_finite from GSL, which is
+       portable, instead of isfinite, which is not.
+       (power256) Ditto.
+
+Thu Dec  7 15:22:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * variable.c variable.h (value_dup): New function.
+
+Mon Dec  4 22:20:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start converting struct variable to an opaque type.  In this
+       phase, we add a bunch of setter and getter functions and convert
+       most of the PSPP code to use them.  The resulting changes are
+       pervasive but mostly trivial, and only the notable changes are
+       logged.
+       
+       * format.c (fmt_equal): New function.
+       
+       * variable.c (var_type_is_valid): New function.
+       (measure_is_valid) Moved here, from format.c.
+       (alignment_is_valid) Moved here, from format.c.
+       (var_get_name) New function.
+       (var_set_name) New function.
+       (width_to_type) New function.
+       (var_get_type) New function.
+       (var_get_width) New function.
+       (var_set_width) New function.
+       (var_is_numeric) New function.
+       (var_is_alpha) New function.
+       (var_is_short_string) New function.
+       (var_is_long_string) New function.
+       (var_is_very_long_string) New function.
+       (var_get_missing_values) New function.
+       (var_set_missing_values) New function.
+       (var_clear_missing_values) New function.
+       (var_has_missing_values) New function.
+       (var_is_value_missing) New function.
+       (var_is_num_missing) New function.
+       (var_is_str_missing) New function.
+       (var_is_value_user_missing) New function.
+       (var_is_num_user_missing) New function.
+       (var_is_str_user_missing) New function.
+       (var_is_value_system_missing) New function.
+       (var_get_print_format) New function.
+       (var_set_print_format) New function.
+       (var_get_write_format) New function.
+       (var_set_write_format) New function.
+       (var_set_both_formats) New function.
+       (var_get_label) New function.
+       (var_set_label) New function.
+       (var_clear_label) New function.
+       (var_has_label) New function.
+       (var_get_measure) New function.
+       (var_set_measure) New function.
+       (var_get_display_width) New function.
+       (var_set_display_width) New function.
+       (var_get_alignment) New function.
+       (var_set_alignment) New function.
+       (var_get_value_cnt) New function.
+       (var_get_leave) New function.
+       (var_get_short_name) New function.
+
+       * variable.h: (struct variable) Removed "type" and "nv" members;
+       they are now computed from "width" where needed.
+
+Mon Dec  4 21:38:40 2006  Ben Pfaff  <blp@gnu.org>
+
+       * missing-values.c (mv_resize): Don't write beyond end of the
+       allocated buffer when resizing a long string.
+
+Sat Dec  2 16:28:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       Clean up identifier code: don't require identifier enumerations to
+       be in a particular order; make better use of string library;
+       expose less of the internals.
+               
+       * identifier.c: (lex_skip_identifier) Rename lex_id_get_length,
+       change interface.  Updated all callers.
+       (lex_id_match) Change interface to use struct substring, update
+       all callers.
+       (lex_id_match_len) Removed.  Update callers to use lex_id_match.
+       (global array keywords[]) Make static, change form.  Update all
+       users to use lex_id_name instead.
+       (lex_is_keyword) New function.
+       (lex_id_to_token) Change interface to use struct substring, update
+       all callers.
+       (lex_id_name) New function.
+
+       * identifier.h: (T_FIRST_KEYWORD) Removed.  Changed users to call
+       lex_is_keyword instead.
+       (T_LAST_KEYWORD) Removed.
+       (T_N_KEYWORDS) Removed.
+       
+Sat Nov 18 20:46:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (fmt_date_template) Distinguish characters for which a
+       space is output and any date delimiter is allowed on input, from
+       those for which a space is output and only a space is allowed on
+       input.  The former is represented by X, the latter by a space.
+       Also, drop distinction between h and H, changing the former to the
+       latter.
+
+       * data-in.c: Completely rewrite internals to conform to SPSS input
+       formats as closely as possible.
+       (data_in) Changed external interface by replacing the structure
+       that was used as a single argument by a set of arguments.  Updated
+       all callers.
+       (data_in_finite_line) Removed.  Converted all callers to use plain
+       data_in.
+       (data_in_get_integer_format) New function.
+       (data_in_set_integer_format) New function.
+       (data_in_get_float_format) New function.
+       (data_in_set_float_format) New function.
+
+       * data-in.h: (enums DI_IGNORE_ERROR, DI_IMPLIED_DECIMALS) Removed.
+       (struct data_in) Removed.
+
+       * data-out.c: (output_date) Drop each component from the input as
+       it is output, to allow us to drop the distinction between h (a
+       count of hours) and H (the hour of day) template characters.
+       Also, handle new X template character.
+       (output_scientific) Follow more rational rule on when to drop
+       fraction introduced between SPSS 13 and 15.  Updated test case to
+       match new behavior.
+
+Sat Nov 11 11:41:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix buffer overflow reported by John Darrington.
+
+       * data-out.c (output_bcd_integer): In case of SYSMIS, etc.,
+       realize that DIGITS is a count of nibbles, not of bytes.
+
+Sat Nov  4 15:59:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * calendar.c (calendar_offset_to_gregorian) Also return the
+       year-of-day.  Change callers to new interface.
+
+       * data-out.c: Completely rewrite internals to conform to SPSS
+       output formats as completely as possible.
+       (data_out) Change interface to put input parameters before output
+       parameters, for consistency with the style I now prefer.  Update
+       all callers.
+       (data_out_get_integer_format) New public function.
+       (data_out_set_integer_format) New public function.
+       (data_out_get_float_format) New public function.
+       (data_out_set_float_format) New public function.
+
+       * data-out.h: New file.  Move prototype for data_out here, from
+       format.h.
+
+       * format.c: (fmt_step_width) Use equality comparison instead of
+       bitwise and, for clarity.
+       (fmt_is_string) Ditto.
+       (fmt_input_to_output) Fix categories that are translated to F
+       format.
+
+Sun Nov  5 08:29:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefilter.c casefilter.h (new files), casefile.c casefile.h 
+       casefile-private.h: Added casefilter to assist commands with missing 
+       values.
+
+Sat Nov  4 11:47:09 2006  Ben Pfaff  <blp@gnu.org>
+
+       Implement SET ERRORS, SHOW ERRORS.  Fixes bug #17609.
+       
+       * settings.c: (route_errors_to_terminal) New variable.
+       (route_errors_to_listing) New variable. 
+       (get_error_routing_to_terminal) New function.
+       (set_error_routing_to_terminal) New function.
+       (get_error_routing_to_listing) New function.
+       (set_error_routing_to_listing) New function.
+
+       * settings.h: (SET_ROUTE_* enums) Removed, because unused.
+
+Tue Oct 31 19:58:27 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: Completely rewrite, to achieve better abstraction.
+       Rewrite all references to formats in other files.
+       
+       * format.def: Rewrite and reorganize.
+
+       * settings.c: Move everything related to custom currency formats
+       into format.[ch], changing them in form, so as to group related
+       code and definitions better.  Changed all references to use the
+       new functions.
+       (static var decimal) Removed.
+       (static var grouping) Removed.
+       (static var cc) Removed.
+       (get_decimal) Removed.
+       (set_decimal) Removed.
+       (get_grouping) Removed.
+       (set_grouping) Removed.
+       (get_cc) Removed.
+       (set_cc) Removed.
+
+       * settings.h: (macro CC_CNT) Removed.
+       (macro CC_WIDTH) Removed.
+       (struct custom_currency) Removed.
+
+Tue Oct 31 19:56:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c (data_in): Use switch statement instead of table, to
+       avoid dependence on the order of the FMT_* enums.
+
+Tue Oct 31 19:35:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-out.c: (num_to_string) Removed, because it was dead code.
+
+Tue Oct 31 18:09:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-in.c (parse_trailer): Fix error message.
+
+Sat Oct 28 11:56:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c (fmt_is_binary): New function.
+
+Thu Oct 19 22:59:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * procedure.c procedure.h: Encapsulated the static data into a single
+       struct.  
+
+Sat Oct 14 16:56:44 2006  Ben Pfaff  <blp@gnu.org>
+
+       * casefile.c (casereader_read_xfer): Always initialize the case,
+       even on an error condition.
+
+Wed Sep 27 09:37:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * procedure.c (case_limit_trns_proc): Fixed buglet which rendered the 
+       entire function useless.
+
+Mon Sep 25 17:11:46 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile-private.h casefile.c casefile.h fastfile.c: Created new
+       casereader method casereader_clone.   
+       
+       * procedure.c pransformations.h: Introduced new type casenum_t
+
+Thu Sep 21 07:00:30 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.c: (width_to_bytes) Rephrase code for clarify.
+
+Sun Jul 16 19:52:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c: (fmt_type_from_string) New function.
+       (fmt_to_string) Include decimals in output if the format has
+       decimals, even if the format type does not.  This way, we can
+       accurately reproduce incorrect formats in user output.
+       (check_common_specifier) Make the check for a bad format type an
+       assertion, so we get bug reports if they show up.  Fix message.
+       Check for decimal places with a format type that doesn't allow
+       them.
+       (check_input_specifier) Remove check for FMT_X, which has been
+       deleted.
+       (check_output_specifier) Ditto. 
+
+       * format.def: Remove FMT_T, FMT_X, FMT_DESCEND, FMT_NEWREC.
+
+       * format.h: (macro FMT_TYPE_LEN_MAX) New macro.
+       (struct fmt_desc) Use FMT_TYPE_LEN_MAX in definition.
+       (enum fmt_parse_flags) Removed.
+
+Mon Jul 17 18:26:21 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c casefile.h: Converted to  an abstract base class.
+       * casefile-private.h fastfile.c fastfile.h: New files.
+       * automake.mk procedure.c scratch-writer.c storage-stream.c
+
+Wed Jul 12 21:02:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c (internal_procedure): Create sink_case with only as
+       many values as the compacted dictionary.
+
+Wed Jul 12 21:01:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove "debugging" code that caused plenty of false positives and
+       no true positives.
+       
+       * case.h (struct ccase): [DEBUGGING] Remove `this' member.
+
+       * case.c: Remove all references to `this' member.
+
+Thu Jul  6 19:09:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix link error noted by Jason Stover.
+       
+       * storage-stream.c: Include <assert.h>.
+
+Tue Jul  4 08:47:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
+       ALL) and additional underlying system file issues.
+
+       Thanks to John Darrington for review.
+
+       First problem: var_hash points to variables not owned by the
+       sys-file-reader, which the caller may free or modify.  Use an
+       array of sfm_vars instead, as done earlier (e.g. CVS version
+       1.12).
+       
+       * sys-file-reader.c (struct sfm_reader): Remove var_hash, svars
+       members and remove all code that references it.  Add vars, var_cnt
+       members.  Remove fix_specials member, which was unused.
+       (struct sfm_var) Remove name member, which was unused.
+       (sfm_close_reader) Free vars member instead of var_hash.
+       (compare_var_shortnames) Removed.
+       (hash_var_shortname) Removed.
+       (sfm_open_reader) Fill out vars array.
+       (compare_var_index) Removed.
+       (sfm_read_case) Use vars instead of var_hash.
+       
+       Second problem: we're confused about when we actually have very
+       long strings, causing us to choose incorrectly between slow path
+       and fast path in sfm_read_case.
+
+       * sys-file-reader.c: (sfm_open_reader) Only mark has_vls if we
+       have very long strings, not when we have long variable names,
+       which is an unrelated feature.
+
+Tue Jun 27 12:06:49 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.h: Move var_set and variable parsing declarations to
+       new header, src/language/lexer/variable-parser.h.  Modified lots
+       of files to include the new header.
+
+Sun Jun 25 22:39:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c (value_to_string): When there's no value label,
+       format the variable according to its print format, instead of
+       always effectively using A or F format.
+
+Mon Jun 19 18:05:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * casefile.c (casefile_get_random_reader): Nasty hack to get around 
+       the mode assertion.
+
+       * format.c: Removed tortological assertion.
+
+Fri Jun  9 12:20:09 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * file-name.c (fn_interp_vars): Change interface to take a
+       substring as input.  Updated all users.
+       
+Fri Jun  9 12:11:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format.c (measure_is_valid): Really return false when m >=
+       n_MEASURES.
+
+Tue Jun  6 18:46:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Implement random access to casefiles, for use in GUI.
+       
+       * casefile.c: (struct casereader) Add `random', `file_ofs',
+       `buffer_ofs' members.
+       (casefile_get_random_reader) New function.
+       (read_open_file) Break part into new function
+       seek_and_fill_buffer().
+       (fill_buffer) Update buffer_ofs, file_ofs.
+       (casereader_seek) New function.
+
+Tue May 30 19:52:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * settings.c: Added call to i18n{done, init}.
+
+Tue May  9 21:09:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.h: Add WARN_UNUSED_RESULT to procedure function
+       prototypes.
+
+Tue May  9 21:08:05 2006  Ben Pfaff  <blp@gnu.org>
+
+       * casefile.c: Convert many uses of `int' to `bool'.
+
+Sat May  6 22:49:43 2006  Ben Pfaff  <blp@gnu.org>
+
+       * transformations.c (trns_chain_destroy): Destroy chain's trns
+       member, to fix memory leak.
+
+Sat May  6 22:48:30 2006  Ben Pfaff  <blp@gnu.org>
+
+       * storage-stream.c (storage_source_decapsulate): Destroy case
+       source to fix memory leak.
+
+Sat May  6 22:46:47 2006  Ben Pfaff  <blp@gnu.org>
+
+       * scratch-reader.c (scratch_reader_read_case): Copy into existing
+       case passed as argument instead of initializing the argument as a
+       case.  Fixes memory leak that showed up in
+       tests/command/aggregate.sh with scratch files.
+
+Sat May  6 22:45:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       * procedure.c (proc_done): Destroy default_dict, to fix memory
+       leak.
+
+Sat May  6 22:44:44 2006  Ben Pfaff  <blp@gnu.org>
+
+       Simplify procedure_with_splits().
+       
+       * procedure.c (struct split_aux_data): Removed case_count member.
+       (procedure_with_splits) Don't initialize case_count.
+       (split_procedure_case_func) Check whether prev_case is null
+       instead of case_count.
+       (split_procedure_end_func) Ditto.
+
+Sat May  6 22:42:23 2006  Ben Pfaff  <blp@gnu.org>
+
+       * case.c (case_move): Do nothing if dst and src are the same
+       object.
+       (case_try_create) Merge two similar cases.
+       (case_copy) Unshare only if data must be actually copied.
+
+Sun May  7 10:04:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-in.c data-out.c dictionary.c sys-file-reader.c
+       sys-file-writer.c variable.c variable.h:  Reworked very long string
+       support for better encapsulation.
+
+Sat May  6 19:02:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c (val_labs_can_set_width): New function.
+       (val_labs_set_width) Clear labels if increasing width to long
+       string.
+       (val_labs_destroy) Remove unneeded test for null.
+       
+Sat May  6 16:14:08 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.h: Remove unneeded dependency on variable.h.
+
+Sat May  6 15:58:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of `char *c' member in union value, for cleanliness.
+       
+       * value.h: (union value) Remove `c' member.
+
+Sat May  6 15:36:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make dictionary compacting functions a little more general.
+       
+       * sys-file-writer.c (sfm_open_writer): Use
+       dict_compacting_would_change().
+       (does_dict_need_translation) Removed.
+
+Sat May  6 15:35:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make dictionary compacting functions a little more general.
+       
+       * dictionary.c (dict_needs_compaction): Rename
+       dict_compacting_would_shrink().  Update all callers.
+       (dict_compacting_would_change) New function.
+       
+Sat May  6 14:25:49 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-writer.c: (does_dict_need_translation) Fix bug:
+       inverted return value (!).
+
+Sat May  6 13:37:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  
+
+       * procedure.c: Search and replace "vfm" by "proc".  Notably:
+       (static var vfm_source) Rename proc_source.  Update all
+       references.
+       (static var vfm_sink) Rename proc_sink.  Update all references.
+       
+Sat May  6 12:38:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, remove
+       PROCESS IF, which was deprecated anyway and can be easily
+       simulated with TEMPORARY followed by SELECT IF.
+
+       * procedure.c: (open_active_file) Don't call
+       add_process_if_trns().
+       (discard_variables) Get rid of redundant call to
+       proc_cancel_all_transformations().
+       (add_process_if_trns) Removed.
+       (process_if_trns_proc) Removed.
+       (process_if_trns_free) Removed.
+
+Sat May  6 10:58:05 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, add
+       `const' to the case passed to procedure()'s callback.
+
+       Updated all users of procedure() as well.
+       
+       * procedure.c: (struct write_case_data) Add "const" to ccase
+       parameter for case_func member.
+       (procedure) Add "const" to ccase parameter for proc_func
+       parameter.
+       (multipass_case_func) Make ccase parameter const.
+       (internal_procedure) Add "const" to ccase parameter for case_func
+       parameter.
+       (split_procedure_case_func) Make ccase parameter const.
+       (multipass_split_case_func) Make ccase parameter const.
+       
+Sat May  6 10:30:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       the output code for SPLIT FILE groups in procedure.c, which really
+       shouldn't be doing any output.  Move it into the individual
+       procedures instead.  This also adds some flexibility.
+
+       Updated many users of procedure_with_splits() and
+       multipass_procedure_with_splits() to call
+       output_split_file_values() and to deal with increased use of
+       const.
+
+       * procedure.c: (struct split_aux_data) Add "const struct ccase *"
+       parameter to begin_func member.
+       (procedure_with_splits) Add "const struct ccase *" parameter to
+       begin_func parameter.  Make ccase parameter const in proc_func
+       parameter.
+       (split_procedure_case_func) Don't dump split file group.  Pass
+       case to begin_func.
+       (dump_splits) Moved to language/dictionary/split-file.c as
+       output_split_file_values().
+       (struct multipass_split_aux_data) Add "const struct ccase *"
+       parameter to split_func member.
+       (multipass_procedure_with_splits) Add "const struct ccase *"
+       parameter to split_func parameter.
+       (multipass_split_case_func) Save new SPLIT FILE case before
+       outputting case.
+       (multipass_split_output) Pass saved SPLIT FILE case to split_func.
+       
+Fri May  5 22:48:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  Change
+       internal_procedure() so that it calls open_active_file() and
+       close_active_file(), which isolates most of the actual procedure
+       functionality.
+
+       * procedure.c: (struct write_case_data) Rename `proc_func' member
+       to `case_func' and update all references.
+       (procedure) Rewrite as one-line wrapper around
+       internal_procedure().
+       (struct multipass_aux_data) New.
+       (multipass_callback) Renamed multipass_case_func().  Use struct
+       multipass_aux_data as auxiliary data.
+       (multipass_end_func) New function.
+       (multipass_procedure) Rewrite as wrapper for internal_procedure()
+       that uses multipass_case_func, multipass_end_func.
+       (internal_procedure) Add `end_func' argument.  Move optimization
+       of trivial case in here.  Move call to open_active_file() and
+       close_active_file() in here.  Now assert that vfm_source is
+       non-null.
+       (procedure_with_splits_callback) Rename
+       split_procedure_case_func().
+       (split_procedure_end_func) New function.
+       (multipass_split_callback) Rename multipass_split_case_func.
+       (multipass_split_end_func) New function.
+       (discard_variables) No need to test for nonnull vfm_source.
+
+Fri May  5 21:34:02 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  Get rid of unused member.
+
+       * procedure.c: (struct write_case_data) Remove `cases_analyzed'
+       member.
+       (write_case) Don't increment cases_analyzed.
+
+Thu May  4 21:50:11 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, move
+       procedure.c and procedure.h from src to src/data.  Update
+       makefiles and #includes accordingly.
+
+       * procedure.c: Moved here from src/.
+
+       * procedure.h: Moved here from src/.
+
+Wed May  3 22:42:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * automake.mk: (src_data_libdata_a_SOURCES) Add transformations.c,
+       transformations.h.
+
+       * dictionary.c: (global variable default_dict) Move to
+       src/procedure.c.
+
+       * variable.h: (TRNS_*) Move to transformations.h.
+       (struct transformation) Move to transformations.c.
+
+Thu May  4 13:47:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * sys-file-reader.c: Fixed invalid read problems.
+
+Tue May  2 15:57:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       * storage-stream.c: Add missing function comments.
+
+Tue May  2 15:50:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, add some
+       new, needed functionality to storage-stream.
+
+       * storage-stream.c: (storage_source_decapsulate) New function.
+
+Tue May  2 15:43:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.c (width_to_bytes): Declarations must precede
+       statements for C90 compliance.
+
+Tue May  2 10:42:05 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-out.c, data-in.c, variable.c, variable.h: New functions 
+       copy_mangle and copy_demangle for reading/writing cases; emulates the 
+       way SPSS deals with strings > 255 bytes.
+
+       * sys-file-reader.c sys-file-writer.c: Added support for Record 7, 
+       subtype 14 needed for strings longer than 255 bytes.
+
+       * dictionary.c, format.def, value.c : Updated to use MAX_STRING 
+        instead of literal values. Also fixed some constness issues.
+
+       * format.h: Constness
+
+       * sfm-private.h: Renamed the case_size identifier, since I discovered 
+        that SPSS's respect for this variable is very nominal.
+
+Mon May  1 15:45:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       Change case limit type from int to size_t.
+
+       * dictionary.c: (struct dictionary) Change type of case_limit
+       member.
+       (dict_get_case_limit) Change return type.
+       (dict_set_case_limit) Change parameter type.
+
+Wed Apr 26 20:01:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.h: (struct variable) Rename `reinit' member as `leave'
+       and invert sense.  Fix up all references.
+
+Wed Apr 26 19:39:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, break
+       procedure.c into multiple files.
+       
+       * automake.mk: (src_data_libdata_a_SOURCES) Add all the new files.
+
+       * case-sink.c: New file.
+
+       * case-sink.h: New file.
+       
+       * case-source.c: New file.
+
+       * case-source.h: New file.
+       
+       * storage-stream.c: New file.
+
+       * storage-stream.h: New file.
+
+Wed Apr 26 14:55:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.h: (struct variable) Remove `init' member and all
+       references to it from other files.  It was initialized in several
+       places, but nothing really ever used it for anything worthwhile.
+       Thanks to Jason Stover for pointing out how confusing this
+       member is.
+
+Sun Apr 23 22:04:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+       
+       * casefile.c: (io_error) Use err_msg() instead of err_vmsg().
+       Format message ourselves.
+
+       * data-in.c: (vdls_error) Ditto.
+
+       * por-file-reader.c: (error) Ditto.
+
+       * sys-file-reader.c: (corrupt_msg) Ditto.
+
+Sun Apr 16 18:49:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       GNU standards require "file name" instead of "filename" in
+       documentation.  It's nice for our code to follow the convention
+       too.
+       
+       * casefile.c: (struct casefile) Rename `filename' member to
+       `file_name'.  Updated all references.
+
+       * file-name.c: [!unix] (struct file_identity) Rename
+       normalized_filename member to normalized_file_name.  Updated all
+       references.
+
+Sun Apr 16 18:35:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       We don't really support anything but Unix-like environments well,
+       so we might as well de-obfuscate by writing directory and path
+       separators explicitly.
+
+       * file-name.h: (macro DIR_SEPARATOR) Removed.  Changed all usages
+       to just '/'.
+       (macro PATH_SEPARATOR) Removed.  Changed all usages to just ':'.
+       (macro DIR_SEPARATOR_STRING) Removed.  Changed all usages to just
+       "/".
+       (macro PATH_SEPARATOR_STRING) Removed.  Changed all usages to just
+       ":"
+
+Sun Apr 16 18:28:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       GNU standards require "file name" instead of "filename" in
+       documentation.  It's nice for our code to follow the convention
+       too.
+       
+       * filename.c: Rename to file-name.c.
+
+       * filename.h: Rename to file-name.h.  Update all inclusions.
+       Update header guards.
+
+       * automake.mk: Update file names.
+
+Sun Apr 16 16:42:47 2006  Ben Pfaff  <blp@gnu.org>
+
+       * filename.c: (fn_dirname) Renamed fn_dir_name(), all references
+       updated.
+       (fn_basename) Removed (dead code).
+       (fn_absolute_p) Renamed fn_is_absolute(), all references updated.
+       (fn_special_p) Renamed fn_is_special(), all references updated.
+       (fn_exists_p) Renamed fn_exists(), all references updated.
+
+Sun Apr 16 16:33:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * filename.c: (fn_tilde_expand) Rewrite for cleaner code.  
+       Also, now it only tilde-expands file names, not paths.
+       (fn_search_path) Tilde-expand one directory at a time.
+
+Sun Apr 16 16:28:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * filename.c: (fn_search_path) rewrite for cleaner code.  Also,
+       get rid of non-Unixlike version of the code, which has probably
+       never been tested.
+       (fn_prepend_dir) Removed (dead code).
+
+       * filename.h: (macro DIR_SEPARATOR_STRING) New.
+       (macro PATH_SEPARATOR_STRING) New.
+Sun Apr 16 16:05:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we get
+       rid of VM() and the other msg() support for "verbosity", replacing
+       it by a new function verbose_msg().
+
+       * filename.c: (fn_search_path) Use verbose_msg() instead of
+       msg(VM(), ...).  
+
+Sat Apr 15 19:53:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sfm-private.h: Get rid of #defines after #error, which makes no
+       sense.
+
+Sat Apr 15 19:48:57 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of our own int32 type in favor of the standard int32_t
+       type.
+       
+       * sfm-private.h: (int32 macro) Don't define this anymore.  Do
+       include <stdint.h>.
+
+       * sys-file-reader.c: Use int32_t instead of int32 throughout.
+       
+       * sys-file-writer.c: Use int32_t instead of int32 throughout.
+
+Sat Apr 15 19:36:47 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove ill-considered file routines that are no longer used.
+       
+       * filename.c: (fn_open_ext) Removed.
+       (fn_close_ext) Removed.
+
+       * filename.h: (struct file_ext) Removed.
+
+Mon Apr  3 13:22:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable.c (var_is_valid_name): Move declarations before code
+       for C90 compliance.
+
+Tue Apr  4 15:28:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * filename.ch (fn_interp_vars): Fixed small buglet.
+
+Tue Mar 28 13:47:16 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * filename.[ch] (fn_interp_vars): Changed the signature and semantics
+       so as to modify the string inline.   Thus makeing it easier to
+       destroy the results when no longer needed.
+       
+2006-03-25  Jason Stover  <jhs@math.gcsu.edu>
+
+       * category.c (cat_stored_values_destroy): Fixed memory leak.
+
+Fri Mar 24 18:15:41 2006  Ben Pfaff  <blp@gnu.org>
+
+       Add some missing frees.  Thanks to John Darrington for reporting
+       these.
+
+       * any-writer.c (any_writer_close): Free writer.
+
+       * any-reader.c (any_reader_close): Free reader.
+
+Mon Mar 20 16:33:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       * por-file-reader.c: (error) Mark as NO_RETURN.
+
+Sat Mar 11 15:06:07 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * settings.c: Changed default value of scompress to true.
+
+Sat Mar  4 13:22:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sfm-private.h: Include variable.h, to get SHORT_NAME_LEN.
+
+       * value.h: Remove check on MAX_SHORT_STRING, which I don't think
+       really applies.
+
+       * variable.h: Move definition of SHORT_NAME_LEN, LONG_NAME_LEN
+       here from pref.h.orig.
+
+Sat Mar  4 12:50:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * sys-file-reader.c: Fixed bug reading compressed files.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * Numerous renames.  See src/ChangeLog for details.
+       
+       * Moved files from src directory
diff --git a/src/data/attributes.c b/src/data/attributes.c
new file mode 100644 (file)
index 0000000..aa12829
--- /dev/null
@@ -0,0 +1,298 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <data/attributes.h>
+#include <assert.h>
+#include <string.h>
+#include <libpspp/array.h>
+#include <libpspp/hash-functions.h>
+#include "xalloc.h"
+
+/* A custom attribute of the sort maintained by the DATAFILE
+   ATTRIBUTE and VARIABLE ATTRIBUTE commands.
+
+   Attributes have a name (the rules for which are the same as
+   those for PSPP variable names) and one or more values, each of
+   which is a string.  An attribute may be part of one attribute
+   set. */
+struct attribute
+  {
+    struct hmap_node node;      /* Used by attrset. */
+    char *name;                 /* Name. */
+    char **values;              /* Each value. */
+    size_t n_values;            /* Number of values. */
+    size_t allocated_values;    /* Amount of allocated space for values. */
+  };
+
+/* Creates and returns a new attribute with the given NAME.  The
+   attribute initially has no values.  (Attributes with no values
+   cannot be saved to system files, so at least one value should
+   be added before the attribute is made available to the PSPP
+   user.) */
+struct attribute *
+attribute_create (const char *name)
+{
+  struct attribute *attr = xmalloc (sizeof *attr);
+  attr->name = xstrdup (name);
+  attr->values = NULL;
+  attr->n_values = 0;
+  attr->allocated_values = 0;
+  return attr;
+}
+
+/* Creates and returns a new attribute with the same name and
+   values as ORIG. */
+struct attribute *
+attribute_clone (const struct attribute *orig)
+{
+  struct attribute *attr;
+  size_t i;
+
+  attr = attribute_create (orig->name);
+  for (i = 0; i < orig->n_values; i++)
+    attribute_add_value (attr, orig->values[i]);
+  return attr;
+}
+
+/* Destroys ATTR and frees all associated memory.
+
+   This function must not be called if ATTR is part of an
+   attribute set.  Use attrset_delete() instead. */
+void
+attribute_destroy (struct attribute *attr)
+{
+  if (attr != NULL)
+    {
+      size_t i;
+
+      for (i = 0; i < attr->n_values; i++)
+        free (attr->values[i]);
+      free (attr->values);
+      free (attr->name);
+      free (attr);
+    }
+}
+
+/* Returns the name of ATTR.  The caller must not free or modify
+   the returned string. */
+const char *
+attribute_get_name (const struct attribute *attr)
+{
+  return attr->name;
+}
+
+/* Returns ATTR's value with the given INDEX, or a null pointer
+   if INDEX is greater than or equal to the number of values in
+   ATTR (that is, attributes are numbered starting from 0).  The
+   caller must not free or modify the returned string.  */
+const char *
+attribute_get_value (const struct attribute *attr, size_t index)
+{
+  return index < attr->n_values ? attr->values[index] : NULL;
+}
+
+/* Returns ATTR's number of values. */
+size_t
+attribute_get_n_values (const struct attribute *attrs)
+{
+  return attrs->n_values;
+}
+
+/* Adds a copy of VALUE as a new value to ATTR.  The caller
+   retains ownership of VALUE. */
+void
+attribute_add_value (struct attribute *attr, const char *value)
+{
+  if (attr->n_values >= attr->allocated_values)
+    attr->values = x2nrealloc (attr->values, &attr->allocated_values,
+                               sizeof *attr->values);
+  attr->values[attr->n_values++] = xstrdup (value);
+}
+
+/* Adds or replaces the value with the given INDEX in ATTR by a
+   copy of VALUE.  The caller retains ownership of VALUE.
+
+   If INDEX is an existing value index, that value is replaced.
+   If no value index numbered INDEX exists in ATTR, then it is
+   added, and any values intermediate between the last maximum
+   index and INDEX are set to the empty string. */
+void
+attribute_set_value (struct attribute *attr, size_t index, const char *value)
+{
+  if (index < attr->n_values)
+    {
+      /* Replace existing value. */
+      free (attr->values[index]);
+      attr->values[index] = xstrdup (value);
+    }
+  else
+    {
+      /* Add new value. */
+      while (index > attr->n_values)
+        attribute_add_value (attr, "");
+      attribute_add_value (attr, value);
+    }
+
+}
+
+/* Deletes the value with the given INDEX from ATTR.  Any values
+   with higher-numbered indexes are shifted down into the gap
+   that this creates.
+
+   If INDEX is greater than the maximum index, this has no effect.*/
+void
+attribute_del_value (struct attribute *attr, size_t index)
+{
+  if (index < attr->n_values)
+    {
+      free (attr->values[index]);
+      remove_element (attr->values, attr->n_values, sizeof *attr->values,
+                      index);
+      attr->n_values--;
+    }
+}
+\f
+/* Initializes SET as a new, initially empty attibute set. */
+void
+attrset_init (struct attrset *set)
+{
+  hmap_init (&set->map);
+}
+
+/* Initializes NEW_SET as a new attribute set whose contents are
+   initially the same as that of OLD_SET. */
+void
+attrset_clone (struct attrset *new_set, const struct attrset *old_set)
+{
+  struct attribute *old_attr;
+
+  attrset_init (new_set);
+  HMAP_FOR_EACH (old_attr, struct attribute, node, &old_set->map)
+    {
+      struct attribute *new_attr = attribute_clone (old_attr);
+      hmap_insert (&new_set->map, &new_attr->node,
+                   hmap_node_hash (&old_attr->node));
+    }
+}
+
+/* Frees the storage associated with SET, if SET is nonnull.
+   (Does not free SET itself.) */
+void
+attrset_destroy (struct attrset *set)
+{
+  if (set != NULL)
+    {
+      struct attribute *attr, *next;
+
+      HMAP_FOR_EACH_SAFE (attr, next, struct attribute, node, &set->map)
+        attribute_destroy (attr);
+      hmap_destroy (&set->map);
+    }
+}
+
+/* Returns the number of attributes in SET. */
+size_t
+attrset_count (const struct attrset *set)
+{
+  return hmap_count (&set->map);
+}
+
+/* Returns the attribute in SET whose name matches NAME
+   case-insensitively, or a null pointer if SET does not contain
+   an attribute with that name. */
+struct attribute *
+attrset_lookup (struct attrset *set, const char *name)
+{
+  struct attribute *attr;
+  HMAP_FOR_EACH_WITH_HASH (attr, struct attribute, node,
+                           hsh_hash_case_string (name), &set->map)
+    if (!strcasecmp (attribute_get_name (attr), name))
+      break;
+  return attr;
+}
+
+/* Adds ATTR to SET, which must not already contain an attribute
+   with the same name (matched case insensitively).  Ownership of
+   ATTR is transferred to SET. */
+void
+attrset_add (struct attrset *set, struct attribute *attr)
+{
+  const char *name = attribute_get_name (attr);
+  assert (attrset_lookup (set, name) == NULL);
+  hmap_insert (&set->map, &attr->node, hsh_hash_case_string (name));
+}
+
+/* Deletes any attribute from SET that matches NAME
+   (case-insensitively). */
+void
+attrset_delete (struct attrset *set, const char *name)
+{
+  struct attribute *attr = attrset_lookup (set, name);
+  if (attr != NULL)
+    {
+      hmap_delete (&set->map, &attr->node);
+      attribute_destroy (attr);
+    }
+}
+
+/* Deletes all attributes from SET. */
+void
+attrset_clear (struct attrset *set)
+{
+  attrset_destroy (set);
+  attrset_init (set);
+}
+
+static struct attribute *iterator_data (struct attrset_iterator *iterator)
+{
+  return HMAP_NULLABLE_DATA (iterator->node, struct attribute, node);
+}
+
+/* Returns the first attribute in SET and initializes ITERATOR.
+   If SET is empty, returns a null pointer.
+
+   The caller must not destroy the returned attribute, but it may
+   add or remove values.
+
+   Attributes are visited in no particular order.  Calling
+   attrset_add() during iteration can cause some attributes to
+   be visited more than once and others not at all. */
+struct attribute *
+attrset_first (const struct attrset *set, struct attrset_iterator *iterator)
+{
+  iterator->node = hmap_first (&set->map);
+  return iterator_data (iterator);
+}
+
+/* Returns the next attribute in SET and advances ITERATOR, which
+   should have been initialized by calling attrset_first().  If
+   all the attributes in SET have already been visited, returns a
+   null pointer.
+
+   The caller must not destroy the returned attribute, but it may
+   add or remove values.
+
+   Attributes are visited in no particular order.  Calling
+   attrset_add() during iteration can cause some attributes to
+   be visited more than once and others not at all. */
+struct attribute *
+attrset_next (const struct attrset *set, struct attrset_iterator *iterator)
+{
+  iterator->node = hmap_next (&set->map, iterator->node);
+  return iterator_data (iterator);
+}
diff --git a/src/data/attributes.h b/src/data/attributes.h
new file mode 100644 (file)
index 0000000..87cb772
--- /dev/null
@@ -0,0 +1,70 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DATA_ATTRIBUTES_H
+#define DATA_ATTRIBUTES_H 1
+
+#include <libpspp/hmapx.h>
+
+/* This header supports custom attribute of the sort maintained
+   by the DATAFILE ATTRIBUTE and VARIABLE ATTRIBUTE commands.
+
+   Attributes have a name (the rules for which are the same as
+   those for PSPP variable names) and one or more values, each of
+   which is a string.  An attribute may be part of one attribute
+   set.
+
+   An attribute set is an unordered collection of attributes
+   with names that are unique (case-insensitively). */
+
+struct attribute *attribute_create (const char *name);
+struct attribute *attribute_clone (const struct attribute *);
+void attribute_destroy (struct attribute *);
+
+const char *attribute_get_name (const struct attribute *);
+const char *attribute_get_value (const struct attribute *, size_t index);
+void attribute_add_value (struct attribute *, const char *);
+void attribute_set_value (struct attribute *, size_t index, const char *);
+void attribute_del_value (struct attribute *, size_t index);
+size_t attribute_get_n_values (const struct attribute *);
+
+struct attrset 
+  {
+    struct hmap map;
+  };
+
+void attrset_init (struct attrset *);
+void attrset_clone (struct attrset *, const struct attrset *);
+void attrset_destroy (struct attrset *);
+
+size_t attrset_count (const struct attrset *);
+
+struct attribute *attrset_lookup (struct attrset *, const char *);
+void attrset_add (struct attrset *, struct attribute *);
+void attrset_delete (struct attrset *, const char *);
+void attrset_clear (struct attrset *);
+
+struct attrset_iterator
+  {
+    struct hmap_node *node;
+  };
+struct attribute *attrset_first (const struct attrset *,
+                                 struct attrset_iterator *);
+struct attribute *attrset_next (const struct attrset *,
+                                struct attrset_iterator *);
+
+
+#endif /* data/attributes.h */
index 064d668b2d9a9f23d984c5ea75cd893e6e09f691..bd161dba469147a3c2c7cfa029e99fded534c17d 100644 (file)
@@ -1,14 +1,17 @@
 
-noinst_LIBRARIES += src/data/libdata.a
+noinst_LTLIBRARIES += src/data/libdata.la
 
-src_data_libdata_a_CPPFLAGS = $(LIBXML2_CFLAGS) $(PG_CFLAGS) $(AM_CPPFLAGS) 
+src_data_libdata_la_CPPFLAGS = $(LIBXML2_CFLAGS) $(PG_CFLAGS) $(AM_CPPFLAGS) 
 
+src_data_libdata_la_LIBADD =   $(LIBXML2_LIBS) $(PG_LIBS)
 
-src_data_libdata_a_SOURCES = \
+src_data_libdata_la_SOURCES = \
        src/data/any-reader.c \
        src/data/any-reader.h \
        src/data/any-writer.c \
        src/data/any-writer.h \
+       src/data/attributes.c \
+       src/data/attributes.h \
        src/data/calendar.c \
        src/data/calendar.h \
        src/data/case-map.c \
@@ -103,3 +106,5 @@ src_data_libdata_a_SOURCES = \
        src/data/variable.c \
        src/data/vector.c \
        src/data/vector.h
+
+EXTRA_DIST += src/data/OChangeLog
index 7b3948c441e0658914a3737ae33071f8b0c2a910..c4a716e079e81eb42a0d6ab4bf703da5988ca2cc 100644 (file)
@@ -37,8 +37,6 @@ struct sort_key
 /* A set of criteria for ordering cases. */
 struct case_ordering
   {
-    size_t value_cnt;           /* Number of `union value's per case. */
-
     /* Sort keys. */
     struct sort_key *keys;
     size_t key_cnt;
@@ -49,10 +47,9 @@ struct case_ordering
    contains no variables, so that all cases will compare as
    equal. */
 struct case_ordering *
-case_ordering_create (const struct dictionary *dict)
+case_ordering_create (void)
 {
   struct case_ordering *co = xmalloc (sizeof *co);
-  co->value_cnt = dict_get_next_value_idx (dict);
   co->keys = NULL;
   co->key_cnt = 0;
   return co;
@@ -63,7 +60,6 @@ struct case_ordering *
 case_ordering_clone (const struct case_ordering *orig)
 {
   struct case_ordering *co = xmalloc (sizeof *co);
-  co->value_cnt = orig->value_cnt;
   co->keys = xmemdup (orig->keys, orig->key_cnt * sizeof *orig->keys);
   co->key_cnt = orig->key_cnt;
   return co;
@@ -80,15 +76,6 @@ case_ordering_destroy (struct case_ordering *co)
     }
 }
 
-/* Returns the number of `union value's in the cases that case
-   ordering CO compares (taken from the dictionary used to
-   construct it). */
-size_t
-case_ordering_get_value_cnt (const struct case_ordering *co)
-{
-  return co->value_cnt;
-}
-
 /* Compares cases A and B given case ordering CO and returns a
    strcmp()-type result. */
 int
index 026cd8993690d72c526d15979dff25023d7dc25f..f49f26511402af246c01e26f5bbc2291e1b449e0 100644 (file)
@@ -32,7 +32,7 @@ enum sort_direction
   };
 
 /* Creation and destruction. */
-struct case_ordering *case_ordering_create (const struct dictionary *);
+struct case_ordering *case_ordering_create (void);
 struct case_ordering *case_ordering_clone (const struct case_ordering *);
 void case_ordering_destroy (struct case_ordering *);
 
index 37e1dc85c828f1908fef2454f3ecad872b9a6d68..fcd264e9dc35e08f8d7737b83973ca9c5d4f9e40 100644 (file)
@@ -245,6 +245,7 @@ struct casereader_filter_missing
     struct variable **vars;     /* Variables whose values to filter. */
     size_t var_cnt;             /* Number of variables. */
     enum mv_class class;        /* Types of missing values to filter. */
+    casenumber *n_missing;
   };
 
 static bool casereader_filter_missing_include (const struct ccase *, void *);
@@ -264,6 +265,9 @@ static bool casereader_filter_missing_destroy (void *);
    read or, if that never occurs, until the filtering casereader
    is destroyed.
 
+   If N_MISSING is non-null, then after reading, it will be filled
+   with the totla number of dropped cases.
+
    After this function is called, READER must not ever again
    be referenced directly.  It will be destroyed automatically
    when the filtering casereader is destroyed. */
@@ -271,6 +275,7 @@ struct casereader *
 casereader_create_filter_missing (struct casereader *reader,
                                   const struct variable **vars, size_t var_cnt,
                                   enum mv_class class,
+                                 casenumber *n_missing,
                                   struct casewriter *exclude)
 {
   if (var_cnt > 0 && class != MV_NEVER)
@@ -279,6 +284,8 @@ casereader_create_filter_missing (struct casereader *reader,
       cfm->vars = xmemdup (vars, sizeof *vars * var_cnt);
       cfm->var_cnt = var_cnt;
       cfm->class = class;
+      cfm->n_missing = n_missing;
+      if (n_missing) *n_missing = 0;
       return casereader_create_filter_func (reader,
                                             casereader_filter_missing_include,
                                             casereader_filter_missing_destroy,
@@ -302,7 +309,11 @@ casereader_filter_missing_include (const struct ccase *c, void *cfm_)
       struct variable *var = cfm->vars[i];
       const union value *value = case_data (c, var);
       if (var_is_value_missing (var, value, cfm->class))
-        return false;
+       {
+         if ( cfm->n_missing )
+           (*cfm->n_missing)++;
+         return false;
+       }
     }
   return true;
 }
index b857b5b880e2d4b9cd71c1a5c49e008cf93a5e9f..ae22f1297e19dbe5a12e6d9e2ec49f75ce8de087 100644 (file)
@@ -15,9 +15,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
-
+#include <data/val-type.h>
 #include <data/casereader.h>
-
 #include <stdlib.h>
 
 #include <data/casereader-provider.h>
@@ -110,3 +109,257 @@ static const struct casereader_class casereader_translator_class =
     NULL,
     NULL,
   };
+
+\f
+
+struct casereader_append_numeric
+{
+  int value_ofs;
+  casenumber n;
+  new_value_func *func;
+  void *aux;
+  void (*destroy) (void *aux);
+};
+
+static bool can_destroy (void *can_);
+
+static void can_translate (struct ccase *input, struct ccase *output,
+                          void *can_);
+
+/* Creates and returns a new casereader whose cases are produced
+   by reading from SUBREADER and appending an additional value,
+   generated by FUNC.  AUX is an optional parameter which
+   gets passed to FUNC. FUNC will also receive N as it, which is
+   the ordinal number of the case in the reader.  DESTROY is an
+   optional parameter used to destroy AUX.
+
+   After this function is called, SUBREADER must not ever again
+   be referenced directly.  It will be destroyed automatically
+   when the translating casereader is destroyed. */
+struct casereader *
+casereader_create_append_numeric (struct casereader *subreader,
+                                 new_value_func func, void *aux,
+                                 void (*destroy) (void *aux))
+{
+  struct casereader_append_numeric *can = xmalloc (sizeof *can);
+  can->value_ofs = casereader_get_value_cnt (subreader);
+  can->n = 0;
+  can->aux = aux;
+  can->func = func;
+  can->destroy = destroy;
+  return casereader_create_translator (subreader, can->value_ofs + 1,
+                                       can_translate, can_destroy, can);
+}
+
+
+static void
+can_translate (struct ccase *input, struct ccase *output, void *can_)
+{
+  struct casereader_append_numeric *can = can_;
+  double new_value = can->func (input, can->n++, can->aux);
+  case_nullify (output);
+  case_move (output, input);
+  case_resize (output, can->value_ofs + 1);
+  case_data_rw_idx (output, can->value_ofs)->f = new_value;
+}
+
+static bool
+can_destroy (void *can_)
+{
+  struct casereader_append_numeric *can = can_;
+  if (can->destroy)
+    can->destroy (can->aux);
+  free (can);
+  return true;
+}
+
+\f
+
+struct arithmetic_sequence
+{
+  double first;
+  double increment;
+};
+
+static double
+next_arithmetic (const struct ccase *c UNUSED,
+                casenumber n,
+                void *aux)
+{
+  struct arithmetic_sequence *as = aux;
+  return n * as->increment + as->first;
+}
+
+/* Creates and returns a new casereader whose cases are produced
+   by reading from SUBREADER and appending an additional value,
+   which takes the value FIRST in the first case, FIRST +
+   INCREMENT in the second case, FIRST + INCREMENT * 2 in the
+   third case, and so on.
+
+   After this function is called, SUBREADER must not ever again
+   be referenced directly.  It will be destroyed automatically
+   when the translating casereader is destroyed. */
+struct casereader *
+casereader_create_arithmetic_sequence (struct casereader *subreader,
+                                       double first, double increment)
+{
+  struct arithmetic_sequence *as = xzalloc (sizeof *as);
+  as->first = first;
+  as->increment = increment;
+  return casereader_create_append_numeric (subreader, next_arithmetic,
+                                          as, free);
+}
+
+
+\f
+
+struct casereader_append_rank
+{
+  struct casereader *clone;
+  casenumber n;
+  const struct variable *var;
+  const struct variable *weight;
+  int value_ofs;
+  casenumber n_common;
+  double mean_rank;
+  double cc;
+  distinct_func *distinct;
+  void *aux;
+  enum rank_error *err;
+  double prev_value;
+};
+
+static bool car_destroy (void *car_);
+
+static void car_translate (struct ccase *input, struct ccase *output,
+                          void *car_);
+
+/* Creates and returns a new casereader whose cases are produced
+   by reading from SUBREADER and appending an additional value,
+   which is the rank of the observation.   W is the weight variable
+   of the dictionary containing V, or NULL if there is no weight
+   variable.
+
+   The following preconditions must be met:
+
+   1.    SUBREADER must be sorted on V.
+
+   2.    The weight variables, must be non-negative.
+
+   If either of these preconditions are not satisfied, then the rank
+   variables may not be correct.  In this case, if ERR is non-null,
+   it will be set according to the erroneous conditions encountered.
+
+   If DISTINCT_CALLBACK is non-null, then  it will be called exactly
+   once for every case containing a distinct value of V.  AUX is
+   an auxilliary pointer passed to DISTINCT_CALLBACK.
+
+   After this function is called, SUBREADER must not ever again
+   be referenced directly.  It will be destroyed automatically
+   when the translating casereader is destroyed. */
+struct casereader *
+casereader_create_append_rank (struct casereader *subreader,
+                              const struct variable *v,
+                              const struct variable *w,
+                              enum rank_error *err,
+                              distinct_func *distinct_callback,
+                              void *aux
+                              )
+{
+  struct casereader_append_rank *car = xmalloc (sizeof *car);
+  car->value_ofs = casereader_get_value_cnt (subreader);
+  car->weight = w;
+  car->var = v;
+  car->n = 0;
+  car->n_common = 1;
+  car->cc = 0.0;
+  car->clone = casereader_clone (subreader);
+  car->distinct = distinct_callback;
+  car->aux = aux;
+  car->err = err;
+  car->prev_value = SYSMIS;
+
+  return casereader_create_translator (subreader, car->value_ofs + 1,
+                                       car_translate, car_destroy, car);
+}
+
+
+static bool
+car_destroy (void *car_)
+{
+  struct casereader_append_rank *car = car_;
+  casereader_destroy (car->clone);
+  free (car);
+  return true;
+}
+
+
+static void
+car_translate (struct ccase *input, struct ccase *output,  void *car_)
+{
+  struct casereader_append_rank *car = car_;
+
+  const double value = case_data (input, car->var)->f;
+
+  if ( car->prev_value != SYSMIS)
+    {
+      if (car->err && value < car->prev_value)
+       *car->err |= RANK_ERR_UNSORTED;
+    }
+
+  if ( car->n_common == 1)
+    {
+      double vxx = SYSMIS;
+      casenumber k = 0;
+      double weight = 1.0;
+      if (car->weight)
+       {
+         weight = case_data (input, car->weight)->f;
+         if ( car->err && weight < 0 )
+           *car->err |= RANK_ERR_NEGATIVE_WEIGHT;
+       }
+
+      do
+       {
+         struct ccase c;
+         if ( ! casereader_peek (car->clone, car->n + ++k, &c))
+           break;
+         vxx = case_data (&c, car->var)->f;
+
+         if ( vxx == value)
+           {
+             if (car->weight)
+               {
+                 double w = case_data (&c, car->weight)->f;
+
+                 if ( car->err && w < 0 )
+                   *car->err |= RANK_ERR_NEGATIVE_WEIGHT;
+
+                 weight += w;
+               }
+             else
+               weight += 1.0;
+             car->n_common++;
+           }
+         case_destroy (&c);
+       }
+      while (vxx == value);
+      car->mean_rank = car->cc + (weight + 1) / 2.0;
+      car->cc += weight;
+
+      if (car->distinct)
+       car->distinct (value, car->n_common, weight, car->aux);
+    }
+  else
+    car->n_common--;
+
+  car->n++;
+
+  case_nullify (output);
+  case_move (output, input);
+  case_resize (output, car->value_ofs + 1);
+  case_data_rw_idx (output, car->value_ofs)->f = car->mean_rank ;
+  car->prev_value = value;
+}
+
+
index 6d719c6128da45b9fbd8f6635741132053311816..3df80cb08fb8d38acc302e0654a0217dd666287a 100644 (file)
@@ -98,6 +98,7 @@ struct casereader *
 casereader_create_filter_missing (struct casereader *,
                                   const struct variable **vars, size_t var_cnt,
                                   enum mv_class,
+                                 casenumber *n_missing,
                                   struct casewriter *exclude);
 
 struct casereader *
@@ -112,4 +113,33 @@ casereader_create_translator (struct casereader *, size_t output_value_cnt,
                               bool (*destroy) (void *aux),
                               void *aux);
 
+/* A function which creates a numberic value from an existing case */
+typedef double new_value_func (const struct ccase *, casenumber, void *);
+
+struct casereader *
+casereader_create_append_numeric (struct casereader *subreader,
+                                 new_value_func func, void *aux,
+                                 void (*destroy) (void *aux));
+
+struct casereader *
+casereader_create_arithmetic_sequence (struct casereader *,
+                                       double first, double increment);
+
+enum rank_error
+  {
+    RANK_ERR_NONE = 0,
+    RANK_ERR_NEGATIVE_WEIGHT = 0x01,
+    RANK_ERR_UNSORTED = 0x02
+  };
+
+
+typedef void distinct_func (double v, casenumber n, double w, void *aux);
+
+struct casereader *
+casereader_create_append_rank (struct casereader *,
+                              const struct variable *v, const struct variable *w,
+                              enum rank_error *err,
+                              distinct_func *distinct_callback, void *aux);
+
+
 #endif /* data/casereader.h */
index a30e50e20983f1f88adde7463931ad3ad4430c1b..4461d85e84cfc191821746df34e44b02dfc0f4ef 100644 (file)
@@ -91,8 +91,7 @@ casewriter_get_value_cnt (const struct casewriter *writer)
 struct casereader *
 casewriter_make_reader (struct casewriter *writer)
 {
-  struct casereader *reader;
-  reader = writer->class->convert_to_reader (writer, writer->aux);
+  struct casereader *reader = writer->class->convert_to_reader (writer, writer->aux);
   taint_propagate (writer->taint, casereader_get_taint (reader));
   taint_destroy (writer->taint);
   free (writer);
@@ -241,10 +240,11 @@ casewriter_window_convert_to_reader (struct casewriter *writer UNUSED,
                                      void *window_)
 {
   struct casewindow *window = window_;
-  struct casereader *reader;
-  reader = casereader_create_random (casewindow_get_value_cnt (window),
-                                     casewindow_get_case_cnt (window),
-                                     &casereader_window_class, window);
+  struct casereader *reader =
+    casereader_create_random (casewindow_get_value_cnt (window),
+                             casewindow_get_case_cnt (window),
+                             &casereader_window_class, window);
+
   taint_propagate (casewindow_get_taint (window),
                    casereader_get_taint (reader));
   return reader;
index b0424d9f65c054df4631897702d33ab4eae1c57a..7190418c266f2d31083f12bb3717f4a61b370155 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "xalloc.h"
 
-#define CAT_VALUE_NOT_FOUND -2
+#define CAT_VALUE_NOT_FOUND -1
 
 #define N_INITIAL_CATEGORIES 1
 
@@ -58,6 +58,11 @@ struct cat_vals
                                           track of the number of
                                           values stored.
                                         */
+  size_t *value_counts; /* Element i stores the number of cases for which
+                          the categorical variable has that corresponding 
+                          value. This is necessary for computing covariance
+                          matrices.
+                        */
 };
 
 void
@@ -70,6 +75,7 @@ cat_stored_values_create (const struct variable *v)
       obs_vals->n_categories = 0;
       obs_vals->n_allocated_categories = N_INITIAL_CATEGORIES;
       obs_vals->vals = xnmalloc (N_INITIAL_CATEGORIES, sizeof *obs_vals->vals);
+      obs_vals->value_counts = xnmalloc (N_INITIAL_CATEGORIES, sizeof *obs_vals->value_counts);
       var_set_obs_vals (v, obs_vals);
     }
 }
@@ -80,7 +86,10 @@ cat_stored_values_destroy (struct cat_vals *obs_vals)
   if (obs_vals != NULL)
     {
       if (obs_vals->n_allocated_categories > 0)
-        free (obs_vals->vals);
+       {
+         free (obs_vals->vals);
+         free (obs_vals->value_counts);
+       }
       free (obs_vals);
     }
 }
@@ -99,7 +108,7 @@ cat_value_find (const struct variable *v, const union value *val)
     {
       candidate = obs_vals->vals + i;
       assert (candidate != NULL);
-      if (!compare_values (candidate, val, var_get_width (v)))
+      if (!compare_values (candidate, val, v))
        {
          return i;
        }
@@ -108,15 +117,17 @@ cat_value_find (const struct variable *v, const union value *val)
 }
 
 /*
-   Add the new value unless it is already present.
+   Add the new value unless it is already present. Increment the count.
  */
 void
 cat_value_update (const struct variable *v, const union value *val)
 {
   if (var_is_alpha (v))
     {
+      size_t i;
       struct cat_vals *cv = var_get_obs_vals (v);
-      if (cat_value_find (v, val) == CAT_VALUE_NOT_FOUND)
+      i = cat_value_find (v, val);
+      if (i == CAT_VALUE_NOT_FOUND)
        {
          if (cv->n_categories >= cv->n_allocated_categories)
            {
@@ -124,11 +135,35 @@ cat_value_update (const struct variable *v, const union value *val)
              cv->vals = xnrealloc (cv->vals,
                                    cv->n_allocated_categories,
                                    sizeof *cv->vals);
+             cv->value_counts = xnrealloc (cv->value_counts, cv->n_allocated_categories,
+                                           sizeof *cv->value_counts);
            }
          cv->vals[cv->n_categories] = *val;
+         cv->value_counts[cv->n_categories] = 1;
          cv->n_categories++;
        }
+      else
+       {
+         cv->value_counts[i]++;
+       }
+    }
+}
+/*
+  Return the count for the sth category.
+ */
+size_t
+cat_get_category_count (const size_t s, const struct variable *v)
+{
+  struct cat_vals *tmp;
+  size_t n_categories;
+
+  tmp = var_get_obs_vals (v);
+  n_categories = cat_get_n_categories (v);
+  if (s < n_categories)
+    {
+      return tmp->value_counts[s];
     }
+  return CAT_VALUE_NOT_FOUND;
 }
 
 const union value *
index 6ef408577913207654bc77e5222edcd1e4fe7812..db4bb339bcb5e6ecab1bd0de98a76632dfe20f95 100644 (file)
@@ -50,6 +50,11 @@ const union value *cat_subscript_to_value (const size_t,
 
 void cat_value_update (const struct variable *, const union value *);
 
+/*
+  Return the count for the sth category.
+*/
+size_t
+cat_get_category_count (const size_t, const struct variable *);
 
 /*
   Return the number of categories of a categorical variable.
index 7d4df5adccb9310d6964e5a544a3880ef5238968..3a8d67cc22f66b28eb0bed54126e5a3255449064 100644 (file)
@@ -22,7 +22,7 @@
 #include <libpspp/float-format.h>
 #include <libpspp/integer-format.h>
 #include <libpspp/str.h>
-
+#include <data/format.h>
 
 enum fmt_type;
 union value;
index cef445209a6ef874394f7798b47bafdd173b1317..86688a6774cd939facdb8453dbd7e9e2832934ec 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <ctype.h>
 #include <float.h>
-#include <gsl/gsl_math.h>
 #include <math.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -928,9 +927,9 @@ output_infinite (double number, const struct fmt_spec *format, char *output)
     {
       const char *s;
 
-      if (gsl_isnan (number))
+      if (isnan (number))
         s = "NaN";
-      else if (gsl_isinf (number))
+      else if (isinf (number))
         s = number > 0 ? "+Infinity" : "-Infinity";
       else
         s = "Unknown";
index da85d963c17dfb166ff93ab1e7882f1ee8105d42..a11a1e596c4446106e7f9adab05a385dc307479b 100644 (file)
@@ -28,7 +28,6 @@
 #include <data/sparse-cases.h>
 #include <libpspp/array.h>
 #include <libpspp/assertion.h>
-#include <libpspp/model-checker.h>
 #include <libpspp/range-map.h>
 #include <libpspp/range-set.h>
 #include <libpspp/taint.h>
@@ -1232,36 +1231,10 @@ source_has_backing (const struct source *source)
 #define MAX_ROWS 5
 #define MAX_COLS 5
 
-/* Hashes the structure of datasheet DS and returns the hash.
-   We use MD4 because it is much faster than MD5 or SHA-1 but its
-   collision resistance is just as good. */
-static unsigned int
-hash_datasheet (const struct datasheet *ds)
-{
-  unsigned int hash[DIV_RND_UP (20, sizeof (unsigned int))];
-  struct md4_ctx ctx;
-  struct range_map_node *r;
-
-  md4_init_ctx (&ctx);
-  axis_hash (ds->columns, &ctx);
-  axis_hash (ds->rows, &ctx);
-  for (r = range_map_first (&ds->sources); r != NULL;
-       r = range_map_next (&ds->sources, r))
-    {
-      unsigned long int start = range_map_node_get_start (r);
-      unsigned long int end = range_map_node_get_end (r);
-      md4_process_bytes (&start, sizeof start, &ctx);
-      md4_process_bytes (&end, sizeof end, &ctx);
-    }
-  md4_process_bytes (&ds->column_min_alloc, sizeof ds->column_min_alloc,
-                      &ctx);
-  md4_finish_ctx (&ctx, hash);
-  return hash[0];
-}
 
 /* Clones the structure and contents of ODS into a new datasheet,
    and returns the new datasheet. */
-static struct datasheet *
+struct datasheet *
 clone_datasheet (const struct datasheet *ods)
 {
   struct datasheet *ds;
@@ -1286,426 +1259,33 @@ clone_datasheet (const struct datasheet *ods)
   return ds;
 }
 
-/* lazy_casereader callback function to instantiate a casereader
-   from the datasheet. */
-static struct casereader *
-lazy_callback (void *ds_)
-{
-  struct datasheet *ds = ds_;
-  return datasheet_make_reader (ds);
-}
-
-/* Checks that READER contains the ROW_CNT rows and COLUMN_CNT
-   columns of data in ARRAY, reporting any errors via MC. */
-static void
-check_datasheet_casereader (struct mc *mc, struct casereader *reader,
-                            double array[MAX_ROWS][MAX_COLS],
-                            size_t row_cnt, size_t column_cnt)
-{
-  if (casereader_get_case_cnt (reader) != row_cnt)
-    {
-      if (casereader_get_case_cnt (reader) == CASENUMBER_MAX
-          && casereader_count_cases (reader) == row_cnt)
-        mc_error (mc, "datasheet casereader has unknown case count");
-      else
-        mc_error (mc, "casereader row count (%lu) does not match "
-                  "expected (%zu)",
-                  (unsigned long int) casereader_get_case_cnt (reader),
-                  row_cnt);
-    }
-  else if (casereader_get_value_cnt (reader) != column_cnt)
-    mc_error (mc, "casereader column count (%zu) does not match "
-              "expected (%zu)",
-              casereader_get_value_cnt (reader), column_cnt);
-  else
-    {
-      struct ccase c;
-      size_t row;
-
-      for (row = 0; row < row_cnt; row++)
-        {
-          size_t col;
-
-          if (!casereader_read (reader, &c))
-            {
-              mc_error (mc, "casereader_read failed reading row %zu of %zu "
-                        "(%zu columns)", row, row_cnt, column_cnt);
-              return;
-            }
-
-          for (col = 0; col < column_cnt; col++)
-            if (case_num_idx (&c, col) != array[row][col])
-              mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
-                        "%g != %g",
-                        row, col, row_cnt, column_cnt,
-                        case_num_idx (&c, col), array[row][col]);
-
-         case_destroy (&c);
-        }
-
-      if (casereader_read (reader, &c))
-        mc_error (mc, "casereader has extra cases (expected %zu)", row_cnt);
-    }
-}
-
-/* Checks that datasheet DS contains has ROW_CNT rows, COLUMN_CNT
-   columns, and the same contents as ARRAY, reporting any
-   mismatches via mc_error.  Then, adds DS to MC as a new state. */
-static void
-check_datasheet (struct mc *mc, struct datasheet *ds,
-                 double array[MAX_ROWS][MAX_COLS],
-                 size_t row_cnt, size_t column_cnt)
-{
-  struct datasheet *ds2;
-  struct casereader *reader;
-  unsigned long int serial = 0;
-
-  assert (row_cnt < MAX_ROWS);
-  assert (column_cnt < MAX_COLS);
-
-  /* If it is a duplicate hash, discard the state before checking
-     its consistency, to save time. */
-  if (mc_discard_dup_state (mc, hash_datasheet (ds)))
-    {
-      datasheet_destroy (ds);
-      return;
-    }
-
-  /* Check contents of datasheet via datasheet functions. */
-  if (row_cnt != datasheet_get_row_cnt (ds))
-    mc_error (mc, "row count (%lu) does not match expected (%zu)",
-              (unsigned long int) datasheet_get_row_cnt (ds), row_cnt);
-  else if (column_cnt != datasheet_get_column_cnt (ds))
-    mc_error (mc, "column count (%zu) does not match expected (%zu)",
-              datasheet_get_column_cnt (ds), column_cnt);
-  else
-    {
-      size_t row, col;
-
-      for (row = 0; row < row_cnt; row++)
-        for (col = 0; col < column_cnt; col++)
-          {
-            union value v;
-            if (!datasheet_get_value (ds, row, col, &v, 1))
-              NOT_REACHED ();
-            if (v.f != array[row][col])
-              mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: %g != %g",
-                        row, col, row_cnt, column_cnt, v.f, array[row][col]);
-          }
-    }
-
-  /* Check that datasheet contents are correct when read through
-     casereader. */
-  ds2 = clone_datasheet (ds);
-  reader = datasheet_make_reader (ds2);
-  check_datasheet_casereader (mc, reader, array, row_cnt, column_cnt);
-  casereader_destroy (reader);
-
-  /* Check that datasheet contents are correct when read through
-     casereader with lazy_casereader wrapped around it.  This is
-     valuable because otherwise there is no non-GUI code that
-     uses the lazy_casereader. */
-  ds2 = clone_datasheet (ds);
-  reader = lazy_casereader_create (column_cnt, row_cnt,
-                                   lazy_callback, ds2, &serial);
-  check_datasheet_casereader (mc, reader, array, row_cnt, column_cnt);
-  if (lazy_casereader_destroy (reader, serial))
-    {
-      /* Lazy casereader was never instantiated.  This will
-         only happen if there are no rows (because in that case
-         casereader_read never gets called). */
-      datasheet_destroy (ds2);
-      if (row_cnt != 0)
-        mc_error (mc, "lazy casereader not instantiated, but should "
-                  "have been (size %zu,%zu)", row_cnt, column_cnt);
-    }
-  else
-    {
-      /* Lazy casereader was instantiated.  This is the common
-         case, in which some casereader operation
-         (casereader_read in this case) was performed on the
-         lazy casereader. */
-      casereader_destroy (reader);
-      if (row_cnt == 0)
-        mc_error (mc, "lazy casereader instantiated, but should not "
-                  "have been (size %zu,%zu)", row_cnt, column_cnt);
-    }
-
-  mc_add_state (mc, ds);
-}
-
-/* Extracts the contents of DS into DATA. */
-static void
-extract_data (const struct datasheet *ds, double data[MAX_ROWS][MAX_COLS])
-{
-  size_t column_cnt = datasheet_get_column_cnt (ds);
-  size_t row_cnt = datasheet_get_row_cnt (ds);
-  size_t row, col;
-
-  assert (row_cnt < MAX_ROWS);
-  assert (column_cnt < MAX_COLS);
-  for (row = 0; row < row_cnt; row++)
-    for (col = 0; col < column_cnt; col++)
-      {
-        union value v;
-        if (!datasheet_get_value (ds, row, col, &v, 1))
-          NOT_REACHED ();
-        data[row][col] = v.f;
-      }
-}
-
-/* Clones the structure and contents of ODS into *DS,
-   and the contents of ODATA into DATA. */
-static void
-clone_model (const struct datasheet *ods, double odata[MAX_ROWS][MAX_COLS],
-             struct datasheet **ds, double data[MAX_ROWS][MAX_COLS])
-{
-  *ds = clone_datasheet (ods);
-  memcpy (data, odata, MAX_ROWS * MAX_COLS * sizeof **data);
-}
 
-/* "init" function for struct mc_class. */
-static void
-datasheet_mc_init (struct mc *mc)
+/* Hashes the structure of datasheet DS and returns the hash.
+   We use MD4 because it is much faster than MD5 or SHA-1 but its
+   collision resistance is just as good. */
+unsigned int
+hash_datasheet (const struct datasheet *ds)
 {
-  struct datasheet_test_params *params = mc_get_aux (mc);
-  struct datasheet *ds;
+  unsigned int hash[DIV_RND_UP (20, sizeof (unsigned int))];
+  struct md4_ctx ctx;
+  struct range_map_node *r;
 
-  if (params->backing_rows == 0 && params->backing_cols == 0)
-    {
-      /* Create unbacked datasheet. */
-      ds = datasheet_create (NULL);
-      mc_name_operation (mc, "empty datasheet");
-      check_datasheet (mc, ds, NULL, 0, 0);
-    }
-  else
+  md4_init_ctx (&ctx);
+  axis_hash (ds->columns, &ctx);
+  axis_hash (ds->rows, &ctx);
+  for (r = range_map_first (&ds->sources); r != NULL;
+       r = range_map_next (&ds->sources, r))
     {
-      /* Create datasheet with backing. */
-      struct casewriter *writer;
-      struct casereader *reader;
-      double data[MAX_ROWS][MAX_COLS];
-      int row;
-
-      assert (params->backing_rows > 0 && params->backing_rows <= MAX_ROWS);
-      assert (params->backing_cols > 0 && params->backing_cols <= MAX_COLS);
-
-      writer = mem_writer_create (params->backing_cols);
-      for (row = 0; row < params->backing_rows; row++)
-        {
-          struct ccase c;
-          int col;
-
-          case_create (&c, params->backing_cols);
-          for (col = 0; col < params->backing_cols; col++)
-            {
-              double value = params->next_value++;
-              data[row][col] = value;
-              case_data_rw_idx (&c, col)->f = value;
-            }
-          casewriter_write (writer, &c);
-        }
-      reader = casewriter_make_reader (writer);
-      assert (reader != NULL);
-
-      ds = datasheet_create (reader);
-      mc_name_operation (mc, "datasheet with (%d,%d) backing",
-                         params->backing_rows, params->backing_cols);
-      check_datasheet (mc, ds, data,
-                       params->backing_rows, params->backing_cols);
+      unsigned long int start = range_map_node_get_start (r);
+      unsigned long int end = range_map_node_get_end (r);
+      md4_process_bytes (&start, sizeof start, &ctx);
+      md4_process_bytes (&end, sizeof end, &ctx);
     }
+  md4_process_bytes (&ds->column_min_alloc, sizeof ds->column_min_alloc,
+                      &ctx);
+  md4_finish_ctx (&ctx, hash);
+  return hash[0];
 }
 
-/* "mutate" function for struct mc_class. */
-static void
-datasheet_mc_mutate (struct mc *mc, const void *ods_)
-{
-  struct datasheet_test_params *params = mc_get_aux (mc);
-
-  const struct datasheet *ods = ods_;
-  double odata[MAX_ROWS][MAX_COLS];
-  double data[MAX_ROWS][MAX_COLS];
-  size_t column_cnt = datasheet_get_column_cnt (ods);
-  size_t row_cnt = datasheet_get_row_cnt (ods);
-  size_t pos, new_pos, cnt;
-
-  extract_data (ods, odata);
-
-  /* Insert all possible numbers of columns in all possible
-     positions. */
-  for (pos = 0; pos <= column_cnt; pos++)
-    for (cnt = 0; cnt <= params->max_cols - column_cnt; cnt++)
-      if (mc_include_state (mc))
-        {
-          struct datasheet *ds;
-          union value new[MAX_COLS];
-          size_t i, j;
-
-          mc_name_operation (mc, "insert %zu columns at %zu", cnt, pos);
-          clone_model (ods, odata, &ds, data);
-
-          for (i = 0; i < cnt; i++)
-            new[i].f = params->next_value++;
-
-          if (!datasheet_insert_columns (ds, new, cnt, pos))
-            mc_error (mc, "datasheet_insert_columns failed");
-
-          for (i = 0; i < row_cnt; i++)
-            {
-              insert_range (&data[i][0], column_cnt, sizeof data[i][0],
-                            pos, cnt);
-              for (j = 0; j < cnt; j++)
-                data[i][pos + j] = new[j].f;
-            }
-
-          check_datasheet (mc, ds, data, row_cnt, column_cnt + cnt);
-        }
-
-  /* Delete all possible numbers of columns from all possible
-     positions. */
-  for (pos = 0; pos < column_cnt; pos++)
-    for (cnt = 0; cnt < column_cnt - pos; cnt++)
-      if (mc_include_state (mc))
-        {
-          struct datasheet *ds;
-          size_t i;
-
-          mc_name_operation (mc, "delete %zu columns at %zu", cnt, pos);
-          clone_model (ods, odata, &ds, data);
-
-          datasheet_delete_columns (ds, pos, cnt);
-
-          for (i = 0; i < row_cnt; i++)
-            remove_range (&data[i], column_cnt, sizeof *data[i], pos, cnt);
-
-          check_datasheet (mc, ds, data, row_cnt, column_cnt - cnt);
-        }
-
-  /* Move all possible numbers of columns from all possible
-     existing positions to all possible new positions. */
-  for (pos = 0; pos < column_cnt; pos++)
-    for (cnt = 0; cnt < column_cnt - pos; cnt++)
-      for (new_pos = 0; new_pos < column_cnt - cnt; new_pos++)
-        if (mc_include_state (mc))
-          {
-            struct datasheet *ds;
-            size_t i;
-
-            clone_model (ods, odata, &ds, data);
-            mc_name_operation (mc, "move %zu columns from %zu to %zu",
-                               cnt, pos, new_pos);
-
-            datasheet_move_columns (ds, pos, new_pos, cnt);
-
-            for (i = 0; i < row_cnt; i++)
-              move_range (&data[i], column_cnt, sizeof data[i][0],
-                          pos, new_pos, cnt);
-
-            check_datasheet (mc, ds, data, row_cnt, column_cnt);
-          }
-
-  /* Insert all possible numbers of rows in all possible
-     positions. */
-  for (pos = 0; pos <= row_cnt; pos++)
-    for (cnt = 0; cnt <= params->max_rows - row_cnt; cnt++)
-      if (mc_include_state (mc))
-        {
-          struct datasheet *ds;
-          struct ccase c[MAX_ROWS];
-          size_t i, j;
-
-          clone_model (ods, odata, &ds, data);
-          mc_name_operation (mc, "insert %zu rows at %zu", cnt, pos);
-
-          for (i = 0; i < cnt; i++)
-            {
-              case_create (&c[i], column_cnt);
-              for (j = 0; j < column_cnt; j++)
-                case_data_rw_idx (&c[i], j)->f = params->next_value++;
-            }
-
-          insert_range (data, row_cnt, sizeof data[pos], pos, cnt);
-          for (i = 0; i < cnt; i++)
-            for (j = 0; j < column_cnt; j++)
-              data[i + pos][j] = case_num_idx (&c[i], j);
-
-          if (!datasheet_insert_rows (ds, pos, c, cnt))
-            mc_error (mc, "datasheet_insert_rows failed");
-
-          check_datasheet (mc, ds, data, row_cnt + cnt, column_cnt);
-        }
-
-  /* Delete all possible numbers of rows from all possible
-     positions. */
-  for (pos = 0; pos < row_cnt; pos++)
-    for (cnt = 0; cnt < row_cnt - pos; cnt++)
-      if (mc_include_state (mc))
-        {
-          struct datasheet *ds;
-
-          clone_model (ods, odata, &ds, data);
-          mc_name_operation (mc, "delete %zu rows at %zu", cnt, pos);
-
-          datasheet_delete_rows (ds, pos, cnt);
-
-          remove_range (&data[0], row_cnt, sizeof data[0], pos, cnt);
-
-          check_datasheet (mc, ds, data, row_cnt - cnt, column_cnt);
-        }
-
-  /* Move all possible numbers of rows from all possible existing
-     positions to all possible new positions. */
-  for (pos = 0; pos < row_cnt; pos++)
-    for (cnt = 0; cnt < row_cnt - pos; cnt++)
-      for (new_pos = 0; new_pos < row_cnt - cnt; new_pos++)
-        if (mc_include_state (mc))
-          {
-            struct datasheet *ds;
-
-            clone_model (ods, odata, &ds, data);
-            mc_name_operation (mc, "move %zu rows from %zu to %zu",
-                               cnt, pos, new_pos);
-
-            datasheet_move_rows (ds, pos, new_pos, cnt);
-
-            move_range (&data[0], row_cnt, sizeof data[0],
-                        pos, new_pos, cnt);
-
-            check_datasheet (mc, ds, data, row_cnt, column_cnt);
-          }
-}
-
-/* "destroy" function for struct mc_class. */
-static void
-datasheet_mc_destroy (const struct mc *mc UNUSED, void *ds_)
-{
-  struct datasheet *ds = ds_;
-  datasheet_destroy (ds);
-}
 
-/* Executes the model checker on the datasheet test driver with
-   the given OPTIONS and passing in the given PARAMS, which must
-   point to a modifiable "struct datasheet_test_params".  If any
-   value in PARAMS is out of range, it will be adjusted into the
-   valid range before running the test.
 
-   Returns the results of the model checking run. */
-struct mc_results *
-datasheet_test (struct mc_options *options, void *params_)
-{
-  struct datasheet_test_params *params = params_;
-  static const struct mc_class datasheet_mc_class =
-    {
-      datasheet_mc_init,
-      datasheet_mc_mutate,
-      datasheet_mc_destroy,
-    };
-
-  params->next_value = 1;
-  params->max_rows = MIN (params->max_rows, MAX_ROWS);
-  params->max_cols = MIN (params->max_cols, MAX_COLS);
-  params->backing_rows = MIN (params->backing_rows, params->max_rows);
-  params->backing_cols = MIN (params->backing_cols, params->max_cols);
-
-  mc_options_set_aux (options, params);
-  return mc_run (&datasheet_mc_class, options);
-}
index 3d106193d1cd393bec14297a392bb68bac983604..2a05fe0da516bef80ea9ee7abafb7b38c33e4892 100644 (file)
@@ -66,21 +66,7 @@ bool datasheet_get_value (const struct datasheet *, casenumber, size_t column,
 bool datasheet_put_value (struct datasheet *, casenumber, size_t column,
                           const union value *, int width);
 
-/* Testing. */
-struct mc_options;
-
-struct datasheet_test_params
-  {
-    /* Parameters. */
-    int max_rows;
-    int max_cols;
-    int backing_rows;
-    int backing_cols;
-
-    /* State. */
-    int next_value;
-  };
-
-struct mc_results *datasheet_test (struct mc_options *options, void *params);
 
+unsigned int hash_datasheet (const struct datasheet *ds);
+struct datasheet *clone_datasheet (const struct datasheet *ds);
 #endif /* data/datasheet.h */
index 526bb280a0956b70a24f4db3e32943f98701a7ec..caf8e2fc3490cc81968197e732b74f45a5aa14f3 100644 (file)
 #include <stdlib.h>
 #include <ctype.h>
 
-#include "case.h"
-#include "category.h"
-#include "identifier.h"
-#include "settings.h"
-#include "value-labels.h"
-#include "vardict.h"
-#include "variable.h"
-#include "vector.h"
+#include <data/attributes.h>
+#include <data/case.h>
+#include <data/category.h>
+#include <data/identifier.h>
+#include <data/settings.h>
+#include <data/value-labels.h>
+#include <data/vardict.h>
+#include <data/variable.h>
+#include <data/vector.h>
 #include <libpspp/array.h>
 #include <libpspp/assertion.h>
 #include <libpspp/compiler.h>
@@ -61,6 +62,7 @@ struct dictionary
     struct string documents;    /* Documents, as a string. */
     struct vector **vector;     /* Vectors of variables. */
     size_t vector_cnt;          /* Number of vectors. */
+    struct attrset attributes;  /* Custom attributes. */
     const struct dict_callbacks *callbacks; /* Callbacks on dictionary
                                               modification */
     void *cb_data ;                  /* Data passed to callbacks */
@@ -115,6 +117,7 @@ dict_create (void)
 
   d->name_tab = hsh_create (8, compare_vars_by_name, hash_var_by_name,
                             NULL, NULL);
+  attrset_init (&d->attributes);
   return d;
 }
 
@@ -178,6 +181,8 @@ dict_clone (const struct dictionary *s)
   for (i = 0; i < s->vector_cnt; i++)
     d->vector[i] = vector_clone (s->vector[i], s, d);
 
+  dict_set_attributes (d, dict_get_attributes (s));
+
   return d;
 }
 
@@ -208,6 +213,7 @@ dict_clear (struct dictionary *d)
   d->label = NULL;
   ds_destroy (&d->documents);
   dict_clear_vectors (d);
+  attrset_clear (&d->attributes);
 }
 
 /* Destroys the aux data for every variable in D, by calling
@@ -235,6 +241,7 @@ dict_destroy (struct dictionary *d)
 
       dict_clear (d);
       hsh_destroy (d->name_tab);
+      attrset_destroy (&d->attributes);
       free (d);
     }
 }
@@ -1285,6 +1292,32 @@ dict_clear_vectors (struct dictionary *d)
   d->vector_cnt = 0;
 }
 
+/* Returns D's attribute set.  The caller may examine or modify
+   the attribute set, but must not destroy it.  Destroying D or
+   calling dict_set_attributes for D will also destroy D's
+   attribute set. */
+struct attrset *
+dict_get_attributes (const struct dictionary *d) 
+{
+  return (struct attrset *) &d->attributes;
+}
+
+/* Replaces D's attributes set by a copy of ATTRS. */
+void
+dict_set_attributes (struct dictionary *d, const struct attrset *attrs)
+{
+  attrset_destroy (&d->attributes);
+  attrset_clone (&d->attributes, attrs);
+}
+
+/* Returns true if D has at least one attribute in its attribute
+   set, false if D's attribute set is empty. */
+bool
+dict_has_attributes (const struct dictionary *d) 
+{
+  return attrset_count (&d->attributes) > 0;
+}
+
 /* Called from variable.c to notify the dictionary that some property of
    the variable has changed */
 void
index 0ab259d35b539f1635345a307572817944986d50..bb14f52ebef0fe7560ddab190693f75be8b6457f 100644 (file)
@@ -142,6 +142,11 @@ const struct vector *dict_lookup_vector (const struct dictionary *,
                                          const char *name);
 void dict_clear_vectors (struct dictionary *);
 
+/* Attributes. */
+struct attrset *dict_get_attributes (const struct dictionary *);
+void dict_set_attributes (struct dictionary *, const struct attrset *);
+bool dict_has_attributes (const struct dictionary *);
+
 /* Functions to be called upon dictionary changes. */
 struct dict_callbacks
  {
index 48a27876a76c16352cbce667000fbfe532bd4b62..23249f6a85c10f261e04a6efd20551c926357e9d 100644 (file)
@@ -17,8 +17,8 @@
 #ifndef FORMAT_GUESSER_H
 #define FORMAT_GUESSER_H 1
 
+#include <libpspp/str.h>
 struct fmt_spec;
-struct substring;
 
 struct fmt_guesser *fmt_guesser_create (void);
 void fmt_guesser_destroy (struct fmt_guesser *);
index 75022ea7f6d8b924d72112e198b59d677c79e3a0..8a27f6b785ccc548d5a14436cfe221ee7476d3e6 100644 (file)
@@ -20,7 +20,6 @@
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
-#include <gsl/gsl_math.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -778,7 +777,7 @@ format_trig_double (long double value, int base_10_precision, char output[])
      0...30**6, an invariant of the loop below. */
   errno = 0;
   base_2_sig = frexp (value, &base_2_exp);
-  if (errno != 0 || !gsl_finite (base_2_sig))
+  if (errno != 0 || !isfinite (base_2_sig))
     goto missing_value;
   if (base_2_exp == 0 && base_2_sig == 0.)
     goto zero;
index 72e14be4fce9542eb8f7c92b6a21563fc2842f0c..244248a20aeecdf34bcabedbbf188047e5c9b71c 100644 (file)
@@ -37,7 +37,7 @@
 
 #if !PSQL_SUPPORT
 struct casereader *
-psql_open_reader (struct psql_read_info *info, struct dictionary **dict)
+psql_open_reader (struct psql_read_info *info UNUSED, struct dictionary **dict UNUSED)
 {
   msg (ME, _("Support for reading postgres databases was not compiled into this installation of PSPP"));
 
index 5b791dc2e130b832bec51d31c79353f5fd2a4dc6..ad509fb028059a6c6d3af86445a1bdb9e744ce08 100644 (file)
@@ -125,7 +125,7 @@ static struct settings the_settings = {
     /* endcmd */
   '.',
     /* workspace */
-  4L * 1024 * 1024,
+  64L * 1024 * 1024,
     /* default_format */
   {FMT_F, 8, 2},
     /* testing_mode */
@@ -149,6 +149,8 @@ settings_init (int *width, int *length)
   settings_set_epoch (-1);
   i18n_init ();
   the_settings.styles = fmt_create ();
+
+  settings_set_decimal_char (get_system_decimal ());
 }
 
 void
index 2de7e9009edff74dff34fc80f8bc6c9b55bf4931..2f2bbe99b46edd2ad28e5bebb75015581b3267f9 100644 (file)
@@ -19,6 +19,9 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <data/format.h>
+#include <libpspp/float-format.h>
+#include <libpspp/integer-format.h>
 
 struct settings;
 
@@ -105,13 +108,13 @@ void settings_set_endcmd (char);
 
 size_t settings_get_workspace (void);
 size_t settings_get_workspace_cases (size_t value_cnt);
-void settings_set_workspace ( size_t);
+void settings_set_workspace (size_t);
 
 const struct fmt_spec *settings_get_format (void);
 void settings_set_format ( const struct fmt_spec *);
 
 bool settings_get_testing_mode (void);
-void settings_set_testing_mode ( bool);
+void settings_set_testing_mode (bool);
 
 enum behavior_mode {
   ENHANCED,             /* Use improved PSPP behavior. */
index d5b5b15f6ff2bbf1ae4c40e859620e7a16b3fa96..c80bd5f557246cead2e3cc0feeb743834a48d0f5 100644 (file)
@@ -34,6 +34,7 @@
 #include <libpspp/hash.h>
 #include <libpspp/array.h>
 
+#include <data/attributes.h>
 #include <data/case.h>
 #include <data/casereader-provider.h>
 #include <data/casereader.h>
@@ -98,9 +99,11 @@ static struct variable *lookup_var_by_value_idx (struct sfm_reader *,
                                                  struct variable **,
                                                  int value_idx);
 
+static void sys_msg (struct sfm_reader *r, int class,
+                     const char *format, va_list args)
+     PRINTF_FORMAT (3, 0);
 static void sys_warn (struct sfm_reader *, const char *, ...)
      PRINTF_FORMAT (2, 3);
-
 static void sys_error (struct sfm_reader *, const char *, ...)
      PRINTF_FORMAT (2, 3)
      NO_RETURN;
@@ -112,15 +115,23 @@ static double read_float (struct sfm_reader *);
 static void read_string (struct sfm_reader *, char *, size_t);
 static void skip_bytes (struct sfm_reader *, size_t);
 
-static struct variable_to_value_map *open_variable_to_value_map (
-  struct sfm_reader *, size_t size);
-static void close_variable_to_value_map (struct sfm_reader *r,
-                                         struct variable_to_value_map *);
-static bool read_variable_to_value_map (struct sfm_reader *,
-                                        struct dictionary *,
-                                        struct variable_to_value_map *,
-                                        struct variable **var, char **value,
-                                        int *warning_cnt);
+static struct text_record *open_text_record (struct sfm_reader *, size_t size);
+static void close_text_record (struct sfm_reader *r,
+                               struct text_record *);
+static bool read_variable_to_value_pair (struct sfm_reader *,
+                                         struct dictionary *,
+                                         struct text_record *,
+                                         struct variable **var, char **value);
+static void text_warn (struct sfm_reader *r, struct text_record *text,
+                       const char *format, ...)
+  PRINTF_FORMAT (3, 4);
+static char *text_get_token (struct text_record *,
+                             struct substring delimiters);
+static bool text_match (struct text_record *, char c);
+static bool text_read_short_name (struct sfm_reader *, struct dictionary *,
+                                  struct text_record *,
+                                  struct substring delimiters,
+                                  struct variable **);
 
 static bool close_reader (struct sfm_reader *r);
 \f
@@ -163,7 +174,12 @@ static void read_long_var_name_map (struct sfm_reader *,
 static void read_long_string_map (struct sfm_reader *,
                                   size_t size, size_t count,
                                   struct dictionary *);
-
+static void read_data_file_attributes (struct sfm_reader *,
+                                       size_t size, size_t count,
+                                       struct dictionary *);
+static void read_variable_attributes (struct sfm_reader *,
+                                      size_t size, size_t count,
+                                      struct dictionary *);
 
 /* Opens the system file designated by file handle FH for
    reading.  Reads the system file's dictionary into *DICT.
@@ -748,9 +764,12 @@ read_extension_record (struct sfm_reader *r, struct dictionary *dict,
       break;
 
     case 17:
-      /* Text field that defines variable attributes.  New in
-         SPSS 14. */
-      break;
+      read_data_file_attributes (r, size, count, dict);
+      return;
+
+    case 18:
+      read_variable_attributes (r, size, count, dict);
+      return;
 
     case 20:
       /* New in SPSS 16.  Contains a single string that describes
@@ -927,14 +946,12 @@ static void
 read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count,
                         struct dictionary *dict)
 {
-  struct variable_to_value_map *map;
+  struct text_record *text;
   struct variable *var;
   char *long_name;
-  int warning_cnt = 0;
 
-  map = open_variable_to_value_map (r, size * count);
-  while (read_variable_to_value_map (r, dict, map, &var, &long_name,
-                                     &warning_cnt))
+  text = open_text_record (r, size * count);
+  while (read_variable_to_value_pair (r, dict, text, &var, &long_name))
     {
       char **short_names;
       size_t short_name_cnt;
@@ -980,7 +997,7 @@ read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count,
         }
       free (short_names);
     }
-  close_variable_to_value_map (r, map);
+  close_text_record (r, text);
   r->has_long_var_names = true;
 }
 
@@ -990,14 +1007,12 @@ static void
 read_long_string_map (struct sfm_reader *r, size_t size, size_t count,
                       struct dictionary *dict)
 {
-  struct variable_to_value_map *map;
+  struct text_record *text;
   struct variable *var;
   char *length_s;
-  int warning_cnt = 0;
 
-  map = open_variable_to_value_map (r, size * count);
-  while (read_variable_to_value_map (r, dict, map, &var, &length_s,
-                                     &warning_cnt))
+  text = open_text_record (r, size * count);
+  while (read_variable_to_value_pair (r, dict, text, &var, &length_s))
     {
       size_t idx = var_get_dict_index (var);
       long int length;
@@ -1045,7 +1060,7 @@ read_long_string_map (struct sfm_reader *r, size_t size, size_t count,
       dict_delete_consecutive_vars (dict, idx + 1, segment_cnt - 1);
       var_set_width (var, length);
     }
-  close_variable_to_value_map (r, map);
+  close_text_record (r, text);
   dict_compact_values (dict);
 }
 
@@ -1183,6 +1198,96 @@ read_value_labels (struct sfm_reader *r,
 
   pool_destroy (subpool);
 }
+
+/* Reads a set of custom attributes from TEXT into ATTRS.
+   ATTRS may be a null pointer, in which case the attributes are
+   read but discarded. */
+static void
+read_attributes (struct sfm_reader *r, struct text_record *text,
+                 struct attrset *attrs)
+{
+  do
+    {
+      struct attribute *attr;
+      char *key;
+      int index;
+
+      /* Parse the key. */
+      key = text_get_token (text, ss_cstr ("("));
+      if (key == NULL)
+        return;
+
+      attr = attribute_create (key);
+      for (index = 1; ; index++)
+        {
+          /* Parse the value. */
+          char *value;
+          size_t length;
+
+          value = text_get_token (text, ss_cstr ("\n"));
+          if (value == NULL)
+            {
+              text_warn (r, text, _("Error parsing attribute value %s[%d]"),
+                         key, index);
+              break;
+            }              
+
+          length = strlen (value);
+          if (length >= 2 && value[0] == '\'' && value[length - 1] == '\'') 
+            {
+              value[length - 1] = '\0';
+              attribute_add_value (attr, value + 1); 
+            }
+          else 
+            {
+              text_warn (r, text,
+                         _("Attribute value %s[%d] is not quoted: %s"),
+                         key, index, value);
+              attribute_add_value (attr, value); 
+            }
+
+          /* Was this the last value for this attribute? */
+          if (text_match (text, ')'))
+            break;
+        }
+      if (attrs != NULL)
+        attrset_add (attrs, attr);
+      else
+        attribute_destroy (attr);
+    }
+  while (!text_match (text, '/'));
+}
+
+/* Reads record type 7, subtype 17, which lists custom
+   attributes on the data file.  */
+static void
+read_data_file_attributes (struct sfm_reader *r,
+                           size_t size, size_t count,
+                           struct dictionary *dict)
+{
+  struct text_record *text = open_text_record (r, size * count);
+  read_attributes (r, text, dict_get_attributes (dict));
+  close_text_record (r, text);
+}
+
+/* Reads record type 7, subtype 18, which lists custom
+   attributes on individual variables.  */
+static void
+read_variable_attributes (struct sfm_reader *r,
+                          size_t size, size_t count,
+                          struct dictionary *dict)
+{
+  struct text_record *text = open_text_record (r, size * count);
+  for (;;) 
+    {
+      struct variable *var;
+      if (!text_read_short_name (r, dict, text, ss_cstr (":"), &var))
+        break;
+      read_attributes (r, text, var != NULL ? var_get_attributes (var) : NULL);
+    }
+  close_text_record (r, text);
+}
+
 \f
 /* Case reader. */
 
@@ -1518,82 +1623,124 @@ lookup_var_by_short_name (struct dictionary *d, const char *short_name)
   return NULL;
 }
 \f
-/* Helpers for reading records that contain "variable=value"
-   pairs. */
+/* Helpers for reading records that contain structured text
+   strings. */
+
+/* Maximum number of warnings to issue for a single text
+   record. */
+#define MAX_TEXT_WARNINGS 5
 
 /* State. */
-struct variable_to_value_map
+struct text_record
   {
     struct substring buffer;    /* Record contents. */
     size_t pos;                 /* Current position in buffer. */
+    int n_warnings;             /* Number of warnings issued or suppressed. */
   };
 
-/* Reads SIZE bytes into a "variable=value" map for R,
-   and returns the map. */
-static struct variable_to_value_map *
-open_variable_to_value_map (struct sfm_reader *r, size_t size)
+/* Reads SIZE bytes into a text record for R,
+   and returns the new text record. */
+static struct text_record *
+open_text_record (struct sfm_reader *r, size_t size)
 {
-  struct variable_to_value_map *map = pool_alloc (r->pool, sizeof *map);
+  struct text_record *text = pool_alloc (r->pool, sizeof *text);
   char *buffer = pool_malloc (r->pool, size + 1);
   read_bytes (r, buffer, size);
-  map->buffer = ss_buffer (buffer, size);
-  map->pos = 0;
-  return map;
+  text->buffer = ss_buffer (buffer, size);
+  text->pos = 0;
+  text->n_warnings = 0;
+  return text;
 }
 
-/* Closes MAP and frees its storage.
-   Not really needed, because the pool will free the map anyway,
-   but can be used to free it earlier. */
+/* Closes TEXT, frees its storage, and issues a final warning
+   about suppressed warnings if necesary. */
 static void
-close_variable_to_value_map (struct sfm_reader *r,
-                             struct variable_to_value_map *map)
+close_text_record (struct sfm_reader *r, struct text_record *text)
 {
-  pool_free (r->pool, ss_data (map->buffer));
+  if (text->n_warnings > MAX_TEXT_WARNINGS)
+    sys_warn (r, _("Suppressed %d additional related warnings."),
+              text->n_warnings - MAX_TEXT_WARNINGS);
+  pool_free (r->pool, ss_data (text->buffer));
 }
 
-/* Reads the next variable=value pair from MAP.
+/* Reads a variable=value pair from TEXT.
    Looks up the variable in DICT and stores it into *VAR.
    Stores a null-terminated value into *VALUE. */
 static bool
-read_variable_to_value_map (struct sfm_reader *r, struct dictionary *dict,
-                            struct variable_to_value_map *map,
-                            struct variable **var, char **value,
-                            int *warning_cnt)
+read_variable_to_value_pair (struct sfm_reader *r, struct dictionary *dict,
+                             struct text_record *text,
+                             struct variable **var, char **value)
 {
-  int max_warnings = 5;
-
   for (;;)
     {
-      struct substring short_name_ss, value_ss;
+      if (!text_read_short_name (r, dict, text, ss_cstr ("="), var))
+        return false;
+      
+      *value = text_get_token (text, ss_buffer ("\t\0", 2));
+      if (*value == NULL)
+        return false;
 
-      if (!ss_tokenize (map->buffer, ss_cstr ("="), &map->pos, &short_name_ss)
-          || !ss_tokenize (map->buffer, ss_buffer ("\t\0", 2), &map->pos,
-                           &value_ss))
-        {
-          if (*warning_cnt > max_warnings)
-            sys_warn (r, _("Suppressed %d additional variable map warnings."),
-                      *warning_cnt - max_warnings);
-          return false;
-        }
+      text->pos += ss_span (ss_substr (text->buffer, text->pos, SIZE_MAX),
+                            ss_buffer ("\t\0", 2));
 
-      map->pos += ss_span (ss_substr (map->buffer, map->pos, SIZE_MAX),
-                           ss_buffer ("\t\0", 2));
+      if (*var != NULL)
+        return true;
+    }
+}
 
-      ss_data (short_name_ss)[ss_length (short_name_ss)] = '\0';
-      *var = lookup_var_by_short_name (dict, ss_data (short_name_ss));
-      if (*var == NULL)
-        {
-          if (++*warning_cnt <= max_warnings)
-            sys_warn (r, _("Variable map refers to unknown variable %s."),
-                      ss_data (short_name_ss));
-          continue;
-        }
+static bool
+text_read_short_name (struct sfm_reader *r, struct dictionary *dict,
+                      struct text_record *text, struct substring delimiters,
+                      struct variable **var)
+{
+  char *short_name = text_get_token (text, delimiters);
+  if (short_name == NULL)
+    return false;
 
-      ss_data (value_ss)[ss_length (value_ss)] = '\0';
-      *value = ss_data (value_ss);
+  *var = lookup_var_by_short_name (dict, short_name);
+  if (*var == NULL)
+    text_warn (r, text, _("Variable map refers to unknown variable %s."),
+               short_name);
+  return true;
+}
+
+/* Displays a warning for the current file position, limiting the
+   number to MAX_TEXT_WARNINGS for TEXT. */
+static void
+text_warn (struct sfm_reader *r, struct text_record *text,
+           const char *format, ...)
+{
+  if (text->n_warnings++ < MAX_TEXT_WARNINGS) 
+    {
+      va_list args;
 
+      va_start (args, format);
+      sys_msg (r, MW, format, args);
+      va_end (args);
+    }
+}
+
+static char *
+text_get_token (struct text_record *text, struct substring delimiters)
+{
+  struct substring token;
+
+  if (!ss_tokenize (text->buffer, delimiters, &text->pos, &token))
+    return NULL;
+  ss_data (token)[ss_length (token)] = '\0';
+  return ss_data (token);
+}
+
+static bool
+text_match (struct text_record *text, char c)
+{
+  if (text->buffer.string[text->pos] == c) 
+    {
+      text->pos++;
       return true;
     }
+  else
+    return false;
 }
 \f
 /* Messages. */
index 7804e5914f72d7ac49f06a1f8ccb1bd71aec48ce..aa539a51364fb6804aa1ddfc2b14d2ee545ebbc3 100644 (file)
@@ -33,6 +33,7 @@
 #include <libpspp/str.h>
 #include <libpspp/version.h>
 
+#include <data/attributes.h>
 #include <data/case.h>
 #include <data/casewriter-provider.h>
 #include <data/casewriter.h>
@@ -111,6 +112,11 @@ static void write_variable_display_parameters (struct sfm_writer *w,
 
 static void write_documents (struct sfm_writer *, const struct dictionary *);
 
+static void write_data_file_attributes (struct sfm_writer *,
+                                        const struct dictionary *);
+static void write_variable_attributes (struct sfm_writer *,
+                                       const struct dictionary *);
+
 static void write_int (struct sfm_writer *, int32_t);
 static inline void convert_double_to_output_format (double, uint8_t[8]);
 static void write_float (struct sfm_writer *, double);
@@ -235,6 +241,10 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d,
 
   write_vls_length_table (w, d);
 
+  if (attrset_count (dict_get_attributes (d)))
+    write_data_file_attributes (w, d);
+  write_variable_attributes (w, d);
+
   /* Write end-of-headers record. */
   write_int (w, 999);
   write_int (w, 0);
@@ -520,6 +530,72 @@ write_documents (struct sfm_writer *w, const struct dictionary *d)
   write_bytes (w, dict_get_documents (d), line_cnt * DOC_LINE_LENGTH);
 }
 
+static void
+put_attrset (struct string *string, const struct attrset *attrs)
+{
+  const struct attribute *attr;
+  struct attrset_iterator i;
+
+  for (attr = attrset_first (attrs, &i); attr != NULL;
+       attr = attrset_next (attrs, &i)) 
+    {
+      size_t n_values = attribute_get_n_values (attr);
+      size_t j;
+
+      ds_put_cstr (string, attribute_get_name (attr));
+      ds_put_char (string, '(');
+      for (j = 0; j < n_values; j++) 
+        ds_put_format (string, "'%s'\n", attribute_get_value (attr, j));
+      ds_put_char (string, ')');
+    }
+}
+
+static void
+write_attribute_record (struct sfm_writer *w, const struct string *content,
+                        int subtype) 
+{
+  write_int (w, 7);
+  write_int (w, subtype);
+  write_int (w, 1);
+  write_int (w, ds_length (content));
+  write_bytes (w, ds_data (content), ds_length (content));
+}
+
+static void
+write_data_file_attributes (struct sfm_writer *w,
+                            const struct dictionary *d)
+{
+  struct string s = DS_EMPTY_INITIALIZER;
+  put_attrset (&s, dict_get_attributes (d));
+  write_attribute_record (w, &s, 17);
+  ds_destroy (&s);
+}
+
+static void
+write_variable_attributes (struct sfm_writer *w, const struct dictionary *d)
+{
+  struct string s = DS_EMPTY_INITIALIZER;
+  size_t n_vars = dict_get_var_cnt (d);
+  size_t n_attrsets = 0;
+  size_t i;
+
+  for (i = 0; i < n_vars; i++)
+    { 
+      struct variable *v = dict_get_var (d, i);
+      struct attrset *attrs = var_get_attributes (v);
+      if (attrset_count (attrs)) 
+        {
+          if (n_attrsets++)
+            ds_put_char (&s, '/');
+          ds_put_format (&s, "%s:", var_get_short_name (v, 0));
+          put_attrset (&s, attrs);
+        }
+    }
+  if (n_attrsets) 
+    write_attribute_record (w, &s, 18);
+  ds_destroy (&s);
+}
+
 /* Write the alignment, width and scale values. */
 static void
 write_variable_display_parameters (struct sfm_writer *w,
index 49555d9a4ea3b11ce15149ebdca388722af6dcb4..9fcf1cbb9b8fa0a97cb4e75544a9a6892879ab68 100644 (file)
@@ -20,6 +20,7 @@
 #include <data/val-type.h>
 #include <libpspp/hash.h>
 #include <libpspp/str.h>
+#include "variable.h"
 
 #include "xalloc.h"
 
@@ -46,8 +47,12 @@ value_create (int width)
    Only the short string portion of longer strings are
    compared. */
 int
-compare_values (const union value *a, const union value *b, int width)
+compare_values (const void *a_, const void *b_, const void *var_)
 {
+  const union value *a = a_;
+  const union value *b = b_;
+  const struct variable *var = var_;
+  int width = var_get_width (var);
   return (width == 0
           ? (a->f < b->f ? -1 : a->f > b->f)
           : memcmp (a->s, b->s, MIN (MAX_SHORT_STRING, width)));
@@ -56,24 +61,14 @@ compare_values (const union value *a, const union value *b, int width)
 /* Create a hash of V, which has the given WIDTH.
    Only the short string portion of a longer string is hashed. */
 unsigned
-hash_value (const union value *v, int width)
+hash_value (const void *v_, const void *var_)
 {
+  const union value *v = v_;
+  const struct variable *var = var_;
+  int width = var_get_width (var);
   return (width == 0
           ? hsh_hash_double (v->f)
-          : hsh_hash_bytes (v->s, MIN (MAX_SHORT_STRING, width)));
-}
-
-
-int
-compare_ptr_values (const union value **v1, const union value **v2, int width)
-{
-  return compare_values (*v1, *v2, width);
-}
-
-unsigned
-hash_ptr_value (const union value **v, int width)
-{
-  return hash_value (*v, width);
+         : hsh_hash_bytes (v->s, width));
 }
 
 
index 4554a36617eb589153dc7244f19b3edf74c0bbd7..9103c6b317fe8f1939767a78236a83f94924c148 100644 (file)
@@ -39,12 +39,8 @@ union value
 union value *value_dup (const union value *, int width);
 union value *value_create (int width);
 
-int compare_values (const union value *, const union value *, int width);
-unsigned hash_value (const union value *, int width);
-
-int compare_ptr_values (const union value **, const union value **, int width);
-unsigned hash_ptr_value (const union value **, int width);
-
+int compare_values (const void *, const void *, const void *var);
+unsigned hash_value (const void *, const void *var);
 
 static inline size_t value_cnt_from_width (int width);
 void value_copy (union value *, const union value *, int width);
index a455e40a1f5bd72d025d30d941460d91ded5dc2a..d14237d925c3442e4baa8bbf9204a09044f41818 100644 (file)
 
 #include <stdlib.h>
 
-#include "category.h"
-#include "data-out.h"
-#include "format.h"
-#include "dictionary.h"
-#include "identifier.h"
-#include "missing-values.h"
-#include "value-labels.h"
-#include "vardict.h"
+#include <data/attributes.h>
+#include <data/category.h>
+#include <data/data-out.h>
+#include <data/format.h>
+#include <data/dictionary.h>
+#include <data/identifier.h>
+#include <data/missing-values.h>
+#include <data/value-labels.h>
+#include <data/vardict.h>
 
 #include <libpspp/misc.h>
 #include <libpspp/assertion.h>
@@ -76,6 +77,9 @@ struct variable
        vectors with binary entries, so any variable of type ALPHA will
        have its values stored here. */
     struct cat_vals *obs_vals;
+
+    /* Custom attributes. */
+    struct attrset attributes;
   };
 \f
 /* Creates and returns a new variable with the given NAME and
@@ -108,6 +112,7 @@ var_create (const char *name, int width)
   v->aux = NULL;
   v->aux_dtor = NULL;
   v->obs_vals = NULL;
+  attrset_init (&v->attributes);
 
   return v;
 }
@@ -138,10 +143,28 @@ var_clone (const struct variable *old_var)
   var_set_display_width (new_var, var_get_display_width (old_var));
   var_set_alignment (new_var, var_get_alignment (old_var));
   var_set_leave (new_var, var_get_leave (old_var));
+  var_set_attributes (new_var, var_get_attributes (old_var));
 
   return new_var;
 }
 
+/* Create a variable to be used for internal calculations only */
+struct variable *
+var_create_internal (int case_idx)
+{
+  struct variable *v = var_create ("$internal", 0);
+
+  struct vardict_info vdi;
+
+  vdi.dict = NULL;
+  vdi.dict_index = 0;
+  vdi.case_index = case_idx;
+
+  var_set_vardict (v, &vdi);
+
+  return v;
+}
+
 /* Destroys variable V.
    V must not belong to a dictionary.  If it does, use
    dict_delete_var instead. */
@@ -150,7 +173,11 @@ var_destroy (struct variable *v)
 {
   if (v != NULL)
     {
-      assert (!var_has_vardict (v));
+      if (var_has_vardict (v))
+       {
+         const struct vardict_info *vdi = var_get_vardict (v);
+         assert (vdi->dict == NULL);
+       }
       cat_stored_values_destroy (v->obs_vals);
       var_clear_short_names (v);
       var_clear_aux (v);
@@ -307,6 +334,20 @@ compare_var_ptrs_by_name (const void *a_, const void *b_,
   return strcasecmp (var_get_name (*a), var_get_name (*b));
 }
 
+/* A hsh_compare_func that orders pointers to variables A and B
+   by their dictionary indexes. */
+int
+compare_var_ptrs_by_dict_index (const void *a_, const void *b_,
+                                const void *aux UNUSED)
+{
+  struct variable *const *a = a_;
+  struct variable *const *b = b_;
+  size_t a_index = var_get_dict_index (*a);
+  size_t b_index = var_get_dict_index (*b);
+
+  return a_index < b_index ? -1 : a_index > b_index;
+}
+
 /* A hsh_hash_func that hashes pointer to variable V based on its
    name. */
 unsigned
@@ -578,7 +619,6 @@ var_append_value_name (const struct variable *v, const union value *value,
     ds_put_cstr (str, name);
 }
 \f
-\f
 /* Print and write formats. */
 
 /* Returns V's print format specification. */
@@ -1000,6 +1040,31 @@ var_has_obs_vals (const struct variable *v)
   return v->obs_vals != NULL;
 }
 \f
+/* Returns variable V's attribute set.  The caller may examine or
+   modify the attribute set, but must not destroy it.  Destroying
+   V, or calling var_set_attributes() on V, will also destroy its
+   attribute set. */
+struct attrset *
+var_get_attributes (const struct variable *v) 
+{
+  return (struct attrset *) &v->attributes;
+}
+
+/* Replaces variable V's attributes set by a copy of ATTRS. */
+void
+var_set_attributes (struct variable *v, const struct attrset *attrs) 
+{
+  attrset_destroy (&v->attributes);
+  attrset_clone (&v->attributes, attrs);
+}
+
+/* Returns true if V has any custom attributes, false if it has none. */
+bool
+var_has_attributes (const struct variable *v)
+{
+  return attrset_count (&v->attributes) > 0;
+}
+\f
 /* Returns V's vardict structure. */
 const struct vardict_info *
 var_get_vardict (const struct variable *v)
index c7f86aaf716896541de0909829e8039527627e47..ecfa6b765ec8447da8ce58f53506d77035cf2bec 100644 (file)
@@ -32,6 +32,8 @@ union value;
 struct variable *var_create (const char *name, int width);
 struct variable *var_clone (const struct variable *);
 void var_destroy (struct variable *);
+struct variable *var_create_internal (int case_idx);
+
 
 /* Variable names. */
 #define VAR_NAME_LEN 64 /* Maximum length of variable name, in bytes. */
@@ -48,6 +50,8 @@ unsigned hash_var_by_name (const void *, const void *);
 int compare_var_ptrs_by_name (const void *, const void *, const void *);
 unsigned hash_var_ptr_by_name (const void *, const void *);
 
+int compare_var_ptrs_by_dict_index (const void *, const void *, const void *);
+
 /* Types and widths of values associated with a variable. */
 enum val_type var_get_type (const struct variable *);
 int var_get_width (const struct variable *);
@@ -173,6 +177,11 @@ struct cat_vals *var_get_obs_vals (const struct variable *);
 void var_set_obs_vals (const struct variable *, struct cat_vals *);
 bool var_has_obs_vals (const struct variable *);
 
+/* Custom attributes. */
+struct attrset *var_get_attributes (const struct variable *);
+void var_set_attributes (struct variable *, const struct attrset *);
+bool var_has_attributes (const struct variable *);
+
 /* Function types. */
 typedef bool var_predicate_func (const struct variable *);
 
diff --git a/src/language/ChangeLog b/src/language/ChangeLog
deleted file mode 100644 (file)
index a32af12..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6441.  Reviewed by John Darrington.
-
-       * command.def: Add DEBUG FORMAT GUESSER command.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add GET DATA command.
-
-2007-11-05  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6258.  Reviewed by John Darrington.
-
-       * command.c (report_state_mismatch): Replace code to construct an
-       error message from bits and pieces by a switch statement that
-       hard-codes each possible error.  Makes i18n easier.
-       Suggested by Chusslove Illich <caslav.ilic@gmx.net>.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * command.def: Add DEBUG PAPER SIZE command.
-
-2007-09-05  John Darrington <john@darrington.wattle.id.au>
-
-       * command.c (do_parse_command): Translate CMD_FAILURE into
-       CMD_CASCADING_FAILURE, if the ERRMODE_STOP is set on the syntax
-       source. 
-       
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add DEBUG DATASHEET command.  Remove DEBUG CASEFILE
-       command.
-
-2007-03-18  Ben Pfaff  <blp@gnu.org>
-
-       * syntax-string-source.c (close): Rename to do_close to avoid
-       conflict with POSIX function of the same name.
-
-Thu Feb  8 15:04:42 2007  Ben Pfaff  <blp@gnu.org>
-
-       Reduce platform dependence.
-
-       * command.c (shell): Always define this function, instead of only
-       in unix, but make it a stub when fork or execl is not available.
-       (run_command): Move parsing code into cmd_host.
-       (cmd_host): Drop unix dependence now that the shell function is
-       always defined. 
-
-Sun Jan 21 15:31:52 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * command.c command.h: Renamed cmd_parse to cmd_parse_in_state.
-       New function cmd_parse.
-
-Wed Dec 13 21:02:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add DELETE VARS.
-
-Sat Dec 16 22:15:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make it possible to pull cases from the active file with a
-       function call, instead of requiring indirection through a callback
-       function.
-
-       * command.def: Marked MATRIX DATA as unimplemented.
-
-Sun Dec  3 11:59:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       * syntax-file.c (read_syntax_file): Always read GETL_BATCH lines.
-
-Wed Nov 29 19:35:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * command.c: Updated to reflect changed function names.
-
-       * line-buffer.c line-buffer.h: Removed.  Guts of it moved to
-       libpspp/getl.[ch] The rest moved to files listed below.
-
-       * syntax-file.c syntax-file.h prompt.c prompt.h: New files.
-
-Wed Nov 22 06:26:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: HOST command needs F_KEEP_FINAL_TOKEN.
-
-Sat Oct 28 16:15:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * linebuffer.c linebuffer.h: Moved getl_buf from here, into
-       lexer/lexer.c
-
-Thu Oct 26 20:19:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command.def: Add DEBUG FLOAT FORMAT.
-
-Fri Oct 20 10:59:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * command.def: Added additional unimpl commands.
-
-Sun Oct 15 19:38:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command.c: (do_parse_command) Issue an error for unimplemented
-       commands, instead of silently ignoring them.  Reported by John
-       Darrington.
-
-Wed Jun 28 11:38:23 2006  Ben Pfaff  <blp@gnu.org>
-
-       Don't offer both the full and abbreviated names for a single
-       command in command name completion.
-       
-       * command.c: (enum flags) Add F_ABBREV flag.
-       (cmd_complete) Ignore command with F_ABBREV flag set.
-
-       * command.def: Add F_ABBREV to N, Q, SORT commands.
-
-Tue Jun 27 22:36:38 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix regression in command name completion reported by John
-       Darrington.  Now completion is again state-dependent and occurs
-       only on the first line of a command.
-       
-       * command.c (do_parse_command): Move reading the first token of
-       the command here, from execute_command and cmd_input_program.
-       Call set_completion_state and getl_set_prompt_style here.
-       (do_parse_command) Use in_correct_state instead of
-       verify_valid_command.
-       (verify_valid_command) Break into two new functions,
-       in_correct_state and report_state_mismatch.
-       (set_completion_state) New function.
-       (cmd_complete) New function.
-       [HAVE_READLINE] (pspp_attempted_completion_function) Removed.
-       [HAVE_READLINE] (command_generator) Removed.
-
-       * line-buffer.c: (struct getl_source) Change `interactive' member
-       signature to take enum getl_prompt_style instead of const char *.
-       (create_interactive_source) Ditto, for parameter type.
-       (getl_append_interactive) Ditto.
-       (read_line_from_source) Pass get_prompt_style() to interactive
-       function instead of get_prompt().
-       (get_prompt) Removed.
-       (get_prompt_style) New function.
-       
-Sat May  6 13:25:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, remove
-       PROCESS IF, which was deprecated anyway and can be easily
-       simulated with TEMPORARY followed by SELECT IF.
-
-       * command.def: Removed PROCESS IF.
-
-Mon May  1 18:17:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Further clean up the CMD_* command result codes.
-       
-       * command.c (cmd_result_is_valid): New function.
-       (cmd_result_is_success) Assert that argument is valid.  Simplified
-       check to one for a positive result.
-       (cmd_result_is_failure) Assert that argument is valid.  Simplified
-       check to one for a negative result.
-       (do_parse_command) Check that command's returned result is valid.
-
-       * command.h: (enum cmd_result) Renamed CMD_QUIT to CMD_FINISH and
-       updated all users.  Removed CMD_END_SUBLOOP in favor of new
-       CMD_PRIVATE_FIRST...CMD_PRIVATE_LAST range.  Changed failure codes
-       to have negative values.
-
-Mon May  1 15:56:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove vestiges of FILE TYPE support. 
-       
-       * command.def: Mark FILE TYPE, RECORD TYPE unimplemented.
-
-Wed Apr 26 21:13:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       CLEAR TRANSFORMATIONS is unsafe as implemented.  It's a fair
-       amount of work to implement it correctly, so make it
-       unimplemented.
-               
-       * command.c: (cmd_clear_transformations) Removed.
-
-       * command.def: Mark CLEAR TRANSFORMATIONS as unimplemented.
-
-Wed Apr 26 13:06:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       Work on readline completion.
-
-       * command.c: (pspp_completion_function) Removed.
-       (pspp_attempted_completion_function) New function.
-       (command_generator) New function.
-
-Wed Apr 26 13:04:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       Improve the way we handle the various parsing "states".  Until now
-       we've hard-coded the state transitions in the command definition
-       file, but that's error-prone and, worse, it's redundant--we can
-       figure out what state we're in anyhow.  We can cleanly handle
-       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
-       
-       * command.c: (cmd_result_is_success) New function.
-       (cmd_result_is_failure) New function.
-       (enum states) New enum.
-       (enum flags) New enum.
-       (struct command) Add states, flags members.  Remove transition,
-       skip_entire_name, debug members.  Renamed func member as function.
-       (macro DEFCMD) Removed.
-       (macro DBGCMD) Removed.
-       (macro SPCCMD) Removed.
-       (macro UNIMPL) Removed.
-       (macro DEF_CMD) New.
-       (macro UNIMPL_CMD) New.
-       (macro COMMAND_CNT) Changed to static const var, renamed
-       command_cnt.  Updated all references.
-       (FILE_TYPE_okay) Removed.
-       (cmd_parse) Rewrote in terms of do_parse_command().
-       (do_parse_command) New function.
-       (find_command) New function.
-       (unknown_command_error) Use struct string to simplify code.
-       (parse_command_name) Recognize comment command names.  Handle
-       flags.  Don't reject testing-mode-only commands here--let higher
-       level do it.
-       (verify_valid_command) New function.
-       (cmd_comment) New function.
-
-       * command.def: Completely rewritten and now sensibly organized.
-
-       * command.h: (enum STATE_*) Renamed CMD_STATE_*.
-       (CMD_*) Now "enum cmd_result".  Added CMD_QUIT.  New
-       CMD_END_SUBLOOP.  Removed CMD_TRAILING_GARBAGE, CMD_PART_SUCCESS,
-       CMD_PART_SUCCESS_MAYBE and replaced all references by CMD_FAILURE.
-       Added CMD_NOT_IMPLEMENTED.
-        (macro DEFCMD) Removed.
-       (macro DBGCMD) Removed.
-       (macro SPCCMD) Removed.
-       (macro UNIMPL) Removed.
-       (macro DEF_CMD) New.
-       (macro UNIMPL_CMD) New.
-
-Mon Apr  3 11:03:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       * list.q: (write_all_headers) Adapt to new html and output
-       internals.
-       (clean_up) Ditto.
-       (write_varname) Ditto.
-       (write_fallback_headers) Ditto.
-       (determine_layout) Ditto.
-       (list_cases) Ditto.
-       
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/OChangeLog b/src/language/OChangeLog
new file mode 100644 (file)
index 0000000..a32af12
--- /dev/null
@@ -0,0 +1,250 @@
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6441.  Reviewed by John Darrington.
+
+       * command.def: Add DEBUG FORMAT GUESSER command.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add GET DATA command.
+
+2007-11-05  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6258.  Reviewed by John Darrington.
+
+       * command.c (report_state_mismatch): Replace code to construct an
+       error message from bits and pieces by a switch statement that
+       hard-codes each possible error.  Makes i18n easier.
+       Suggested by Chusslove Illich <caslav.ilic@gmx.net>.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * command.def: Add DEBUG PAPER SIZE command.
+
+2007-09-05  John Darrington <john@darrington.wattle.id.au>
+
+       * command.c (do_parse_command): Translate CMD_FAILURE into
+       CMD_CASCADING_FAILURE, if the ERRMODE_STOP is set on the syntax
+       source. 
+       
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add DEBUG DATASHEET command.  Remove DEBUG CASEFILE
+       command.
+
+2007-03-18  Ben Pfaff  <blp@gnu.org>
+
+       * syntax-string-source.c (close): Rename to do_close to avoid
+       conflict with POSIX function of the same name.
+
+Thu Feb  8 15:04:42 2007  Ben Pfaff  <blp@gnu.org>
+
+       Reduce platform dependence.
+
+       * command.c (shell): Always define this function, instead of only
+       in unix, but make it a stub when fork or execl is not available.
+       (run_command): Move parsing code into cmd_host.
+       (cmd_host): Drop unix dependence now that the shell function is
+       always defined. 
+
+Sun Jan 21 15:31:52 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * command.c command.h: Renamed cmd_parse to cmd_parse_in_state.
+       New function cmd_parse.
+
+Wed Dec 13 21:02:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add DELETE VARS.
+
+Sat Dec 16 22:15:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make it possible to pull cases from the active file with a
+       function call, instead of requiring indirection through a callback
+       function.
+
+       * command.def: Marked MATRIX DATA as unimplemented.
+
+Sun Dec  3 11:59:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       * syntax-file.c (read_syntax_file): Always read GETL_BATCH lines.
+
+Wed Nov 29 19:35:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * command.c: Updated to reflect changed function names.
+
+       * line-buffer.c line-buffer.h: Removed.  Guts of it moved to
+       libpspp/getl.[ch] The rest moved to files listed below.
+
+       * syntax-file.c syntax-file.h prompt.c prompt.h: New files.
+
+Wed Nov 22 06:26:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: HOST command needs F_KEEP_FINAL_TOKEN.
+
+Sat Oct 28 16:15:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * linebuffer.c linebuffer.h: Moved getl_buf from here, into
+       lexer/lexer.c
+
+Thu Oct 26 20:19:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command.def: Add DEBUG FLOAT FORMAT.
+
+Fri Oct 20 10:59:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * command.def: Added additional unimpl commands.
+
+Sun Oct 15 19:38:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command.c: (do_parse_command) Issue an error for unimplemented
+       commands, instead of silently ignoring them.  Reported by John
+       Darrington.
+
+Wed Jun 28 11:38:23 2006  Ben Pfaff  <blp@gnu.org>
+
+       Don't offer both the full and abbreviated names for a single
+       command in command name completion.
+       
+       * command.c: (enum flags) Add F_ABBREV flag.
+       (cmd_complete) Ignore command with F_ABBREV flag set.
+
+       * command.def: Add F_ABBREV to N, Q, SORT commands.
+
+Tue Jun 27 22:36:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix regression in command name completion reported by John
+       Darrington.  Now completion is again state-dependent and occurs
+       only on the first line of a command.
+       
+       * command.c (do_parse_command): Move reading the first token of
+       the command here, from execute_command and cmd_input_program.
+       Call set_completion_state and getl_set_prompt_style here.
+       (do_parse_command) Use in_correct_state instead of
+       verify_valid_command.
+       (verify_valid_command) Break into two new functions,
+       in_correct_state and report_state_mismatch.
+       (set_completion_state) New function.
+       (cmd_complete) New function.
+       [HAVE_READLINE] (pspp_attempted_completion_function) Removed.
+       [HAVE_READLINE] (command_generator) Removed.
+
+       * line-buffer.c: (struct getl_source) Change `interactive' member
+       signature to take enum getl_prompt_style instead of const char *.
+       (create_interactive_source) Ditto, for parameter type.
+       (getl_append_interactive) Ditto.
+       (read_line_from_source) Pass get_prompt_style() to interactive
+       function instead of get_prompt().
+       (get_prompt) Removed.
+       (get_prompt_style) New function.
+       
+Sat May  6 13:25:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, remove
+       PROCESS IF, which was deprecated anyway and can be easily
+       simulated with TEMPORARY followed by SELECT IF.
+
+       * command.def: Removed PROCESS IF.
+
+Mon May  1 18:17:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Further clean up the CMD_* command result codes.
+       
+       * command.c (cmd_result_is_valid): New function.
+       (cmd_result_is_success) Assert that argument is valid.  Simplified
+       check to one for a positive result.
+       (cmd_result_is_failure) Assert that argument is valid.  Simplified
+       check to one for a negative result.
+       (do_parse_command) Check that command's returned result is valid.
+
+       * command.h: (enum cmd_result) Renamed CMD_QUIT to CMD_FINISH and
+       updated all users.  Removed CMD_END_SUBLOOP in favor of new
+       CMD_PRIVATE_FIRST...CMD_PRIVATE_LAST range.  Changed failure codes
+       to have negative values.
+
+Mon May  1 15:56:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove vestiges of FILE TYPE support. 
+       
+       * command.def: Mark FILE TYPE, RECORD TYPE unimplemented.
+
+Wed Apr 26 21:13:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       CLEAR TRANSFORMATIONS is unsafe as implemented.  It's a fair
+       amount of work to implement it correctly, so make it
+       unimplemented.
+               
+       * command.c: (cmd_clear_transformations) Removed.
+
+       * command.def: Mark CLEAR TRANSFORMATIONS as unimplemented.
+
+Wed Apr 26 13:06:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       Work on readline completion.
+
+       * command.c: (pspp_completion_function) Removed.
+       (pspp_attempted_completion_function) New function.
+       (command_generator) New function.
+
+Wed Apr 26 13:04:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       Improve the way we handle the various parsing "states".  Until now
+       we've hard-coded the state transitions in the command definition
+       file, but that's error-prone and, worse, it's redundant--we can
+       figure out what state we're in anyhow.  We can cleanly handle
+       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
+       
+       * command.c: (cmd_result_is_success) New function.
+       (cmd_result_is_failure) New function.
+       (enum states) New enum.
+       (enum flags) New enum.
+       (struct command) Add states, flags members.  Remove transition,
+       skip_entire_name, debug members.  Renamed func member as function.
+       (macro DEFCMD) Removed.
+       (macro DBGCMD) Removed.
+       (macro SPCCMD) Removed.
+       (macro UNIMPL) Removed.
+       (macro DEF_CMD) New.
+       (macro UNIMPL_CMD) New.
+       (macro COMMAND_CNT) Changed to static const var, renamed
+       command_cnt.  Updated all references.
+       (FILE_TYPE_okay) Removed.
+       (cmd_parse) Rewrote in terms of do_parse_command().
+       (do_parse_command) New function.
+       (find_command) New function.
+       (unknown_command_error) Use struct string to simplify code.
+       (parse_command_name) Recognize comment command names.  Handle
+       flags.  Don't reject testing-mode-only commands here--let higher
+       level do it.
+       (verify_valid_command) New function.
+       (cmd_comment) New function.
+
+       * command.def: Completely rewritten and now sensibly organized.
+
+       * command.h: (enum STATE_*) Renamed CMD_STATE_*.
+       (CMD_*) Now "enum cmd_result".  Added CMD_QUIT.  New
+       CMD_END_SUBLOOP.  Removed CMD_TRAILING_GARBAGE, CMD_PART_SUCCESS,
+       CMD_PART_SUCCESS_MAYBE and replaced all references by CMD_FAILURE.
+       Added CMD_NOT_IMPLEMENTED.
+        (macro DEFCMD) Removed.
+       (macro DBGCMD) Removed.
+       (macro SPCCMD) Removed.
+       (macro UNIMPL) Removed.
+       (macro DEF_CMD) New.
+       (macro UNIMPL_CMD) New.
+
+Mon Apr  3 11:03:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * list.q: (write_all_headers) Adapt to new html and output
+       internals.
+       (clean_up) Ditto.
+       (write_varname) Ditto.
+       (write_fallback_headers) Ditto.
+       (determine_layout) Ditto.
+       (list_cases) Ditto.
+       
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 4b467dedda05ca3d96e93f282b90710b8f53f2bd..a62351630006b508238ddb28b8bea2fb77c878cb 100644 (file)
@@ -10,9 +10,14 @@ include $(top_srcdir)/src/language/stats/automake.mk
 include $(top_srcdir)/src/language/data-io/automake.mk
 include $(top_srcdir)/src/language/expressions/automake.mk
 
-noinst_LIBRARIES += src/language/liblanguage.a
+noinst_LTLIBRARIES +=  src/language/liblanguage.la
 
-src_language_liblanguage_a_SOURCES = \
+
+src_language_liblanguage_la_LIBADD = \
+       lib/misc/libmisc.la \
+       src/output/charts/libcharts.la
+
+src_language_liblanguage_la_SOURCES = \
        src/language/syntax-file.c \
        src/language/syntax-file.h \
        src/language/syntax-string-source.c \
@@ -33,10 +38,11 @@ src_language_liblanguage_a_SOURCES = \
        $(language_expressions_sources)
 
 
-
-nodist_src_language_liblanguage_a_SOURCES = \
+nodist_src_language_liblanguage_la_SOURCES = \
        $(src_language_data_io_built_sources) \
        $(src_language_utilities_built_sources) \
        $(src_language_stats_built_sources)  \
        $(language_tests_built_sources) \
        $(expressions_built_sources)
+
+EXTRA_DIST += src/language/OChangeLog
index 77eb3a3a7a7ea2e5e666220d1cefac0d56354bb7..442234d9bd9d6678fb38aab64cdd377a636a1051 100644 (file)
@@ -53,6 +53,7 @@ DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "ADD DOCUMENT", cmd_add_documents)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "APPLY DICTIONARY", cmd_apply_dictionary)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "BREAK", cmd_break)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "COMPUTE", cmd_compute)
+DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "DATAFILE ATTRIBUTE", cmd_datafile_attribute)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "DISPLAY", cmd_display)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, F_KEEP_FINAL_TOKEN, "DOCUMENT", cmd_document)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "DO IF", cmd_do_if)
@@ -79,6 +80,7 @@ DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "SPLIT FILE", cmd_split_file)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "STRING", cmd_string)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VALUE LABELS", cmd_value_labels)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VARIABLE ALIGNMENT", cmd_variable_alignment)
+DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VARIABLE ATTRIBUTE", cmd_variable_attribute)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VARIABLE LABELS", cmd_variable_labels)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VARIABLE LEVEL", cmd_variable_level)
 DEF_CMD (S_DATA | S_INPUT_PROGRAM, 0, "VARIABLE WIDTH", cmd_variable_width)
@@ -113,6 +115,7 @@ DEF_CMD (S_DATA, 0, "ONEWAY", cmd_oneway)
 DEF_CMD (S_DATA, 0, "PEARSON CORRELATIONS", cmd_correlations)
 DEF_CMD (S_DATA, 0, "RANK", cmd_rank)
 DEF_CMD (S_DATA, 0, "REGRESSION", cmd_regression)
+DEF_CMD (S_DATA, 0, "RELIABILITY", cmd_reliability)
 DEF_CMD (S_DATA, 0, "RENAME VARIABLES", cmd_rename_variables)
 DEF_CMD (S_DATA, 0, "SAMPLE", cmd_sample)
 DEF_CMD (S_DATA, 0, "SAVE", cmd_save)
@@ -164,7 +167,6 @@ UNIMPL_CMD ("CSSELECT", "Select complex samples")
 UNIMPL_CMD ("CSTABULATE", "Tabulate complex samples")
 UNIMPL_CMD ("CTABLES", "Display complex samples")
 UNIMPL_CMD ("CURVEFIT", "Fit curve to line plot")
-UNIMPL_CMD ("DATAFILE ATTRIBUTE", "User defined datafile attributes")
 UNIMPL_CMD ("DATASET", "Alternate data set")
 UNIMPL_CMD ("DATE", "Create time series data")
 UNIMPL_CMD ("DEFINE", "Syntax macros")
@@ -231,7 +233,6 @@ UNIMPL_CMD ("RATIO STATISTICS", "Descriptives of ratios")
 UNIMPL_CMD ("READ MODEL", "Read new model")
 UNIMPL_CMD ("RECORD TYPE", "Defines a type of record within FILE TYPE")
 UNIMPL_CMD ("REFORMAT", "Read obsolete files")
-UNIMPL_CMD ("RELIABILITY", "Reliability estimates")
 UNIMPL_CMD ("REPEATING DATA", "Specify multiple cases per input record")
 UNIMPL_CMD ("REPORT", "Pretty print working file")
 UNIMPL_CMD ("RESTORE", "Restore settings")
diff --git a/src/language/control/ChangeLog b/src/language/control/ChangeLog
deleted file mode 100644 (file)
index 3421bdf..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-       
-       * loop.c (loop_trns_proc): Use gsl_finite instead of finite, , as
-       a stopgap measure for portability until appropriate gnulib modules
-       are available.
-
-2007-09-23  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21111.  Reviewed by John Darrington.
-
-       * do-if.c: Fix ELSE and ELSE IF clauses.
-       (add_clause): Drop TARGET_INDEX argument and figure out the target
-       of the jump on our own.  The caller couldn't compensate for the
-       inserted BREAK transformation.  Updated all callers.
-
-Fri Feb  2 22:41:43 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * repeat.c (parse_numbers): Fixed bug parseing ranges vs. lists.
-       Ensured that floats are accepted in lists, but not in ranges.
-
-Tue Dec 19 08:12:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix LOOP.  Thanks to Daniel Williams
-       <Daniel.E.Williams@state.or.us> for reporting one of the bugs
-       fixed here.
-       
-       * loop.c (cmd_loop): Keep track of whether we created the index
-       variable and delete it if parsing fails, instead of creating it
-       after parsing the IF clause.  This allows the index variable to be
-       used in the IF clause.  This incidentally fixes a segfault when no
-       index variable was used.  Also, return CMD_CASCADING_FAILURE if we
-       fail.
-       (parse_if_clause): Don't allow more than one IF clause.
-       (parse_index_clause): Don't allow more than one index clause.
-       Create the index variable if it doesn't exist.
-       (end_loop_trns_proc): Invert the sense of END LOOP's IF clause.
-
-Sat Dec  9 20:12:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * repeat.c (parse_lines): Issue an error when attempting to nest
-       DO REPEAT in compatibility mode.
-
-Sat Dec  2 17:01:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       Significant cleanup to DO REPEAT.
-       
-       * repeat.c: (struct line_list) Rename struct repeat_line.  Use
-       struct ll instead of explicit "next" pointer.  Make "file_name"
-       const.  Change "const char *line" to "struct substring text".  Add
-       `syntax' member.  Update all references.
-       (enum repeat_entry_type) Rename repeat_macro_type, update all
-       references.
-       (struct repeat_entry) Rename struct repeat_macro.  Use struct ll
-       instead of explicit "next" pointer.  Change "char[] id" to "struct
-       substring name".  Change "char **replacement" to "struct substring
-       *replacements".  Update all references.
-       (struct repeat_block) Use struct ll_list for lists of lines,
-       macros.  Change "cur_line" to struct ll *.
-       (cmd_do_repeat) Don't bother adding an empty getl source at all.
-       This saves special-casing an empty source in repeat_read.
-       (parse_specification) Use new find_macro function.
-       (find_macro) New function.
-       (skip_indentor) Removed.
-       (recognize_keyword) Change interface, update callers.
-       (recognize_do_repeat) Ditto.
-       (recognize_end_repeat) Ditto.
-       (parse_lines) Use lex_preprocess_line to preprocess the input line
-       to check for DO REPEAT and END REPEAT, instead of coding it
-       inline.
-       (parse_ids) Need to make a copy of the array parsed by
-       parse_mixed_vars_pool, instead of using it verbatim, because we're
-       using struct substring now.
-       (add_replacement) Use struct substring in interface, instead of
-       const char *, and update all callers.
-       (find_substitution) Rewrite using substring, in terms of
-       find_macro.
-       (do_repeat_filter) Use struct substring to simplify code.
-       (current_line) New function.
-       
-Sat Dec  2 16:40:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix lack of ->name and ->location in DO REPEAT's getl_interface.
-       See bug #15702.
-
-       * repeat.c: (cmd_do_repeat) Initialize name, location in
-       getl_interface.
-       (do_repeat_read) Adjust semantics of cur_line so that, after the
-       call, it points to the line just returned, instead of to the next
-       line to be returned.  Thus, do_repeat_name and do_repeat_location
-       can use cur_line to obtain the info they need.
-       (do_repeat_name) New function.
-       (do_repeat_location) New function.
-
-Thu Nov 30 22:01:27 2006  Ben Pfaff  <blp@gnu.org>
-
-       * repeat.c (do_repeat_read): Properly handle empty DO REPEAT...END
-       REPEAT block.  Fixes bug #18407.  Thanks to John Darrington for
-       reporting this bug.
-
-Sat Oct 28 16:18:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * repeat.c: Eliminated references to extern variable getl_buf.
-
-Sun May  7 18:18:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix memory leaks.
-       
-       * repeat.c: (parse_ids) Take pool parameter and allocate all
-       memory from pool.  Reduce implementation from loop to single call
-       to parse_mixed_vars_pool().
-       (store_numeric) Removed.
-       (add_replacement) New function.
-       (parse_numbers) Take pool parameter and allocate all memory from
-       pool.  Require ranges to be in increasing order.
-       (parse_strings) Take pool parameter and allocate all memory from
-       pool.
-
-Wed May  3 22:45:41 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * do-if.c: (cmd_do_if) Use finalizer to ensure control stack gets
-       cleared.
-       (do_if_finalize_func) New function.
-
-       * loop.c: (create_loop_trns) Use finalizer to ensure control stack gets
-       cleared.
-       (loop_trns_finalize) New function.
-
-       * temporary.c: (global var temporary) Removed.  Changed references
-       to use proc_make_temporary_transformations_permanent() or
-       proc_in_temporary_transformations().
-       (global var temp_dict) Removed.
-       (global var temp_trns) Removed.
-       (cmd_temporary) Reimplement in terms of
-       proc_in_temporary_transformations() and
-       proc_start_temporary_transformations().
-       (cancel_temporary) Moved to procedure.c, renamed
-       proc_cancel_temporary_transformations().
-               
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/control/OChangeLog b/src/language/control/OChangeLog
new file mode 100644 (file)
index 0000000..3421bdf
--- /dev/null
@@ -0,0 +1,149 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+       
+       * loop.c (loop_trns_proc): Use gsl_finite instead of finite, , as
+       a stopgap measure for portability until appropriate gnulib modules
+       are available.
+
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+
+       * do-if.c: Fix ELSE and ELSE IF clauses.
+       (add_clause): Drop TARGET_INDEX argument and figure out the target
+       of the jump on our own.  The caller couldn't compensate for the
+       inserted BREAK transformation.  Updated all callers.
+
+Fri Feb  2 22:41:43 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * repeat.c (parse_numbers): Fixed bug parseing ranges vs. lists.
+       Ensured that floats are accepted in lists, but not in ranges.
+
+Tue Dec 19 08:12:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix LOOP.  Thanks to Daniel Williams
+       <Daniel.E.Williams@state.or.us> for reporting one of the bugs
+       fixed here.
+       
+       * loop.c (cmd_loop): Keep track of whether we created the index
+       variable and delete it if parsing fails, instead of creating it
+       after parsing the IF clause.  This allows the index variable to be
+       used in the IF clause.  This incidentally fixes a segfault when no
+       index variable was used.  Also, return CMD_CASCADING_FAILURE if we
+       fail.
+       (parse_if_clause): Don't allow more than one IF clause.
+       (parse_index_clause): Don't allow more than one index clause.
+       Create the index variable if it doesn't exist.
+       (end_loop_trns_proc): Invert the sense of END LOOP's IF clause.
+
+Sat Dec  9 20:12:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * repeat.c (parse_lines): Issue an error when attempting to nest
+       DO REPEAT in compatibility mode.
+
+Sat Dec  2 17:01:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       Significant cleanup to DO REPEAT.
+       
+       * repeat.c: (struct line_list) Rename struct repeat_line.  Use
+       struct ll instead of explicit "next" pointer.  Make "file_name"
+       const.  Change "const char *line" to "struct substring text".  Add
+       `syntax' member.  Update all references.
+       (enum repeat_entry_type) Rename repeat_macro_type, update all
+       references.
+       (struct repeat_entry) Rename struct repeat_macro.  Use struct ll
+       instead of explicit "next" pointer.  Change "char[] id" to "struct
+       substring name".  Change "char **replacement" to "struct substring
+       *replacements".  Update all references.
+       (struct repeat_block) Use struct ll_list for lists of lines,
+       macros.  Change "cur_line" to struct ll *.
+       (cmd_do_repeat) Don't bother adding an empty getl source at all.
+       This saves special-casing an empty source in repeat_read.
+       (parse_specification) Use new find_macro function.
+       (find_macro) New function.
+       (skip_indentor) Removed.
+       (recognize_keyword) Change interface, update callers.
+       (recognize_do_repeat) Ditto.
+       (recognize_end_repeat) Ditto.
+       (parse_lines) Use lex_preprocess_line to preprocess the input line
+       to check for DO REPEAT and END REPEAT, instead of coding it
+       inline.
+       (parse_ids) Need to make a copy of the array parsed by
+       parse_mixed_vars_pool, instead of using it verbatim, because we're
+       using struct substring now.
+       (add_replacement) Use struct substring in interface, instead of
+       const char *, and update all callers.
+       (find_substitution) Rewrite using substring, in terms of
+       find_macro.
+       (do_repeat_filter) Use struct substring to simplify code.
+       (current_line) New function.
+       
+Sat Dec  2 16:40:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix lack of ->name and ->location in DO REPEAT's getl_interface.
+       See bug #15702.
+
+       * repeat.c: (cmd_do_repeat) Initialize name, location in
+       getl_interface.
+       (do_repeat_read) Adjust semantics of cur_line so that, after the
+       call, it points to the line just returned, instead of to the next
+       line to be returned.  Thus, do_repeat_name and do_repeat_location
+       can use cur_line to obtain the info they need.
+       (do_repeat_name) New function.
+       (do_repeat_location) New function.
+
+Thu Nov 30 22:01:27 2006  Ben Pfaff  <blp@gnu.org>
+
+       * repeat.c (do_repeat_read): Properly handle empty DO REPEAT...END
+       REPEAT block.  Fixes bug #18407.  Thanks to John Darrington for
+       reporting this bug.
+
+Sat Oct 28 16:18:48 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * repeat.c: Eliminated references to extern variable getl_buf.
+
+Sun May  7 18:18:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix memory leaks.
+       
+       * repeat.c: (parse_ids) Take pool parameter and allocate all
+       memory from pool.  Reduce implementation from loop to single call
+       to parse_mixed_vars_pool().
+       (store_numeric) Removed.
+       (add_replacement) New function.
+       (parse_numbers) Take pool parameter and allocate all memory from
+       pool.  Require ranges to be in increasing order.
+       (parse_strings) Take pool parameter and allocate all memory from
+       pool.
+
+Wed May  3 22:45:41 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * do-if.c: (cmd_do_if) Use finalizer to ensure control stack gets
+       cleared.
+       (do_if_finalize_func) New function.
+
+       * loop.c: (create_loop_trns) Use finalizer to ensure control stack gets
+       cleared.
+       (loop_trns_finalize) New function.
+
+       * temporary.c: (global var temporary) Removed.  Changed references
+       to use proc_make_temporary_transformations_permanent() or
+       proc_in_temporary_transformations().
+       (global var temp_dict) Removed.
+       (global var temp_trns) Removed.
+       (cmd_temporary) Reimplement in terms of
+       proc_in_temporary_transformations() and
+       proc_start_temporary_transformations().
+       (cancel_temporary) Moved to procedure.c, renamed
+       proc_cancel_temporary_transformations().
+               
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 89ff7feeb69cafc9659e633ad3d4ea416b5c9181..e12813abdbb68eea3a2779f70f4e8a3df28b25f7 100644 (file)
@@ -10,3 +10,4 @@ language_control_sources = \
        src/language/control/repeat.c \
        src/language/control/repeat.h
 
+EXTRA_DIST += src/language/control/OChangeLog
index c6309d42186fa814428d5ca8cb5016ebe4ee6003..40a33c11bbafc451adddb40f9529356ed12c6776 100644 (file)
@@ -18,8 +18,6 @@
 
 #include "control-stack.h"
 
-#include <gsl/gsl_math.h>
-
 #include <data/case.h>
 #include <data/dictionary.h>
 #include <data/procedure.h>
@@ -323,8 +321,8 @@ loop_trns_proc (void *loop_, struct ccase *c, casenumber case_num)
       case_data_rw (c, loop->index_var)->f = loop->cur;
 
       /* Throw out pathological cases. */
-      if (!gsl_finite (loop->cur) || !gsl_finite (loop->by)
-          || !gsl_finite (loop->last)
+      if (!isfinite (loop->cur) || !isfinite (loop->by)
+          || !isfinite (loop->last)
           || loop->by == 0.0
           || (loop->by > 0.0 && loop->cur > loop->last)
           || (loop->by < 0.0 && loop->cur < loop->last))
diff --git a/src/language/data-io/ChangeLog b/src/language/data-io/ChangeLog
deleted file mode 100644 (file)
index 1eda1c0..0000000
+++ /dev/null
@@ -1,637 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-
-       * inpt-pgm.c (reread_trns_proc): Use gsl_finite instead of finite,
-       as a stopgap measure for portability until appropriate gnulib
-       modules are available.
-
-2008-02-06 John Darrington <john@darrington.wattle.id.au>
-
-       * get-data.c: Add a /BSIZE subcommand to PSQL reader.
-
-2008-02-02 John Darrington <john@darrington.wattle.id.au>
-
-       * get-data.c (cmd_get_data): Support PSQL type.
-
-2007-12-07  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6302.
-
-       * data-parser.c (data_parser_make_active_file): Fix case count
-       argument to casereader_create_sequential, which fixes data reading
-       in the GUI.
-       Provided by John Darrington.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       Move DATA LIST parsing into generic infrastructure, and generalize
-       it slightly.  Then, use the same infrastructure to implement GET
-       DATA/TYPE=TXT.
-
-       * data-parser.c: New file.
-
-       * data-parser.h: New file.
-
-       * data-list.c (struct dls_var_spec): Removed.
-       (ll_to_dls_var_spec): Removed.
-       (enum dls_type): Removed.
-       (struct data_list_pgm): Rename struct data_list_trns.  Remove
-       pool, specs, type, record_cnt, delims, skip_records, value_cnt
-       members.  Add new `parser' member.
-       (cmd_data_list): Use data-parser infrastructure.
-       (parse_fixed): Ditto.
-       (parse_free): Ditto.
-       (dump_fixed_table): Removed.
-       (dump_free_table): Removed.
-       (cut_field): Removed.
-       (read_from_data_list): Removed.
-       (read_from_data_list_fixed): Removed.
-       (read_from_data_list_free): Removed.
-       (read_from_data_list_list): Removed.
-       (data_list_trns_free): Rename arguments for clarity.
-       (data_list_trns_proc): Ditto.
-       (data_list_casereader_read): Removed.
-       (data_list_casereader_destroy): Removed.
-       (data_list_casereader_class): Removed.
-
-       * get-data.c (cmd_get_data): Support TXT type.
-       (set_type): New function.
-       (parse_get_txt): New function.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * placement-parser.c (parse_column): New function.
-       (parse_column_range): Add `base' argument.  Update all callers.
-       
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       Make GET DATA a separate command, instead of something invoked
-       indirectly from GET.
-
-       * automake.mk: Remove get-data.h from sources.
-
-       * get-data.h: Removed.
-
-       * get-data.c (parse_get_data_command): Rename cmd_get_data.
-
-       * get.c (parse_read_command): No longer any need to check for DATA
-       keyword.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * src/language/data-io/data-reader.c (struct dfm_reader): New
-       `file_size' member to support dfm_get_percent_read.
-       (dfm_open_reader): Initialize file_size.
-       (dfm_get_percent_read): New function.
-
-2007-11-08  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6256: add support for binary, 360 file formats.  Reviewed
-       by John Darrington.
-
-       * data-reader.c (struct dfm_reader): New member `block_left'.
-       (dfm_open_reader): Initialize block_left.  For FH_MODE_TEXT, open
-       the file in text mode.
-       (read_error): New function.
-       (partial_record): New function.
-       (try_to_read_fully): New function.
-       (enum descriptor_type): New enum.
-       (read_descriptor_word): New function.
-       (corrupt_size): New function.
-       (read_size): New function.
-       (read_file_record): Implement new modes.
-       (read_record): Now take care of tracking line numbers here.
-       (dfm_reader_get_legacy_encoding): New function.
-
-       * data-writer.c (dfm_put_record): Implement new modes.
-       (dfm_writer_get_legacy_encoding): New function.
-
-       * file-handle.q: Parse new formats.
-       (cmd_file_handle): Set up new formats.
-
-       * print.c (struct print_trns): New member `encoding'.
-       (internal_cmd_print): Set encoding.
-       (print_trns_proc): Recode output data if necessary.
-       (flush_records): Recode leader byte.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * data-list.c (cmd_data_list): Manage file handle reference
-       counts.
-
-       * data-reader.c (struct dfm_reader): Add `lock' member.
-       (dfm_close_reader): Simplify, as reference counting is now
-       separate from locking.
-       (dfm_open_reader): Lock file.
-
-       * data-writer.c (struct dfm_writer): Add fh_lock, replace_file
-       members.
-       (dfm_open_writer): Lock file and prepare for replacement.
-       (dfm_close_writer): Unlock file and replace it.
-
-       * file-handle.q (cmd_close_file_handle): Use fh_unname.
-       (fh_parse): Don't distinguish existing handles for a given file
-       name from new ones.  Manage file handle reference counts.
-
-       * get.c (parse_read_command): Manage file handle reference counts.
-       (parse_write_command): Ditto.
-       (mtf_close_all_files): Ditto.
-
-       * inpt-pgm.c (cmd_reread): Manage file handle reference counts.
-
-       * print-space.c (cmd_print_space): Manage file handle reference
-       counts.
-
-       * print.c (internal_cmd_print): Manage file handle reference
-       counts.
-
-2007-11-03 John Darrington <john@darrington.wattle.id.au>
-
-       * get.c: Add GET DATA command variant.
-
-       * get-data.c get-data.h (new files): Added support for
-        GET DATA /TYPE='gnm'  command.
-
-2007-09-23  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21111.  Reviewed by John Darrington.
-
-       * data-list.c (data_list_trns_proc): Properly set retval when END
-       subcommand is in use.
-       (cmd_data_list): Don't allow END subcommand to be used with DATA
-       LIST FREE or LIST.
-
-2007-09-12  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (get_translate_case): Change input case parameter from
-       const struct ccase * to struct ccase *, to match change in
-       casereader and casewriter translators.  Destroy input case, to fix
-       memory leak.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (parse_read_command): Compact the values in the target
-       dictionary, to save space.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (struct case_map): Move into new file src/data/case-map.c.
-       (start_case_map): Ditto, and rename case_map_prepare_dict.
-       (finish_case_map): Ditto, and rename case_map_from_dict.
-       (map_case): Ditto, and rename case_map_execute.
-       (destroy_case_map): Ditto, and rename case_map_destroy.
-       (case_map_get_value_cnt): Ditto.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (case_map_get_value_cnt): New function.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #17100.
-       * data-list.c (read_from_data_list_fixed): Handle multi-record
-       DATA LIST correctly.
-
-2007-07-11  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (map_case): Create destination case instead of leaving it
-       undefined.  Fixes bug #20285.
-       Reviewed by John Darrington.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: Essentially rewrite MATCH FILES to support FIRST and
-       LAST.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-       
-       * data-list.c: Make DATA LIST into a casereader.
-
-       * get.c: Change GET, IMPORT, SAVE, EXPORT to use casereaders,
-       casewriters.
-
-       * inpt-pgm.c: Use caseinit code.  Turn INPUT PROGRAM into a
-       casereader.
-
-       * list.q: Adapt to new procedure code.
-
-2007-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Abstract the documents within a dictionary a little better.
-       Thanks to John Darrington for suggestion, initial version, and
-       review.  Patch #5917.
-
-       * get.c (mtf_merge_dictionary): Simplify creating merged document.
-
-       * sys-file-info.c (display_documents): Use new
-       dict_get_document_line_cnt and dict_get_document_line functions.
-
-Thu Feb  1 16:56:02 2007  Ben Pfaff  <blp@gnu.org>
-
-       * file-handle.q (fh_parse): Update to new fh_create_file
-       prototype.
-
-Sat Dec 16 22:16:18 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make it possible to pull cases from the active file with a
-       function call, instead of requiring indirection through a callback
-       function.
-
-       * automake.mk: Removed matrix-data.c.
-
-       * matrix-data.c: Removed.
-
-       * data-list.c (data_list_source_read): Conform with new
-       case_source_class interface.
-       (data_list_source_destroy): Ditto.
-
-       * get.c (case_reader_source_class): Ditto.
-       (case_reader_source_destroy): Ditto.
-       (parse_output_proc): Take advantage of new procedure interface.
-       (output_proc): Removed.
-       (struct mtf_file): Add "struct ccase *" member to allow use of new
-       procedure interface.
-       (cmd_match_files): Take advantage of new procedure interface.
-       (mtf_processing_finish): Removed.
-       (mtf_read_nonactive_records): Renamed mtf_read_records.  Now reads
-       from every file, without any exception for the active file.
-       (mtf_compare_BY_values): Simplify for new interface.
-       (mtf_processing): Simplify for new interface.
-
-       * inpt-pgm.c (is_valid_state): New function.
-       (input_program_source_read): Conform with new case_source_class
-       interface.
-       (input_program_source_destroy): Ditto.
-       (end_case_trns_proc): Now just needs to return TRNS_END_CASE.
-
-Sat Dec  9 18:43:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * list.q (cmd_list): Use new var_create, var_destroy functions.
-
-Thu Nov 30 21:51:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * inpt-pgm.c (cmd_reread): Always return error code upon detecting
-       syntax error.  Fixes bug #18419.  Thanks to John Darrington for
-       reporting this bug.
-
-Sun Nov 19 09:17:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c (parse_free): Follow documented (but odd) rule that
-       N format is treated as F format for free-field input.
-       
-       * data-reader.c (read_file_record): Drop new-line character from
-       input text lines.  This is symmetrical with the recently changed
-       dfm_put_record semantics.
-
-Thu Nov  2 20:56:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       Implement SKIP keyword on DATA LIST.  Fixes bug #17099.
-       
-       * data-list.c: (struct data_list_pgm) Add `skip_records' members.
-       (cmd_data_list) Set skip_records based on user input.
-       (data_list_source_read) Skip records requested by user.
-
-Tue Oct 31 20:04:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * placement-parser.c: (PRS_TYPE_T) Now that struct fmt_spec uses
-       an enum fmt_type for its type member, we can't depend on the
-       ability to put negative values into that member as out-of-band
-       values, because enum fmt_type might be an unsigned type.  So use
-       values around SCHAR_MAX instead, because we know that SCHAR_MAX
-       will fit into any type, signed or unsigned, and there aren't
-       nearly that many format types.
-       (parse_var_placements) Add for_input parameter to specify whether
-       we're parsing input or output formats.  Update all callers.
-       (fixed_parse_columns) Ditto.
-       (fixed_parse_fortran) Ditto.
-       
-Tue Oct 31 18:21:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       * print-space.c (print_space_trns_proc): Let dfm_put_record add
-       the new-line character, to match dfm_put_record change below.
-
-Sat Oct 28 11:57:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-writer.c (struct dfm_writer): Removed `bounce' member, and
-       all references to it.
-       (dfm_put_record) Change semantics so that it adds formatting
-       itself, such as new-line characters, instead of putting that
-       responsibility on the caller.  Also, pad binary records with
-       spaces instead of zeros, for compatibility.
-
-       * print.c (struct prt_out_spec) New member `sysmis_as_spaces'.
-       (struct print_trns) Remove `omit_new_lines' and all references,
-       since dfm_put_record() is taking care of that.  Add
-       `include_prefix'.
-       (internal_cmd_print) Allow an empty set of data to print.  Set
-       include_prefix.
-       (parse_specs) Allow an empty set of data to print.
-       (parse_variable_argument) Only add space with PRINT command.  Set
-       sysmis_as_spaces.
-       (print_trns_proc) Indent records if include_prefix is set, for
-       compatibility.  Output SYSMIS as spaces if sysmis_as_spaces is
-       set.  Put "1" in first column if PRINT EJECT is used with an
-       external output file.
-       (flush_records) Ditto.
-
-Sat Oct 28 16:19:57 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-reader.c: Eliminated references to extern variable getl_buf
-
-Sat Aug  5 08:25:07 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #17329 in REREAD parsing, reported by John Darrington.
-
-       * inpt-pgm.c (cmd_reread): Fix file handle parsing.
-
-Mon Jul 31 10:32:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       * print.c (parse_specs): Allow a comma between specifications.
-
-Sun Jul 16 19:57:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: (src_language_data_io_libdata_io_a_SOURCE) Add
-       print-space.c, placement-parser.c, placement-parser.h.
-
-       * data-list.c: Basically rewrote the whole thing.  Broke out a lot
-       of code into placement-parser.c.  Code is much cleaner now.
-
-       * placement-parser.c: New file.
-
-       * placement-parser.h: New file.
-
-       * print.c: Basically rewrote the whole thing.  Broke out PRINT
-       SPACE into print-space.c.  Code is much cleaner now.
-
-       * print-space.c: New file.
-
-Sat Jul  1 17:39:40 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #11612, "q2c documentation does not agree with code".
-       
-       * list.q: Audit use of q2c "+" prefixes that indicate that a
-       command may appear multiple times.
-
-Sat Jul  1 20:44:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #15786: System File Creation crashes if directoy is
-       nonexistent.
-       
-       * get.c (parse_write_command): Check that the any_writer open
-       succeeds.
-
-Tue Jun 27 22:44:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix regression in command name completion reported by John
-       Darrington.  Now completion is again state-dependent and occurs
-       only on the first line of a command.
-       
-       * inpt-pgm.c: (cmd_input_program) Reading of first token in
-       command moved into cmd_parse.
-
-Fri Jun  9 13:56:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * matrix-data.c (context): Use dynamic string.
-       (another_token) Deal with changed dfm_get_record() interface.
-       (mget_token) Ditto.
-       (force_eol) Ditto.
-
-       * data-list.c (struct data_list_pgm) Delete delims, delim_cnt
-       members, replacing them by struct string delims.  Update all
-       references to use struct string functions.
-       (cut_field) Change interface to avoid needing "end_blank", by
-       getting the data-reader to remember that state for us.  Change
-       internals to use substring.  Update both callers.
-
-       * data-reader.c (read_file_record): Use ds_read_stream().
-       (dfm_get_record) Change interface to return substring.  Updated
-       all callers.
-       (dfm_expand_tabs) Use ds_find_char().  Now maintain position
-       relative to end-of-line.  Use ds_swap().
-       (dfm_reread_record) Don't limit position by line length.
-       (dfm_column_start) Make parameter const.
-       (dfm_columns_past_end) New function.
-       (dfm_get_column) New function.
-
-Thu May 25 18:26:26 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * print.c (print_trns_free): Made the code agree with the comment, by
-       not freeing PRT.  Has the side effect that the command no longer
-       crashes on invalid syntax.
-
-Tue May  9 20:55:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       * get.c (cmd_match_files): Fix memory leak replacing default_dict.
-
-Sat May  6 22:25:09 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix segfault.
-       
-       * list.q (write_fallback_headers): (write_fallback_headers)
-       Properly record width of leader and pass it to write_varname().
-
-Sat May  6 19:03:13 2006  Ben Pfaff  <blp@gnu.org>
-
-       * get.c: (mtf_merge_dictionary) Fix value label memory leak.
-
-Sat May  6 13:51:16 2006  Ben Pfaff  <blp@gnu.org>
-
-       Use a casefile, instead of a case sink, for MATCH FILES output.
-       It's more straightforward, although it has the same effect.
-       
-       * get.c: (struct mtf_proc) Replace `sink' case sink member by
-       `output' casefile member.
-       (cmd_match_files) Work with casefile instead of sink.
-       (mtf_processing) Add case to casefile instead of sink.
-
-Sat May  6 10:43:07 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       the output code for SPLIT FILE groups in procedure.c, which really
-       shouldn't be doing any output.  Move it into the individual
-       procedures instead.  This also adds some flexibility.
-
-       * list.q (write_all_headers): Call output_split_file_values().
-
-Wed May  3 23:00:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * data-list.c: (data_list_trns_proc) Return TRNS_END_FILE at end
-       of file.  (Why didn't we do this before?)
-       (cmd_match_files) Direct procedure output to null sink.
-       Use discard_variables() instead of indirect version.
-
-       * inpt-pgm.c: Use transformation chain.
-       (struct input_program_pgm) Add trns_chain member.
-       (cmd_input_program) Initialize trns_chain member and capture
-       transformations with proc_capture_transformations().
-       (input_program_source_read) Use trns_chain_execute().
-       (destroy_input_program) Destroy input chain.
-
-Tue May  2 10:39:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * list.q Changed from using fixed length char buffers to struct 
-       string so that any length variables can be used.
-
-Mon May  1 18:21:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       Further clean up the CMD_* command result codes.
-       
-       * (enum cmd_result_extensions) New.  Add CMD_END_INPUT_PROGRAM and
-       CMD_END_CASE result codes.
-       (struct input_program_pgm) Added case_nr, write_case, wc_data
-       members for use by END CASE transformation.
-       (emit_END_CASE) New function.
-       (cmd_input_program) Interpret CMD_END_CASE by outputting an END
-       CASE transformation.  If none is output by the input program
-       itself, add one automatically at the end.  Change lack of
-       variables from warning to error.
-       (cmd_end_input_program) Return CMD_END_INPUT_PROGRAM instead of
-       CMD_END_SUBLOOP.
-       (input_program_source_read) No longer any need to special-case END
-       CASE.  Handle TRNS_DROP_CASE properly.  Initialize new members in
-       inp for use by END CASE transformation.
-       (destroy_input_program) New function.
-       (input_program_source_destroy) Just call destroy_input_program().
-       (cmd_end_case) Just return CMD_END_CASE.
-       (end_case_trns_proc) No longer a stub handled by
-       input_program_source_read().  Actually output the case and
-       increment the case number.
-
-Mon May  1 16:06:30 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove vestiges of REPEATING DATA support.
-       
-       * data-list.c: (struct rpd_num_or_var) Removed.
-       (struct repeating_data_trns) Removed.
-       (cmd_repeating_data) Removed.
-       (find_variable_input_spec) Removed.
-       (parse_num_or_var) Removed.
-       (parse_repeating_data) Removed.
-       (realize_value) Removed.
-       (struct rpd_parse_info) Removed.
-       (rpd_parse_record) Removed.
-       (repeating_data_trns_proc) Removed.
-       (repeating_data_trns_free) Removed.
-       (repeating_data_set_write_case) Removed.
-       (rpd_msg) Removed.
-
-       * inpt-pgm.c: (input_program_source_read) Don't deal with
-       REPEATING DATA.
-
-       * data-list.h: Removed.
-
-       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Removed
-       data-list.h.
-
-Mon May  1 15:58:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove vestiges of FILE TYPE support. 
-       
-       * data-list.c: (cmd_data_list) Don't check for FILE TYPE.
-       (cmd_repeating_data) Ditto.
-       
-       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Remove
-       file-type.c, file-type.h.
-
-       * file-type.c: Removed.
-       
-       * file-type.h: Removed.
-
-Wed Apr 26 13:16:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Improve the way we handle the various parsing "states".  Until now
-       we've hard-coded the state transitions in the command definition
-       file, but that's error-prone and, worse, it's redundant--we can
-       figure out what state we're in anyhow.  We can cleanly handle
-       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
-       
-       * data-list.c: (cmd_data_list) Use in_file_type() or
-       in_input_program() in place of case_source_is_class() or
-       case_source_is_complex().
-
-       * file-type.c: NB: Not really fixed except minimally to compile,
-       because it doesn't work anyway.
-       (in_file_type) New function.
-       (cmd_record_type) No need to check that we're in FILE TYPE.
-       (cmd_end_file_type) Ditto.
-       (var file_type_source_class) Make static.
-
-       * get.c: (cmd_match_files) Check vfm_source instead of pgm_state.
-
-       * inpt-pgm.c: (in_input_program) New function.
-       (cmd_input_program) Rewrite to include nested command processing
-       loop.
-       (cmd_end_input_program) Just return CMD_END_SUBLOOP.
-       (var input_program_source_class) Make static.
-       (cmd_end_case) No need to check that we're in INPUT PROGRAM.
-       (cmd_end_file) Ditto.
-       
-       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Add
-       file-type.h, inpt-pgm.h.
-
-       * file-type.h: New file.
-
-       * inpt-pgm.h: New file.
-
-Tue Apr 25 13:11:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       * print.c: Don't special-case MS-DOS line terminators.
-       (macro LINE_END_WIDTH) Removed.
-       (alloc_line) Line ends are 1 byte.
-       (print_trns_proc) Just output \n for line end.
-
-Sun Apr 23 22:05:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-       
-       * data-list.c: (macro RPD_ERR) Removed.
-       (rpd_msg) New function.  Updated all references to tmsg() to call
-       this function instead.
-
-Sat Apr 15 19:38:13 2006  Ben Pfaff  <blp@gnu.org>
-
-       Remove last users of struct file_ext so we can get rid of it
-       entirely.
-       
-       * data-reader.c: (struct dfm_reader) Change file member from
-       struct file_ext to FILE *.  Updated all references.
-       (dfm_close_reader) Close file with fn_close() instead of
-       fn_close_ext().  Also, make a copy of the file name from the file
-       handle before closing it, because we can't extract it after we
-       close the file.
-       (dfm_open_reader) Open file with fn_open() instead of
-       fn_open_ext().
-
-       * data-writer.c: (struct dfm_writer) Change file member 
-       struct file_ext to FILE *.  Updated all references.
-       (dfm_close_writer) Close file with fn_close() instead of
-       fn_close_ext().  Also, make a copy of the file name from the file
-       handle before closing it, because we can't extract it after we
-       close the file.
-       (dfm_open_writer) Open file with fn_open() instead of
-       fn_open_ext().
-
-Sat Apr 15 18:00:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.c: Add prototype to suppress warning for
-       cmd_repeating_data().
-       
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/data-io/OChangeLog b/src/language/data-io/OChangeLog
new file mode 100644 (file)
index 0000000..1eda1c0
--- /dev/null
@@ -0,0 +1,637 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+
+       * inpt-pgm.c (reread_trns_proc): Use gsl_finite instead of finite,
+       as a stopgap measure for portability until appropriate gnulib
+       modules are available.
+
+2008-02-06 John Darrington <john@darrington.wattle.id.au>
+
+       * get-data.c: Add a /BSIZE subcommand to PSQL reader.
+
+2008-02-02 John Darrington <john@darrington.wattle.id.au>
+
+       * get-data.c (cmd_get_data): Support PSQL type.
+
+2007-12-07  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6302.
+
+       * data-parser.c (data_parser_make_active_file): Fix case count
+       argument to casereader_create_sequential, which fixes data reading
+       in the GUI.
+       Provided by John Darrington.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       Move DATA LIST parsing into generic infrastructure, and generalize
+       it slightly.  Then, use the same infrastructure to implement GET
+       DATA/TYPE=TXT.
+
+       * data-parser.c: New file.
+
+       * data-parser.h: New file.
+
+       * data-list.c (struct dls_var_spec): Removed.
+       (ll_to_dls_var_spec): Removed.
+       (enum dls_type): Removed.
+       (struct data_list_pgm): Rename struct data_list_trns.  Remove
+       pool, specs, type, record_cnt, delims, skip_records, value_cnt
+       members.  Add new `parser' member.
+       (cmd_data_list): Use data-parser infrastructure.
+       (parse_fixed): Ditto.
+       (parse_free): Ditto.
+       (dump_fixed_table): Removed.
+       (dump_free_table): Removed.
+       (cut_field): Removed.
+       (read_from_data_list): Removed.
+       (read_from_data_list_fixed): Removed.
+       (read_from_data_list_free): Removed.
+       (read_from_data_list_list): Removed.
+       (data_list_trns_free): Rename arguments for clarity.
+       (data_list_trns_proc): Ditto.
+       (data_list_casereader_read): Removed.
+       (data_list_casereader_destroy): Removed.
+       (data_list_casereader_class): Removed.
+
+       * get-data.c (cmd_get_data): Support TXT type.
+       (set_type): New function.
+       (parse_get_txt): New function.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * placement-parser.c (parse_column): New function.
+       (parse_column_range): Add `base' argument.  Update all callers.
+       
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       Make GET DATA a separate command, instead of something invoked
+       indirectly from GET.
+
+       * automake.mk: Remove get-data.h from sources.
+
+       * get-data.h: Removed.
+
+       * get-data.c (parse_get_data_command): Rename cmd_get_data.
+
+       * get.c (parse_read_command): No longer any need to check for DATA
+       keyword.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * src/language/data-io/data-reader.c (struct dfm_reader): New
+       `file_size' member to support dfm_get_percent_read.
+       (dfm_open_reader): Initialize file_size.
+       (dfm_get_percent_read): New function.
+
+2007-11-08  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6256: add support for binary, 360 file formats.  Reviewed
+       by John Darrington.
+
+       * data-reader.c (struct dfm_reader): New member `block_left'.
+       (dfm_open_reader): Initialize block_left.  For FH_MODE_TEXT, open
+       the file in text mode.
+       (read_error): New function.
+       (partial_record): New function.
+       (try_to_read_fully): New function.
+       (enum descriptor_type): New enum.
+       (read_descriptor_word): New function.
+       (corrupt_size): New function.
+       (read_size): New function.
+       (read_file_record): Implement new modes.
+       (read_record): Now take care of tracking line numbers here.
+       (dfm_reader_get_legacy_encoding): New function.
+
+       * data-writer.c (dfm_put_record): Implement new modes.
+       (dfm_writer_get_legacy_encoding): New function.
+
+       * file-handle.q: Parse new formats.
+       (cmd_file_handle): Set up new formats.
+
+       * print.c (struct print_trns): New member `encoding'.
+       (internal_cmd_print): Set encoding.
+       (print_trns_proc): Recode output data if necessary.
+       (flush_records): Recode leader byte.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * data-list.c (cmd_data_list): Manage file handle reference
+       counts.
+
+       * data-reader.c (struct dfm_reader): Add `lock' member.
+       (dfm_close_reader): Simplify, as reference counting is now
+       separate from locking.
+       (dfm_open_reader): Lock file.
+
+       * data-writer.c (struct dfm_writer): Add fh_lock, replace_file
+       members.
+       (dfm_open_writer): Lock file and prepare for replacement.
+       (dfm_close_writer): Unlock file and replace it.
+
+       * file-handle.q (cmd_close_file_handle): Use fh_unname.
+       (fh_parse): Don't distinguish existing handles for a given file
+       name from new ones.  Manage file handle reference counts.
+
+       * get.c (parse_read_command): Manage file handle reference counts.
+       (parse_write_command): Ditto.
+       (mtf_close_all_files): Ditto.
+
+       * inpt-pgm.c (cmd_reread): Manage file handle reference counts.
+
+       * print-space.c (cmd_print_space): Manage file handle reference
+       counts.
+
+       * print.c (internal_cmd_print): Manage file handle reference
+       counts.
+
+2007-11-03 John Darrington <john@darrington.wattle.id.au>
+
+       * get.c: Add GET DATA command variant.
+
+       * get-data.c get-data.h (new files): Added support for
+        GET DATA /TYPE='gnm'  command.
+
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+
+       * data-list.c (data_list_trns_proc): Properly set retval when END
+       subcommand is in use.
+       (cmd_data_list): Don't allow END subcommand to be used with DATA
+       LIST FREE or LIST.
+
+2007-09-12  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (get_translate_case): Change input case parameter from
+       const struct ccase * to struct ccase *, to match change in
+       casereader and casewriter translators.  Destroy input case, to fix
+       memory leak.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (parse_read_command): Compact the values in the target
+       dictionary, to save space.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (struct case_map): Move into new file src/data/case-map.c.
+       (start_case_map): Ditto, and rename case_map_prepare_dict.
+       (finish_case_map): Ditto, and rename case_map_from_dict.
+       (map_case): Ditto, and rename case_map_execute.
+       (destroy_case_map): Ditto, and rename case_map_destroy.
+       (case_map_get_value_cnt): Ditto.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (case_map_get_value_cnt): New function.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #17100.
+       * data-list.c (read_from_data_list_fixed): Handle multi-record
+       DATA LIST correctly.
+
+2007-07-11  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (map_case): Create destination case instead of leaving it
+       undefined.  Fixes bug #20285.
+       Reviewed by John Darrington.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: Essentially rewrite MATCH FILES to support FIRST and
+       LAST.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+       
+       * data-list.c: Make DATA LIST into a casereader.
+
+       * get.c: Change GET, IMPORT, SAVE, EXPORT to use casereaders,
+       casewriters.
+
+       * inpt-pgm.c: Use caseinit code.  Turn INPUT PROGRAM into a
+       casereader.
+
+       * list.q: Adapt to new procedure code.
+
+2007-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Abstract the documents within a dictionary a little better.
+       Thanks to John Darrington for suggestion, initial version, and
+       review.  Patch #5917.
+
+       * get.c (mtf_merge_dictionary): Simplify creating merged document.
+
+       * sys-file-info.c (display_documents): Use new
+       dict_get_document_line_cnt and dict_get_document_line functions.
+
+Thu Feb  1 16:56:02 2007  Ben Pfaff  <blp@gnu.org>
+
+       * file-handle.q (fh_parse): Update to new fh_create_file
+       prototype.
+
+Sat Dec 16 22:16:18 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make it possible to pull cases from the active file with a
+       function call, instead of requiring indirection through a callback
+       function.
+
+       * automake.mk: Removed matrix-data.c.
+
+       * matrix-data.c: Removed.
+
+       * data-list.c (data_list_source_read): Conform with new
+       case_source_class interface.
+       (data_list_source_destroy): Ditto.
+
+       * get.c (case_reader_source_class): Ditto.
+       (case_reader_source_destroy): Ditto.
+       (parse_output_proc): Take advantage of new procedure interface.
+       (output_proc): Removed.
+       (struct mtf_file): Add "struct ccase *" member to allow use of new
+       procedure interface.
+       (cmd_match_files): Take advantage of new procedure interface.
+       (mtf_processing_finish): Removed.
+       (mtf_read_nonactive_records): Renamed mtf_read_records.  Now reads
+       from every file, without any exception for the active file.
+       (mtf_compare_BY_values): Simplify for new interface.
+       (mtf_processing): Simplify for new interface.
+
+       * inpt-pgm.c (is_valid_state): New function.
+       (input_program_source_read): Conform with new case_source_class
+       interface.
+       (input_program_source_destroy): Ditto.
+       (end_case_trns_proc): Now just needs to return TRNS_END_CASE.
+
+Sat Dec  9 18:43:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * list.q (cmd_list): Use new var_create, var_destroy functions.
+
+Thu Nov 30 21:51:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * inpt-pgm.c (cmd_reread): Always return error code upon detecting
+       syntax error.  Fixes bug #18419.  Thanks to John Darrington for
+       reporting this bug.
+
+Sun Nov 19 09:17:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c (parse_free): Follow documented (but odd) rule that
+       N format is treated as F format for free-field input.
+       
+       * data-reader.c (read_file_record): Drop new-line character from
+       input text lines.  This is symmetrical with the recently changed
+       dfm_put_record semantics.
+
+Thu Nov  2 20:56:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       Implement SKIP keyword on DATA LIST.  Fixes bug #17099.
+       
+       * data-list.c: (struct data_list_pgm) Add `skip_records' members.
+       (cmd_data_list) Set skip_records based on user input.
+       (data_list_source_read) Skip records requested by user.
+
+Tue Oct 31 20:04:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * placement-parser.c: (PRS_TYPE_T) Now that struct fmt_spec uses
+       an enum fmt_type for its type member, we can't depend on the
+       ability to put negative values into that member as out-of-band
+       values, because enum fmt_type might be an unsigned type.  So use
+       values around SCHAR_MAX instead, because we know that SCHAR_MAX
+       will fit into any type, signed or unsigned, and there aren't
+       nearly that many format types.
+       (parse_var_placements) Add for_input parameter to specify whether
+       we're parsing input or output formats.  Update all callers.
+       (fixed_parse_columns) Ditto.
+       (fixed_parse_fortran) Ditto.
+       
+Tue Oct 31 18:21:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       * print-space.c (print_space_trns_proc): Let dfm_put_record add
+       the new-line character, to match dfm_put_record change below.
+
+Sat Oct 28 11:57:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-writer.c (struct dfm_writer): Removed `bounce' member, and
+       all references to it.
+       (dfm_put_record) Change semantics so that it adds formatting
+       itself, such as new-line characters, instead of putting that
+       responsibility on the caller.  Also, pad binary records with
+       spaces instead of zeros, for compatibility.
+
+       * print.c (struct prt_out_spec) New member `sysmis_as_spaces'.
+       (struct print_trns) Remove `omit_new_lines' and all references,
+       since dfm_put_record() is taking care of that.  Add
+       `include_prefix'.
+       (internal_cmd_print) Allow an empty set of data to print.  Set
+       include_prefix.
+       (parse_specs) Allow an empty set of data to print.
+       (parse_variable_argument) Only add space with PRINT command.  Set
+       sysmis_as_spaces.
+       (print_trns_proc) Indent records if include_prefix is set, for
+       compatibility.  Output SYSMIS as spaces if sysmis_as_spaces is
+       set.  Put "1" in first column if PRINT EJECT is used with an
+       external output file.
+       (flush_records) Ditto.
+
+Sat Oct 28 16:19:57 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-reader.c: Eliminated references to extern variable getl_buf
+
+Sat Aug  5 08:25:07 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #17329 in REREAD parsing, reported by John Darrington.
+
+       * inpt-pgm.c (cmd_reread): Fix file handle parsing.
+
+Mon Jul 31 10:32:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       * print.c (parse_specs): Allow a comma between specifications.
+
+Sun Jul 16 19:57:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: (src_language_data_io_libdata_io_a_SOURCE) Add
+       print-space.c, placement-parser.c, placement-parser.h.
+
+       * data-list.c: Basically rewrote the whole thing.  Broke out a lot
+       of code into placement-parser.c.  Code is much cleaner now.
+
+       * placement-parser.c: New file.
+
+       * placement-parser.h: New file.
+
+       * print.c: Basically rewrote the whole thing.  Broke out PRINT
+       SPACE into print-space.c.  Code is much cleaner now.
+
+       * print-space.c: New file.
+
+Sat Jul  1 17:39:40 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #11612, "q2c documentation does not agree with code".
+       
+       * list.q: Audit use of q2c "+" prefixes that indicate that a
+       command may appear multiple times.
+
+Sat Jul  1 20:44:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #15786: System File Creation crashes if directoy is
+       nonexistent.
+       
+       * get.c (parse_write_command): Check that the any_writer open
+       succeeds.
+
+Tue Jun 27 22:44:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix regression in command name completion reported by John
+       Darrington.  Now completion is again state-dependent and occurs
+       only on the first line of a command.
+       
+       * inpt-pgm.c: (cmd_input_program) Reading of first token in
+       command moved into cmd_parse.
+
+Fri Jun  9 13:56:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * matrix-data.c (context): Use dynamic string.
+       (another_token) Deal with changed dfm_get_record() interface.
+       (mget_token) Ditto.
+       (force_eol) Ditto.
+
+       * data-list.c (struct data_list_pgm) Delete delims, delim_cnt
+       members, replacing them by struct string delims.  Update all
+       references to use struct string functions.
+       (cut_field) Change interface to avoid needing "end_blank", by
+       getting the data-reader to remember that state for us.  Change
+       internals to use substring.  Update both callers.
+
+       * data-reader.c (read_file_record): Use ds_read_stream().
+       (dfm_get_record) Change interface to return substring.  Updated
+       all callers.
+       (dfm_expand_tabs) Use ds_find_char().  Now maintain position
+       relative to end-of-line.  Use ds_swap().
+       (dfm_reread_record) Don't limit position by line length.
+       (dfm_column_start) Make parameter const.
+       (dfm_columns_past_end) New function.
+       (dfm_get_column) New function.
+
+Thu May 25 18:26:26 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * print.c (print_trns_free): Made the code agree with the comment, by
+       not freeing PRT.  Has the side effect that the command no longer
+       crashes on invalid syntax.
+
+Tue May  9 20:55:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       * get.c (cmd_match_files): Fix memory leak replacing default_dict.
+
+Sat May  6 22:25:09 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix segfault.
+       
+       * list.q (write_fallback_headers): (write_fallback_headers)
+       Properly record width of leader and pass it to write_varname().
+
+Sat May  6 19:03:13 2006  Ben Pfaff  <blp@gnu.org>
+
+       * get.c: (mtf_merge_dictionary) Fix value label memory leak.
+
+Sat May  6 13:51:16 2006  Ben Pfaff  <blp@gnu.org>
+
+       Use a casefile, instead of a case sink, for MATCH FILES output.
+       It's more straightforward, although it has the same effect.
+       
+       * get.c: (struct mtf_proc) Replace `sink' case sink member by
+       `output' casefile member.
+       (cmd_match_files) Work with casefile instead of sink.
+       (mtf_processing) Add case to casefile instead of sink.
+
+Sat May  6 10:43:07 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       the output code for SPLIT FILE groups in procedure.c, which really
+       shouldn't be doing any output.  Move it into the individual
+       procedures instead.  This also adds some flexibility.
+
+       * list.q (write_all_headers): Call output_split_file_values().
+
+Wed May  3 23:00:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * data-list.c: (data_list_trns_proc) Return TRNS_END_FILE at end
+       of file.  (Why didn't we do this before?)
+       (cmd_match_files) Direct procedure output to null sink.
+       Use discard_variables() instead of indirect version.
+
+       * inpt-pgm.c: Use transformation chain.
+       (struct input_program_pgm) Add trns_chain member.
+       (cmd_input_program) Initialize trns_chain member and capture
+       transformations with proc_capture_transformations().
+       (input_program_source_read) Use trns_chain_execute().
+       (destroy_input_program) Destroy input chain.
+
+Tue May  2 10:39:56 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * list.q Changed from using fixed length char buffers to struct 
+       string so that any length variables can be used.
+
+Mon May  1 18:21:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Further clean up the CMD_* command result codes.
+       
+       * (enum cmd_result_extensions) New.  Add CMD_END_INPUT_PROGRAM and
+       CMD_END_CASE result codes.
+       (struct input_program_pgm) Added case_nr, write_case, wc_data
+       members for use by END CASE transformation.
+       (emit_END_CASE) New function.
+       (cmd_input_program) Interpret CMD_END_CASE by outputting an END
+       CASE transformation.  If none is output by the input program
+       itself, add one automatically at the end.  Change lack of
+       variables from warning to error.
+       (cmd_end_input_program) Return CMD_END_INPUT_PROGRAM instead of
+       CMD_END_SUBLOOP.
+       (input_program_source_read) No longer any need to special-case END
+       CASE.  Handle TRNS_DROP_CASE properly.  Initialize new members in
+       inp for use by END CASE transformation.
+       (destroy_input_program) New function.
+       (input_program_source_destroy) Just call destroy_input_program().
+       (cmd_end_case) Just return CMD_END_CASE.
+       (end_case_trns_proc) No longer a stub handled by
+       input_program_source_read().  Actually output the case and
+       increment the case number.
+
+Mon May  1 16:06:30 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove vestiges of REPEATING DATA support.
+       
+       * data-list.c: (struct rpd_num_or_var) Removed.
+       (struct repeating_data_trns) Removed.
+       (cmd_repeating_data) Removed.
+       (find_variable_input_spec) Removed.
+       (parse_num_or_var) Removed.
+       (parse_repeating_data) Removed.
+       (realize_value) Removed.
+       (struct rpd_parse_info) Removed.
+       (rpd_parse_record) Removed.
+       (repeating_data_trns_proc) Removed.
+       (repeating_data_trns_free) Removed.
+       (repeating_data_set_write_case) Removed.
+       (rpd_msg) Removed.
+
+       * inpt-pgm.c: (input_program_source_read) Don't deal with
+       REPEATING DATA.
+
+       * data-list.h: Removed.
+
+       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Removed
+       data-list.h.
+
+Mon May  1 15:58:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove vestiges of FILE TYPE support. 
+       
+       * data-list.c: (cmd_data_list) Don't check for FILE TYPE.
+       (cmd_repeating_data) Ditto.
+       
+       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Remove
+       file-type.c, file-type.h.
+
+       * file-type.c: Removed.
+       
+       * file-type.h: Removed.
+
+Wed Apr 26 13:16:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Improve the way we handle the various parsing "states".  Until now
+       we've hard-coded the state transitions in the command definition
+       file, but that's error-prone and, worse, it's redundant--we can
+       figure out what state we're in anyhow.  We can cleanly handle
+       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
+       
+       * data-list.c: (cmd_data_list) Use in_file_type() or
+       in_input_program() in place of case_source_is_class() or
+       case_source_is_complex().
+
+       * file-type.c: NB: Not really fixed except minimally to compile,
+       because it doesn't work anyway.
+       (in_file_type) New function.
+       (cmd_record_type) No need to check that we're in FILE TYPE.
+       (cmd_end_file_type) Ditto.
+       (var file_type_source_class) Make static.
+
+       * get.c: (cmd_match_files) Check vfm_source instead of pgm_state.
+
+       * inpt-pgm.c: (in_input_program) New function.
+       (cmd_input_program) Rewrite to include nested command processing
+       loop.
+       (cmd_end_input_program) Just return CMD_END_SUBLOOP.
+       (var input_program_source_class) Make static.
+       (cmd_end_case) No need to check that we're in INPUT PROGRAM.
+       (cmd_end_file) Ditto.
+       
+       * automake.mk (src_language_data_io_libdata_io_a_SOURCES): Add
+       file-type.h, inpt-pgm.h.
+
+       * file-type.h: New file.
+
+       * inpt-pgm.h: New file.
+
+Tue Apr 25 13:11:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       * print.c: Don't special-case MS-DOS line terminators.
+       (macro LINE_END_WIDTH) Removed.
+       (alloc_line) Line ends are 1 byte.
+       (print_trns_proc) Just output \n for line end.
+
+Sun Apr 23 22:05:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+       
+       * data-list.c: (macro RPD_ERR) Removed.
+       (rpd_msg) New function.  Updated all references to tmsg() to call
+       this function instead.
+
+Sat Apr 15 19:38:13 2006  Ben Pfaff  <blp@gnu.org>
+
+       Remove last users of struct file_ext so we can get rid of it
+       entirely.
+       
+       * data-reader.c: (struct dfm_reader) Change file member from
+       struct file_ext to FILE *.  Updated all references.
+       (dfm_close_reader) Close file with fn_close() instead of
+       fn_close_ext().  Also, make a copy of the file name from the file
+       handle before closing it, because we can't extract it after we
+       close the file.
+       (dfm_open_reader) Open file with fn_open() instead of
+       fn_open_ext().
+
+       * data-writer.c: (struct dfm_writer) Change file member 
+       struct file_ext to FILE *.  Updated all references.
+       (dfm_close_writer) Close file with fn_close() instead of
+       fn_close_ext().  Also, make a copy of the file name from the file
+       handle before closing it, because we can't extract it after we
+       close the file.
+       (dfm_open_writer) Open file with fn_open() instead of
+       fn_open_ext().
+
+Sat Apr 15 18:00:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.c: Add prototype to suppress warning for
+       cmd_repeating_data().
+       
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 9cb6b837ec6d4c1c26c55dc7671245cfcc4e62d0..db209be836078494018396feaf61c164a3b8dc39 100644 (file)
@@ -26,3 +26,4 @@ all_q_sources += $(src_language_data_io_built_sources:.c=.q)
 EXTRA_DIST += $(src_language_data_io_built_sources:.c=.q)
 CLEANFILES += $(src_language_data_io_built_sources)
 
+EXTRA_DIST += src/language/data-io/OChangeLog
index ecb87d4a61a779a98af86cc63ae8b896a1bf5ec1..7a2a074b59e763eebe322780c96e86f057991ed6 100644 (file)
@@ -282,7 +282,8 @@ cmd_data_list (struct lexer *lexer, struct dataset *ds)
 
  error:
   data_parser_destroy (parser);
-  dict_destroy (dict);
+  if (!in_input_program ())
+    dict_destroy (dict);
   fh_unref (fh);
   return CMD_CASCADING_FAILURE;
 }
@@ -404,7 +405,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
 
       if (!parse_DATA_LIST_vars_pool (lexer, tmp_pool,
                                      &name, &name_cnt, PV_NONE))
-       return 0;
+       return false;
 
       if (lex_match (lexer, '('))
        {
@@ -435,7 +436,7 @@ parse_free (struct lexer *lexer, struct dictionary *dict,
          if (v == NULL)
            {
              msg (SE, _("%s is a duplicate variable name."), name[i]);
-             return 0;
+             return false;
            }
           var_set_both_formats (v, &output);
 
index 4976d3f42e69712ff52bc82f38d6432b5f5f3359..b250e91bb53d2d7cf7b628fd6f41cb8113f7f30b 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdbool.h>
 #include <data/case.h>
+#include <libpspp/str.h>
 
 struct dataset;
 struct dfm_reader;
index 7fd722a81e3f9737a424f6dfb256c46d005d88c0..24ddcf13ec61cf6749c64cd63bfd4e03268cbeea 100644 (file)
@@ -187,6 +187,7 @@ read_inline_record (struct dfm_reader *r)
 
   if (!lex_get_line_raw (r->lexer))
     {
+      lex_discard_line (r->lexer);
       msg (SE, _("Unexpected end-of-file while reading data in BEGIN "
                  "DATA.  This probably indicates "
                  "a missing or misformatted END DATA command.  "
index e000a0fd3a2b95772aec8a80371379a38b17ed0c..609c9b2c92bec4b85894b6ab26daca928b0031d9 100644 (file)
@@ -19,7 +19,6 @@
 #include <language/data-io/inpt-pgm.h>
 
 #include <float.h>
-#include <gsl/gsl_math.h>
 #include <stdlib.h>
 
 #include <data/case.h>
@@ -333,7 +332,7 @@ reread_trns_proc (void *t_, struct ccase *c, casenumber case_num)
   else
     {
       double column = expr_evaluate_num (t->column, c, case_num);
-      if (!gsl_finite (column) || column < 1)
+      if (!isfinite (column) || column < 1)
        {
          msg (SE, _("REREAD: Column numbers must be positive finite "
               "numbers.  Column set to 1."));
diff --git a/src/language/dictionary/ChangeLog b/src/language/dictionary/ChangeLog
deleted file mode 100644 (file)
index 20778a2..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-2008-03-16  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6452.  Reviewed by John Darrington.
-
-       * variable-display.c (cmd_variable_width): Fix parsing bug.  Also,
-       limit variable display widths to within range 1 thru 2 *
-       MAX_STRING.
-
-2007-11-11  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-info.c (display_variables): Fix DISPLAY LABELS.  Thanks
-       to Guido Gay <gay@irer.it> for reporting this bug.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * apply-dictionary.c (cmd_apply_dictionary): Manage file handle
-       reference counts.
-
-       * sys-file-info.c (cmd_sysfile_info): Manage file handle reference
-       counts.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       Output variable measurement level, alignment, and display width as
-       part of DISPLAY DICTIONARY and SYSFILE INFO output.  Bug #13019.
-       Reviewed by John Darrington.
-       * sys-file-info.c (cmd_sysfile_info): Allow space for new rows of
-       info in output.
-       (display_variables): Ditto.
-       (describe_variable): Output variable measurement level, alignment,
-       and display width as part of DISPLAY DICTIONARY and SYSFILE INFO
-       output.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-       
-       * apply-dictionary.c: Now any_reader_open returns a casereader.
-
-       * sys-file-open.c: Now sfm_reader_open returns a casereader.
-
-Sat Feb  3 21:52:35 2007  Ben Pfaff  <blp@gnu.org>
-
-       * vector.c (cmd_vector): Add support for specifying an output
-       format in the short form of the command, fixing bug #18706.
-       Rewrite to get rid of weird data structure and simplify.
-
-       * sys-file-info.c (display_vectors): For DISPLAY VECTORS, display,
-       in addition to the names of vectors, the names, positions, and
-       print formats of the variables contained in the vectors.
-
-Wed Dec 13 20:59:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add delete-variables.c
-
-       * delete-variables.c (cmd_delete_variables): New function, in new
-       file.
-       
-Sun Dec 10 13:55:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-info.c (cmd_sysfile_info): Report floating-point format
-       used in system file.
-
-Sat Dec  9 18:44:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable-label.c: Move to src/data/variable.c.
-       
-       * vector.c (cmd_vector): Use PV_SAME_WIDTH in parse_variables
-       call, because string variables in a vector must have the same
-       width.
-
-Thu Nov 30 22:06:21 2006  Ben Pfaff  <blp@gnu.org>
-
-       * value-labels.c (get_label): Allow commas between values and
-       labels and between value labels.  Fixes bug #18303.  Thanks to
-       John Darrington for reporting this bug.
-
-Sat Nov  4 16:04:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * numeric.c: (cmd_string) Check that output format is valid.
-       Simplify parsing.
-
-Wed Nov  1 20:50:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sys-file-info.c: (cmd_display) Use compare_var_ptr_names to
-       compare "struct variable **"s, not compare_var_names.  Fixes bug
-       #17423.
-
-Sat May  6 19:03:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * apply-dictionary.c: (cmd_apply_dictionary) Use new function
-       val_labs_can_set_width().
-
-Sat May  6 10:43:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       the output code for SPLIT FILE groups in procedure.c, which really
-       shouldn't be doing any output.  Move it into the individual
-       procedures instead.  This also adds some flexibility.
-
-       * split-file.c (output_split_file_values): New function.
-
-Sat May  6 10:42:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       the output code for SPLIT FILE groups in procedure.c, which really
-       shouldn't be doing any output.  Move it into the individual
-       procedures instead.  This also adds some flexibility.
-
-       * automake.mk (src_language_dictionary_libcmddict_a_SOURCES): Add
-       split-file.h.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/dictionary/OChangeLog b/src/language/dictionary/OChangeLog
new file mode 100644 (file)
index 0000000..20778a2
--- /dev/null
@@ -0,0 +1,118 @@
+2008-03-16  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6452.  Reviewed by John Darrington.
+
+       * variable-display.c (cmd_variable_width): Fix parsing bug.  Also,
+       limit variable display widths to within range 1 thru 2 *
+       MAX_STRING.
+
+2007-11-11  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-info.c (display_variables): Fix DISPLAY LABELS.  Thanks
+       to Guido Gay <gay@irer.it> for reporting this bug.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * apply-dictionary.c (cmd_apply_dictionary): Manage file handle
+       reference counts.
+
+       * sys-file-info.c (cmd_sysfile_info): Manage file handle reference
+       counts.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       Output variable measurement level, alignment, and display width as
+       part of DISPLAY DICTIONARY and SYSFILE INFO output.  Bug #13019.
+       Reviewed by John Darrington.
+       * sys-file-info.c (cmd_sysfile_info): Allow space for new rows of
+       info in output.
+       (display_variables): Ditto.
+       (describe_variable): Output variable measurement level, alignment,
+       and display width as part of DISPLAY DICTIONARY and SYSFILE INFO
+       output.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+       
+       * apply-dictionary.c: Now any_reader_open returns a casereader.
+
+       * sys-file-open.c: Now sfm_reader_open returns a casereader.
+
+Sat Feb  3 21:52:35 2007  Ben Pfaff  <blp@gnu.org>
+
+       * vector.c (cmd_vector): Add support for specifying an output
+       format in the short form of the command, fixing bug #18706.
+       Rewrite to get rid of weird data structure and simplify.
+
+       * sys-file-info.c (display_vectors): For DISPLAY VECTORS, display,
+       in addition to the names of vectors, the names, positions, and
+       print formats of the variables contained in the vectors.
+
+Wed Dec 13 20:59:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add delete-variables.c
+
+       * delete-variables.c (cmd_delete_variables): New function, in new
+       file.
+       
+Sun Dec 10 13:55:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-info.c (cmd_sysfile_info): Report floating-point format
+       used in system file.
+
+Sat Dec  9 18:44:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable-label.c: Move to src/data/variable.c.
+       
+       * vector.c (cmd_vector): Use PV_SAME_WIDTH in parse_variables
+       call, because string variables in a vector must have the same
+       width.
+
+Thu Nov 30 22:06:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       * value-labels.c (get_label): Allow commas between values and
+       labels and between value labels.  Fixes bug #18303.  Thanks to
+       John Darrington for reporting this bug.
+
+Sat Nov  4 16:04:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * numeric.c: (cmd_string) Check that output format is valid.
+       Simplify parsing.
+
+Wed Nov  1 20:50:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sys-file-info.c: (cmd_display) Use compare_var_ptr_names to
+       compare "struct variable **"s, not compare_var_names.  Fixes bug
+       #17423.
+
+Sat May  6 19:03:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * apply-dictionary.c: (cmd_apply_dictionary) Use new function
+       val_labs_can_set_width().
+
+Sat May  6 10:43:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       the output code for SPLIT FILE groups in procedure.c, which really
+       shouldn't be doing any output.  Move it into the individual
+       procedures instead.  This also adds some flexibility.
+
+       * split-file.c (output_split_file_values): New function.
+
+Sat May  6 10:42:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       the output code for SPLIT FILE groups in procedure.c, which really
+       shouldn't be doing any output.  Move it into the individual
+       procedures instead.  This also adds some flexibility.
+
+       * automake.mk (src_language_dictionary_libcmddict_a_SOURCES): Add
+       split-file.h.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index ff4d7853c3a5e8b6487fafb40e111e8dd624d17e..a1b3310176e1687385dd2dbf3bc124e711e08da1 100644 (file)
@@ -120,12 +120,19 @@ cmd_apply_dictionary (struct lexer *lexer, struct dataset *ds)
           var_set_print_format (t, var_get_print_format (s));
           var_set_write_format (t, var_get_write_format (s));
        }
+
+      if (var_has_attributes (s)) 
+        var_set_attributes (t, var_get_attributes (s));
     }
 
   if (!n_matched)
     msg (SW, _("No matching variables found between the source "
               "and target files."));
 
+  /* Data file attributes. */
+  if (dict_has_attributes (dict))
+    dict_set_attributes (dataset_dict (ds), dict_get_attributes (dict));
+
   /* Weighting. */
   if (dict_get_weight (dict) != NULL)
     {
diff --git a/src/language/dictionary/attributes.c b/src/language/dictionary/attributes.c
new file mode 100644 (file)
index 0000000..9e9b808
--- /dev/null
@@ -0,0 +1,200 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <data/attributes.h>
+#include <data/dictionary.h>
+#include <data/procedure.h>
+#include <data/variable.h>
+#include <language/command.h>
+#include <language/lexer/lexer.h>
+#include <language/lexer/variable-parser.h>
+#include <libpspp/message.h>
+
+#include "xalloc.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+static enum cmd_result parse_attributes (struct lexer *, struct attrset **,
+                                         size_t n);
+
+/* Parses the DATAFILE ATTRIBUTE command. */
+int
+cmd_datafile_attribute (struct lexer *lexer, struct dataset *ds)
+{
+  struct attrset *set = dict_get_attributes (dataset_dict (ds));
+  return parse_attributes (lexer, &set, 1);
+}
+
+/* Parses the VARIABLE ATTRIBUTE command. */
+int
+cmd_variable_attribute (struct lexer *lexer, struct dataset *ds)
+{
+  do 
+    {
+      struct variable **vars;
+      struct attrset **sets;
+      size_t n_vars, i;
+      bool ok;
+
+      if (!lex_force_match_id (lexer, "VARIABLES")
+          || !lex_force_match (lexer, '=')
+          || !parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
+                               PV_NONE))
+        return CMD_FAILURE;
+
+      sets = xmalloc (n_vars * sizeof *sets);
+      for (i = 0; i < n_vars; i++)
+        sets[i] = var_get_attributes (vars[i]);
+
+      ok = parse_attributes (lexer, sets, n_vars);
+      free (vars);
+      free (sets);
+      if (!ok)
+        return CMD_FAILURE;
+    }
+  while (lex_match (lexer, '/'));
+
+  return lex_end_of_command (lexer);
+}
+
+static bool
+match_subcommand (struct lexer *lexer, const char *keyword) 
+{
+  if (lex_token (lexer) == T_ID
+      && lex_id_match (ss_cstr (lex_tokid (lexer)), ss_cstr (keyword))
+      && lex_look_ahead (lexer) == '=') 
+    {
+      lex_get (lexer);          /* Skip keyword. */
+      lex_get (lexer);          /* Skip '='. */
+      return true;
+    }
+  else
+    return false;
+}
+
+static bool
+parse_attribute_name (struct lexer *lexer, char name[VAR_NAME_LEN + 1],
+                      size_t *index) 
+{
+  if (!lex_force_id (lexer))
+    return false;
+  strcpy (name, lex_tokid (lexer));
+  lex_get (lexer);
+
+  if (lex_match (lexer, '[')) 
+    {
+      if (!lex_force_int (lexer))
+        return false;
+      if (lex_integer (lexer) < 1 || lex_integer (lexer) > 65535)
+        {
+          msg (SE, _("Attribute array index must be between 1 and 65535."));
+          return false;
+        }
+      *index = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ']'))
+        return false;
+    }
+  else
+    *index = 0;
+  return true;
+}
+
+static bool
+add_attribute (struct lexer *lexer, struct attrset **sets, size_t n) 
+{
+  char name[VAR_NAME_LEN + 1];
+  size_t index, i;
+  char *value;
+
+  if (!parse_attribute_name (lexer, name, &index)
+      || !lex_force_match (lexer, '(')
+      || !lex_force_string (lexer))
+    return false;
+  value = ds_cstr (lex_tokstr (lexer));
+
+  for (i = 0; i < n; i++)
+    {
+      struct attribute *attr = attrset_lookup (sets[i], name);
+      if (attr == NULL) 
+        {
+          attr = attribute_create (name);
+          attrset_add (sets[i], attr); 
+        }
+      attribute_set_value (attr, index ? index - 1 : 0, value);
+    }
+
+  lex_get (lexer);
+  return lex_force_match (lexer, ')');
+}
+
+static bool
+delete_attribute (struct lexer *lexer, struct attrset **sets, size_t n) 
+{
+  char name[VAR_NAME_LEN + 1];
+  size_t index, i;
+
+  if (!parse_attribute_name (lexer, name, &index))
+    return false;
+
+  for (i = 0; i < n; i++) 
+    {
+      struct attrset *set = sets[i];
+      if (index == 0)
+        attrset_delete (set, name);
+      else
+        {
+          struct attribute *attr = attrset_lookup (set, name);
+          if (attr != NULL) 
+            {
+              attribute_del_value (attr, index - 1);
+              if (attribute_get_n_values (attr) == 0)
+                attrset_delete (set, name); 
+            }
+        }
+    }
+  return true;
+}
+
+static enum cmd_result
+parse_attributes (struct lexer *lexer, struct attrset **sets, size_t n) 
+{
+  enum { UNKNOWN, ADD, DELETE } command = UNKNOWN;
+  do 
+    {
+      if (match_subcommand (lexer, "ATTRIBUTE"))
+        command = ADD;
+      else if (match_subcommand (lexer, "DELETE"))
+        command = DELETE;
+      else if (command == UNKNOWN)
+        {
+          lex_error (lexer, _("expecting ATTRIBUTE= or DELETE="));
+          return CMD_FAILURE;
+        }
+
+      if (!(command == ADD
+            ? add_attribute (lexer, sets, n)
+            : delete_attribute (lexer, sets, n)))
+        return CMD_FAILURE;
+    }
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
+  return CMD_SUCCESS;
+}
index a33a84f978b374c627ea31add0e3f689ed2133b4..2aa91842c5db8bdc42848624e049b15bcd9187c8 100644 (file)
@@ -1,6 +1,7 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
 language_dictionary_sources = \
+ src/language/dictionary/attributes.c \
  src/language/dictionary/apply-dictionary.c \
  src/language/dictionary/delete-variables.c \
  src/language/dictionary/formats.c \
@@ -17,3 +18,4 @@ language_dictionary_sources = \
  src/language/dictionary/variable-display.c \
  src/language/dictionary/weight.c
 
+EXTRA_DIST += src/language/dictionary/OChangeLog
index b98854db6ea290a053a43fa377b6d0e4d246b305..d6279159a6587e8cf2d8c82524e52581c50ba979 100644 (file)
@@ -19,6 +19,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <data/attributes.h>
 #include <data/casereader.h>
 #include <data/dictionary.h>
 #include <data/file-handle-def.h>
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-/* Constants for DISPLAY utility. */
-enum
+/* Information to include in displaying a dictionary. */
+enum 
   {
-    AS_NAMES = 0,
-    AS_INDEX,
-    AS_VARIABLES,
-    AS_LABELS,
-    AS_DICTIONARY,
-    AS_SCRATCH,
-    AS_VECTOR
+    DF_DICT_INDEX       = 1 << 0,
+    DF_FORMATS          = 1 << 1,
+    DF_VALUE_LABELS     = 1 << 2,
+    DF_VARIABLE_LABELS  = 1 << 3,
+    DF_MISSING_VALUES   = 1 << 4,
+    DF_AT_ATTRIBUTES    = 1 << 5, /* Attributes whose names begin with @. */
+    DF_ATTRIBUTES       = 1 << 6, /* All other attributes. */
+    DF_MISC             = 1 << 7,
+    DF_ALL              = (1 << 8) - 1
   };
 
-static int describe_variable (const struct variable *v, struct tab_table *t, int r, int as);
+static int describe_variable (const struct variable *v, struct tab_table *t,
+                              int r, int pc, int flags);
 
 /* Sets the widths of all the columns and heights of all the rows in
    table T for driver D. */
@@ -87,8 +91,7 @@ cmd_sysfile_info (struct lexer *lexer, struct dataset *ds UNUSED)
   struct tab_table *t;
   struct casereader *reader;
   struct sfm_read_info info;
-  int r, nr;
-  int i;
+  int r, i;
 
   lex_match_id (lexer, "FILE");
   lex_match (lexer, '=');
@@ -153,9 +156,7 @@ cmd_sysfile_info (struct lexer *lexer, struct dataset *ds UNUSED)
   tab_dim (t, tab_natural_dimensions);
   tab_submit (t);
 
-  nr = 1 + 2 * dict_get_var_cnt (d);
-
-  t = tab_create (4, nr, 1);
+  t = tab_create (4, 1 + 2 * dict_get_var_cnt (d), 1);
   tab_dim (t, sysfile_info_dim);
   tab_headers (t, 0, 0, 1, 0);
   tab_text (t, 0, 0, TAB_LEFT | TAT_TITLE, _("Variable"));
@@ -163,19 +164,8 @@ cmd_sysfile_info (struct lexer *lexer, struct dataset *ds UNUSED)
   tab_text (t, 3, 0, TAB_LEFT | TAT_TITLE, _("Position"));
   tab_hline (t, TAL_2, 0, 3, 1);
   for (r = 1, i = 0; i < dict_get_var_cnt (d); i++)
-    {
-      struct variable *v = dict_get_var (d, i);
-      const int nvl = val_labs_count (var_get_value_labels (v));
-
-      if (r + 13 + nvl > nr)
-       {
-         nr = MAX (nr * dict_get_var_cnt (d) / (i + 1), nr);
-         nr += 10 + nvl;
-         tab_realloc (t, 4, nr);
-       }
-
-      r = describe_variable (v, t, r, AS_DICTIONARY);
-    }
+    r = describe_variable (dict_get_var (d, i), t, r, 3,
+                           DF_ALL & ~DF_AT_ATTRIBUTES);
 
   tab_box (t, TAL_1, TAL_1, -1, -1, 0, 0, 3, r);
   tab_vline (t, TAL_1, 1, 0, r);
@@ -197,6 +187,7 @@ static void display_macros (void);
 static void display_documents (const struct dictionary *dict);
 static void display_variables (const struct variable **, size_t, int);
 static void display_vectors (const struct dictionary *dict, int sorted);
+static void display_data_file_attributes (struct attrset *, int flags);
 
 int
 cmd_display (struct lexer *lexer, struct dataset *ds)
@@ -228,73 +219,81 @@ cmd_display (struct lexer *lexer, struct dataset *ds)
     }
   else
     {
-      static const char *sbc[] =
-       {"NAMES", "INDEX", "VARIABLES", "LABELS",
-        "DICTIONARY", "SCRATCH", "VECTORS", NULL};
-      const char **cp;
-      int as;
+      int flags;
 
       sorted = lex_match_id (lexer, "SORTED");
 
-      for (cp = sbc; *cp; cp++)
-       if (lex_token (lexer) == T_ID
-            && lex_id_match (ss_cstr (*cp), ss_cstr (lex_tokid (lexer))))
-         {
-           lex_get (lexer);
-           break;
-         }
-      as = cp - sbc;
-
-      if (*cp == NULL)
-       as = AS_NAMES;
-
-      if (as == AS_VECTOR)
+      if (lex_match_id (lexer, "VECTORS"))
        {
          display_vectors (dataset_dict(ds), sorted);
-         return CMD_SUCCESS;
+         return lex_end_of_command (lexer);
        }
+      else if (lex_match_id (lexer, "SCRATCH")) 
+        {
+          dict_get_vars (dataset_dict (ds), &vl, &n, DC_ORDINARY);
+          flags = 0;
+        }
+      else 
+        {
+          struct subcommand 
+            {
+              const char *name;
+              int flags;
+            };
+          static const struct subcommand subcommands[] = 
+            {
+              {"@ATTRIBUTES", DF_ATTRIBUTES | DF_AT_ATTRIBUTES},
+              {"ATTRIBUTES", DF_ATTRIBUTES},
+              {"DICTIONARY", DF_ALL & ~DF_AT_ATTRIBUTES},
+              {"INDEX", DF_DICT_INDEX},
+              {"LABELS", DF_DICT_INDEX | DF_VARIABLE_LABELS},
+              {"NAMES", 0},
+              {"VARIABLES",
+               DF_DICT_INDEX | DF_FORMATS | DF_MISSING_VALUES | DF_MISC},
+              {NULL, 0},
+            };
+          const struct subcommand *sbc;
+
+          flags = 0;
+          for (sbc = subcommands; sbc->name != NULL; sbc++)
+            if (lex_match_id (lexer, sbc->name))
+              {
+                flags = sbc->flags;
+                break;
+              }
+
+          lex_match (lexer, '/');
+          lex_match_id (lexer, "VARIABLES");
+          lex_match (lexer, '=');
+
+          if (lex_token (lexer) != '.')
+            {
+              if (!parse_variables_const (lexer, dataset_dict (ds), &vl, &n,
+                                          PV_NONE))
+                {
+                  free (vl);
+                  return CMD_FAILURE;
+                }
+            }
+          else
+            dict_get_vars (dataset_dict (ds), &vl, &n, 0);
+        }
 
-      lex_match (lexer, '/');
-      lex_match_id (lexer, "VARIABLES");
-      lex_match (lexer, '=');
-
-      if (lex_token (lexer) != '.')
-       {
-         if (!parse_variables_const (lexer, dataset_dict (ds), &vl, &n, PV_NONE))
-           {
-             free (vl);
-             return CMD_FAILURE;
-           }
-         as = AS_DICTIONARY;
-       }
+      if (n > 0) 
+        {
+          sort (vl, n, sizeof *vl,
+                (sorted
+                 ? compare_var_ptrs_by_name
+                 : compare_var_ptrs_by_dict_index), NULL);
+          display_variables (vl, n, flags);
+        }
       else
-       dict_get_vars (dataset_dict (ds), &vl, &n, 0);
-
-      if (as == AS_SCRATCH)
-       {
-         size_t i, m;
-         for (i = 0, m = n; i < n; i++)
-           if (dict_class_from_id (var_get_name (vl[i])) != DC_SCRATCH)
-             {
-               vl[i] = NULL;
-               m--;
-             }
-         as = AS_NAMES;
-         n = m;
-       }
-
-      if (n == 0)
-       {
-         msg (SW, _("No variables to display."));
-         return CMD_FAILURE;
-       }
-
-      if (sorted)
-       sort (vl, n, sizeof *vl, compare_var_ptrs_by_name, NULL);
-
-      display_variables (vl, n, as);
-
+        msg (SW, _("No variables to display."));
       free (vl);
+
+      if (flags & (DF_ATTRIBUTES | DF_AT_ATTRIBUTES))
+        display_data_file_attributes (dict_get_attributes (dataset_dict (ds)),
+                                      flags);
     }
 
   return lex_end_of_command (lexer);
@@ -333,7 +332,7 @@ display_documents (const struct dictionary *dict)
     }
 }
 
-static int _as;
+static int _flags;
 
 /* Sets the widths of all the columns and heights of all the rows in
    table T for driver D. */
@@ -344,14 +343,16 @@ variables_dim (struct tab_table *t, struct outp_driver *d)
   int i;
 
   t->w[0] = tab_natural_width (t, d, 0);
-  if (_as == AS_DICTIONARY || _as == AS_VARIABLES || _as == AS_LABELS)
+  if (_flags & (DF_VALUE_LABELS | DF_VARIABLE_LABELS | DF_MISSING_VALUES
+                | DF_AT_ATTRIBUTES | DF_ATTRIBUTES))
     {
       t->w[1] = MAX (tab_natural_width (t, d, 1), d->prop_em_width * 5);
       t->w[2] = MAX (tab_natural_width (t, d, 2), d->prop_em_width * 35);
       pc = 3;
     }
-  else pc = 1;
-  if (_as != AS_NAMES)
+  else
+    pc = 1;
+  if (_flags & DF_DICT_INDEX)
     t->w[pc] = tab_natural_width (t, d, pc);
 
   for (i = 0; i < t->nr; i++)
@@ -359,155 +360,220 @@ variables_dim (struct tab_table *t, struct outp_driver *d)
 }
 
 static void
-display_variables (const struct variable **vl, size_t n, int as)
+display_variables (const struct variable **vl, size_t n, int flags)
 {
-  const struct variable **vp = vl;     /* Variable pointer. */
   struct tab_table *t;
   int nc;                      /* Number of columns. */
-  int nr;                      /* Number of rows. */
   int pc;                      /* `Position column' */
   int r;                       /* Current row. */
   size_t i;
 
-  _as = as;
-  switch (as)
-    {
-    case AS_INDEX:
-      nc = 2;
-      break;
-    case AS_NAMES:
-      nc = 1;
-      break;
-    default:
-      nc = 4;
-      break;
-    }
+  _flags = flags;
+
+  /* One column for the name,
+     two columns for general description,
+     one column for dictionary index. */
+  nc = 1;
+  if (flags & ~DF_DICT_INDEX)
+    nc += 2;
+  pc = nc;
+  if (flags & DF_DICT_INDEX)
+    nc++;
 
   t = tab_create (nc, n + 5, 1);
   tab_headers (t, 0, 0, 1, 0);
-  nr = n + 5;
   tab_hline (t, TAL_2, 0, nc - 1, 1);
   tab_text (t, 0, 0, TAB_LEFT | TAT_TITLE, _("Variable"));
-  pc = (as == AS_INDEX ? 1 : 3);
-  if (as != AS_NAMES)
+  if (flags & ~DF_DICT_INDEX) 
+    tab_joint_text (t, 1, 0, 2, 0, TAB_LEFT | TAT_TITLE,
+                    (flags & ~(DF_DICT_INDEX | DF_VARIABLE_LABELS)
+                     ? _("Description") : _("Label")));
+  if (flags & DF_DICT_INDEX)
     tab_text (t, pc, 0, TAB_LEFT | TAT_TITLE, _("Position"));
-  if (as == AS_DICTIONARY || as == AS_VARIABLES)
-    tab_joint_text (t, 1, 0, 2, 0, TAB_LEFT | TAT_TITLE, _("Description"));
-  else if (as == AS_LABELS)
-    tab_joint_text (t, 1, 0, 2, 0, TAB_LEFT | TAT_TITLE, _("Label"));
   tab_dim (t, variables_dim);
 
-  for (i = r = 1; i <= n; i++)
-    {
-      const struct variable *v;
-
-      while (*vp == NULL)
-       vp++;
-      v = *vp++;
-
-      if (as == AS_DICTIONARY || as == AS_VARIABLES)
-       {
-         int nvl = val_labs_count (var_get_value_labels (v));
-
-         if (r + 13 + nvl > nr)
-           {
-             nr = MAX (nr * n / (i + 1), nr);
-             nr += 10 + nvl;
-             tab_realloc (t, nc, nr);
-           }
-
-         r = describe_variable (v, t, r, as);
-       } else {
-         tab_text (t, 0, r, TAB_LEFT, var_get_name (v));
-         if (as == AS_LABELS)
-            {
-              const char *label = var_get_label (v);
-              tab_joint_text (t, 1, r, 2, r, TAB_LEFT,
-                              label == NULL ? "(no label)" : label);
-            }
-         if (as != AS_NAMES)
-           {
-             tab_text (t, pc, r, TAT_PRINTF, "%zu",
-                        var_get_dict_index (v) + 1);
-             tab_hline (t, TAL_1, 0, nc - 1, r);
-           }
-         r++;
-       }
-    }
-  tab_hline (t, as == AS_NAMES ? TAL_1 : TAL_2, 0, nc - 1, 1);
-  if (as != AS_NAMES)
+  r = 1;
+  for (i = 0; i < n; i++)
+    r = describe_variable (vl[i], t, r, pc, flags);
+  tab_hline (t, flags & ~DF_DICT_INDEX ? TAL_2 : TAL_1, 0, nc - 1, 1);
+  if (flags)
     {
       tab_box (t, TAL_1, TAL_1, -1, -1, 0, 0, nc - 1, r - 1);
       tab_vline (t, TAL_1, 1, 0, r - 1);
     }
   else
     tab_flags (t, SOMF_NO_TITLE);
-  if (as == AS_DICTIONARY || as == AS_VARIABLES || as == AS_LABELS)
-    tab_vline (t, TAL_1, 3, 0, r - 1);
+  if (flags & ~DF_DICT_INDEX)
+    tab_vline (t, TAL_1, nc - 1, 0, r - 1);
   tab_resize (t, -1, r);
   tab_columns (t, TAB_COL_DOWN, 1);
   tab_submit (t);
 }
 \f
-/* Puts a description of variable V into table T starting at row R.
-   The variable will be described in the format AS.  Returns the next
-   row available for use in the table. */
+static bool
+is_at_name (const char *name) 
+{
+  return name[0] == '@' || (name[0] == '$' && name[1] == '@');
+}
+
+static size_t
+count_attributes (const struct attrset *set, int flags) 
+{
+  struct attrset_iterator i;
+  struct attribute *attr;
+  size_t n_attrs;
+  
+  n_attrs = 0;
+  for (attr = attrset_first (set, &i); attr != NULL;
+       attr = attrset_next (set, &i)) 
+    if (flags & DF_AT_ATTRIBUTES || !is_at_name (attribute_get_name (attr)))
+      n_attrs += attribute_get_n_values (attr);
+  return n_attrs;
+}
+
+static void
+display_attributes (struct tab_table *t, const struct attrset *set, int flags,
+                    int c, int r)
+{
+  struct attrset_iterator i;
+  struct attribute *attr;
+
+  for (attr = attrset_first (set, &i); attr != NULL;
+       attr = attrset_next (set, &i)) 
+    {
+      const char *name = attribute_get_name (attr);
+      size_t n_values;
+      size_t i;
+
+      if (!(flags & DF_AT_ATTRIBUTES) && is_at_name (name))
+        continue;
+
+      n_values = attribute_get_n_values (attr);
+      for (i = 0; i < n_values; i++)
+        {
+          if (n_values > 1)
+            tab_text (t, c, r, TAB_LEFT | TAT_PRINTF, "%s[%d]",
+                      name, i + 1);
+          else
+            tab_text (t, c, r, TAB_LEFT, name);
+          tab_text (t, c + 1, r, TAB_LEFT, attribute_get_value (attr, i));
+          r++;
+        }
+    }
+}
+
+static void
+display_data_file_attributes (struct attrset *set, int flags) 
+{
+  struct tab_table *t;
+  size_t n_attrs;
+
+  n_attrs = count_attributes (set, flags);
+  if (!n_attrs)
+    return;
+
+  t = tab_create (2, n_attrs + 1, 0);
+  tab_headers (t, 0, 0, 1, 0);
+  tab_box (t, TAL_1, TAL_1, -1, TAL_1, 0, 0, tab_nc (t) - 1, tab_nr (t) - 1);
+  tab_hline (t, TAL_2, 0, 1, 1); 
+  tab_text (t, 0, 0, TAB_LEFT | TAT_TITLE, _("Attribute"));
+  tab_text (t, 1, 0, TAB_LEFT | TAT_TITLE, _("Value"));
+  display_attributes (t, set, flags, 0, 1);
+  tab_columns (t, TAB_COL_DOWN, 1);
+  tab_dim (t, tab_natural_dimensions);
+  tab_title (t, "Custom data file attributes.");
+  tab_submit (t);
+}
+
+/* Puts a description of variable V into table T starting at row
+   R.  The variable will be described in the format given by
+   FLAGS.  Returns the next row available for use in the
+   table. */
 static int
-describe_variable (const struct variable *v, struct tab_table *t, int r, int as)
+describe_variable (const struct variable *v, struct tab_table *t, int r,
+                   int pc, int flags)
 {
-  const struct fmt_spec *print = var_get_print_format (v);
-  const struct fmt_spec *write = var_get_write_format (v);
-  enum measure m = var_get_measure (v);
-  enum alignment a = var_get_alignment (v);
+  size_t n_attrs = 0;
+  int need_rows;
+
+  /* Make sure that enough rows are allocated. */
+  need_rows = 1;
+  if (flags & ~(DF_DICT_INDEX | DF_VARIABLE_LABELS))
+    need_rows += 15;
+  if (flags & DF_VALUE_LABELS)
+    need_rows += val_labs_count (var_get_value_labels (v));
+  if (flags & (DF_ATTRIBUTES | DF_AT_ATTRIBUTES))
+    {
+      n_attrs = count_attributes (var_get_attributes (v), flags);
+      need_rows += n_attrs; 
+    }
+  if (r + need_rows > tab_nr (t))
+    {
+      int nr = MAX (r + need_rows, tab_nr (t) * 2);
+      tab_realloc (t, -1, nr);
+    }
 
   /* Put the name, var label, and position into the first row. */
   tab_text (t, 0, r, TAB_LEFT, var_get_name (v));
-  tab_text (t, 3, r, TAT_PRINTF, "%zu", var_get_dict_index (v) + 1);
+  if (flags & DF_DICT_INDEX)
+    tab_text (t, pc, r, TAT_PRINTF, "%zu", var_get_dict_index (v) + 1);
 
-  if (as == AS_DICTIONARY && var_has_label (v))
+  if (flags & DF_VARIABLE_LABELS && var_has_label (v))
     {
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT, var_get_label (v));
       r++;
     }
 
   /* Print/write format, or print and write formats. */
-  if (fmt_equal (print, write))
+  if (flags & DF_FORMATS) 
     {
-      char str[FMT_STRING_LEN_MAX + 1];
-      tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF, _("Format: %s"),
-                     fmt_to_string (print, str));
-      r++;
+      const struct fmt_spec *print = var_get_print_format (v);
+      const struct fmt_spec *write = var_get_write_format (v);
+
+      if (fmt_equal (print, write))
+        {
+          char str[FMT_STRING_LEN_MAX + 1];
+          tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
+                          _("Format: %s"), fmt_to_string (print, str));
+          r++;
+        }
+      else
+        {
+          char str[FMT_STRING_LEN_MAX + 1];
+          tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
+                          _("Print Format: %s"), fmt_to_string (print, str));
+          r++;
+          tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
+                          _("Write Format: %s"), fmt_to_string (write, str));
+          r++;
+        }
     }
-  else
+  
+  /* Measurement level, display width, alignment. */
+  if (flags & DF_MISC) 
     {
-      char str[FMT_STRING_LEN_MAX + 1];
+      enum measure m = var_get_measure (v);
+      enum alignment a = var_get_alignment (v);
+
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-                     _("Print Format: %s"), fmt_to_string (print, str));
+                      _("Measure: %s"),
+                      m == MEASURE_NOMINAL ? _("Nominal")
+                      : m == MEASURE_ORDINAL ? _("Ordinal")
+                      : _("Scale"));
       r++;
       tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-                     _("Write Format: %s"), fmt_to_string (write, str));
+                      _("Display Alignment: %s"),
+                      a == ALIGN_LEFT ? _("Left")
+                      : a == ALIGN_CENTRE ? _("Center")
+                      : _("Right"));
+      r++;
+      tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
+                      _("Display Width: %d"), var_get_display_width (v));
       r++;
     }
-
-  /* Measurement level, display width, alignment. */
-  tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-                  _("Measure: %s"),
-                  m == MEASURE_NOMINAL ? _("Nominal")
-                  : m == MEASURE_ORDINAL ? _("Ordinal")
-                  : _("Scale"));
-  r++;
-  tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-                  _("Display Alignment: %s"),
-                  a == ALIGN_LEFT ? _("Left")
-                  : a == ALIGN_CENTRE ? _("Center")
-                  : _("Right"));
-  r++;
-  tab_joint_text (t, 1, r, 2, r, TAB_LEFT | TAT_PRINTF,
-                  _("Display Width: %d"), var_get_display_width (v));
-  r++;
-
+  
   /* Missing values if any. */
-  if (var_has_missing_values (v))
+  if (flags & DF_MISSING_VALUES && var_has_missing_values (v))
     {
       char buf[128];
       char *cp;
@@ -552,7 +618,7 @@ describe_variable (const struct variable *v, struct tab_table *t, int r, int as)
     }
 
   /* Value labels. */
-  if (as == AS_DICTIONARY && var_has_value_labels (v))
+  if (flags & DF_VALUE_LABELS && var_has_value_labels (v))
     {
       const struct val_labs *val_labs = var_get_value_labels (v);
       struct val_labs_iterator *i;
@@ -587,8 +653,17 @@ describe_variable (const struct variable *v, struct tab_table *t, int r, int as)
       tab_vline (t, TAL_1, 2, orig_r, r - 1);
     }
 
+  if (flags & (DF_ATTRIBUTES | DF_AT_ATTRIBUTES) && n_attrs)
+    {
+      tab_joint_text (t, 1, r, 2, r, TAB_LEFT, "Custom attributes:");
+      r++;
+
+      display_attributes (t, var_get_attributes (v), flags, 1, r);
+      r += n_attrs;
+    }
+
   /* Draw a line below the last row of information on this variable. */
-  tab_hline (t, TAL_1, 0, 3, r);
+  tab_hline (t, TAL_1, 0, tab_nc (t) - 1, r);
 
   return r;
 }
index 4b7c03961783c0109b30c8e5a32bcb13b43658b3..39f544ec4b917fa2b517129a06ad6c252d5cc171 100644 (file)
@@ -163,11 +163,9 @@ get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt)
        {
          if (!lex_is_number (lexer))
            {
-             lex_error (lexer, _("expecting integer"));
+             lex_error (lexer, _("expecting number"));
              return 0;
            }
-         if (!lex_is_integer (lexer))
-           msg (SW, _("Value label `%g' is not integer."), lex_tokval (lexer));
          value.f = lex_tokval (lexer);
        }
       lex_get (lexer);
diff --git a/src/language/expressions/ChangeLog b/src/language/expressions/ChangeLog
deleted file mode 100644 (file)
index 18c9441..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-
-       * evaluate.c (expr_evaluate): Use gsl_finite instead of finite, as
-       a stopgap measure for portability until appropriate gnulib modules
-       are available.
-
-       * helpers.h (copy_string): Ditto.
-
-2007-10-12  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6224.
-
-       * helpers.c: Don't need our own trunc function implementation
-       anymore, since we now use the one from gnulib.
-
-2007-07-17  Ben Pfaff  <blp@gnu.org>
-
-       Patch #19335.  Reviewed by John Darrington.
-
-       * evaluate.h.pl: Use strict and all warnings.  Fix warnings that
-       this triggers.
-
-       * evaluate.inc.pl: Ditto.
-
-       * generate.pl: Ditto.
-
-       * operations.h.pl: Ditto.
-
-       * optimize.inc.pl: Ditto.
-
-       * parse.inc.pl: Ditto.
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * parse.c (expr_get_function): New function.
-       (expr_get_function_cnt): New function.
-       (expr_operation_get_name): New function.
-       (expr_operation_get_prototype): New function.
-       (expr_operation_get_arg_cnt): New function.
-
-Thu Feb  1 06:59:27 2007  Ben Pfaff  <blp@gnu.org>
-
-       * parse.c (parse_function): Accept TO in any case for use with
-       n-ary functions.  Fixes bug #18923.  Thanks to John Darrington for
-       reporting this bug.
-
-Sat Dec 16 12:20:14 2006  Ben Pfaff  <blp@gnu.org>
-
-       * operations.def: Reverse order of arguments to DATEDIFF, for
-       compatibility.  Thanks to Daniel Williams
-       <Daniel.E.Williams@state.or.us> for reporting this bug.
-
-Wed Dec 13 19:30:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Implement support for DATESUM, DATEDIFF expression functions.  See
-       patch #5637.
-       
-       * helpers.c (enum date_unit): New enum.
-       [!HAVE_TRUNC] (trunc): New function.
-       (recognize_unit): New function.
-       (year_diff): New function.
-       (month_diff): New function.
-       (quarter_diff): New function.
-       (date_unit_duration): New function.
-       (expr_date_difference): New function.
-       (enum date_sum_method): New function.
-       (recognize_method): New function.
-       (add_months): New function.
-       (expr_date_sum): New function.
-       
-       * operations.def: Implement DATESUM, DATEDIFF functions.  Mark
-       VALUELABEL no_abbrev.
-
-Sun Dec 10 16:49:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       * operations.def: Implement VALUELABEL function.  Add DATEDIFF,
-       DATESUM unimplemented stubs.
-
-       * parse.c (type_coercion_core): Add support for OP_var type, which
-       is a name for a numeric or string variable.
-       (is_compatible) New function.
-       (check_operator) Only require values to be compatible with their
-       expected types, not identical.
-       (is_valid_node) Ditto.
-       (compare_names) Always return mismatch if the command name can't
-       be abbreviated.
-       (lookup_function_helper) Pass the new OPF_NO_ABBREV flag to the
-       comparison function.
-
-       * generate.pl (init_all_types): Add support for a type just called
-       "var" that may be a numeric or string variable name.  Also, add a
-       no_abbrev option that prevents a function name from being
-       abbreviated (in case of naming conflict otherwise).
-       
-       * parse.inc.pl: Output OPF_NO_ABBREV flag.
-
-       * private.h: Add OPF_NO_ABBREV flag.
-
-Wed Jul 12 21:03:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       * evaluate.c (cmd_debug_evaluate): Don't try to resize a null
-       case.
-
-Fri Jun  9 13:59:15 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * generate.pl (init_all_types): `struct fixed_string' is now
-       `struct substring'.
-
-Sun May  7 10:05:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * evaluate.c: Removed call to copy_mangle, and replaced with the
-       original buf_copy_rpad.
-
-Mon May  1 15:11:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       Prohibit LAG following TEMPORARY.  This both matches SPSS behavior
-       and fixes a bug: we saved the cases for LAG before TEMPORARY but
-       allowed access to variables created afterward anyhow (which could
-       cause a segfault).
-
-       * generate.pl: Parse "perm_only" flag on operations.
-
-       * operations.def: Add "perm_only" flag to LAG operations.
-
-       * parse.c: Disallow OPF_PERM_ONLY operations after TEMPORARY.
-
-       * parse.inc.pl: Output OPF_PERM_ONLY flag for "perm_only"
-       operations.
-
-       * private.h: Add OPF_PERM_ONLY flag.
-
-Sun Apr 23 22:06:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-       
-       * helpers.c: (expr_error) Use err_msg() instead of err_vmsg().
-       Format message ourselves.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/expressions/OChangeLog b/src/language/expressions/OChangeLog
new file mode 100644 (file)
index 0000000..18c9441
--- /dev/null
@@ -0,0 +1,147 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+
+       * evaluate.c (expr_evaluate): Use gsl_finite instead of finite, as
+       a stopgap measure for portability until appropriate gnulib modules
+       are available.
+
+       * helpers.h (copy_string): Ditto.
+
+2007-10-12  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6224.
+
+       * helpers.c: Don't need our own trunc function implementation
+       anymore, since we now use the one from gnulib.
+
+2007-07-17  Ben Pfaff  <blp@gnu.org>
+
+       Patch #19335.  Reviewed by John Darrington.
+
+       * evaluate.h.pl: Use strict and all warnings.  Fix warnings that
+       this triggers.
+
+       * evaluate.inc.pl: Ditto.
+
+       * generate.pl: Ditto.
+
+       * operations.h.pl: Ditto.
+
+       * optimize.inc.pl: Ditto.
+
+       * parse.inc.pl: Ditto.
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * parse.c (expr_get_function): New function.
+       (expr_get_function_cnt): New function.
+       (expr_operation_get_name): New function.
+       (expr_operation_get_prototype): New function.
+       (expr_operation_get_arg_cnt): New function.
+
+Thu Feb  1 06:59:27 2007  Ben Pfaff  <blp@gnu.org>
+
+       * parse.c (parse_function): Accept TO in any case for use with
+       n-ary functions.  Fixes bug #18923.  Thanks to John Darrington for
+       reporting this bug.
+
+Sat Dec 16 12:20:14 2006  Ben Pfaff  <blp@gnu.org>
+
+       * operations.def: Reverse order of arguments to DATEDIFF, for
+       compatibility.  Thanks to Daniel Williams
+       <Daniel.E.Williams@state.or.us> for reporting this bug.
+
+Wed Dec 13 19:30:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Implement support for DATESUM, DATEDIFF expression functions.  See
+       patch #5637.
+       
+       * helpers.c (enum date_unit): New enum.
+       [!HAVE_TRUNC] (trunc): New function.
+       (recognize_unit): New function.
+       (year_diff): New function.
+       (month_diff): New function.
+       (quarter_diff): New function.
+       (date_unit_duration): New function.
+       (expr_date_difference): New function.
+       (enum date_sum_method): New function.
+       (recognize_method): New function.
+       (add_months): New function.
+       (expr_date_sum): New function.
+       
+       * operations.def: Implement DATESUM, DATEDIFF functions.  Mark
+       VALUELABEL no_abbrev.
+
+Sun Dec 10 16:49:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       * operations.def: Implement VALUELABEL function.  Add DATEDIFF,
+       DATESUM unimplemented stubs.
+
+       * parse.c (type_coercion_core): Add support for OP_var type, which
+       is a name for a numeric or string variable.
+       (is_compatible) New function.
+       (check_operator) Only require values to be compatible with their
+       expected types, not identical.
+       (is_valid_node) Ditto.
+       (compare_names) Always return mismatch if the command name can't
+       be abbreviated.
+       (lookup_function_helper) Pass the new OPF_NO_ABBREV flag to the
+       comparison function.
+
+       * generate.pl (init_all_types): Add support for a type just called
+       "var" that may be a numeric or string variable name.  Also, add a
+       no_abbrev option that prevents a function name from being
+       abbreviated (in case of naming conflict otherwise).
+       
+       * parse.inc.pl: Output OPF_NO_ABBREV flag.
+
+       * private.h: Add OPF_NO_ABBREV flag.
+
+Wed Jul 12 21:03:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       * evaluate.c (cmd_debug_evaluate): Don't try to resize a null
+       case.
+
+Fri Jun  9 13:59:15 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * generate.pl (init_all_types): `struct fixed_string' is now
+       `struct substring'.
+
+Sun May  7 10:05:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * evaluate.c: Removed call to copy_mangle, and replaced with the
+       original buf_copy_rpad.
+
+Mon May  1 15:11:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       Prohibit LAG following TEMPORARY.  This both matches SPSS behavior
+       and fixes a bug: we saved the cases for LAG before TEMPORARY but
+       allowed access to variables created afterward anyhow (which could
+       cause a segfault).
+
+       * generate.pl: Parse "perm_only" flag on operations.
+
+       * operations.def: Add "perm_only" flag to LAG operations.
+
+       * parse.c: Disallow OPF_PERM_ONLY operations after TEMPORARY.
+
+       * parse.inc.pl: Output OPF_PERM_ONLY flag for "perm_only"
+       operations.
+
+       * private.h: Add OPF_PERM_ONLY flag.
+
+Sun Apr 23 22:06:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+       
+       * helpers.c: (expr_error) Use err_msg() instead of err_vmsg().
+       Format message ourselves.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 630445dfb7999862c4f4aae606ea3235e618721e..bc4e830d7ffefc010cf3283d6f237fb8dc58a880 100644 (file)
@@ -37,3 +37,5 @@ generate_from_pl = $(MKDIR_P) `dirname $@` && \
 
 .inc.pl.inc:
        $(generate_from_pl)
+
+EXTRA_DIST += src/language/expressions/OChangeLog
index 6402cc0a2a7c6f7d71f9c09fd5fe110532e22cd3..fc5b74a3ab57b7727e96226c785640e5a3e8ee43 100644 (file)
@@ -18,7 +18,6 @@
 #include "private.h"
 
 #include <ctype.h>
-#include <gsl/gsl_math.h>
 #include <libpspp/assertion.h>
 #include <libpspp/message.h>
 #include "helpers.h"
@@ -64,7 +63,7 @@ expr_evaluate (struct expression *e, const struct ccase *c, int case_idx,
           break;
 
         case OP_return_number:
-          *(double *) result = gsl_finite (ns[-1]) ? ns[-1] : SYSMIS;
+          *(double *) result = isfinite (ns[-1]) ? ns[-1] : SYSMIS;
           return;
 
         case OP_return_string:
index 59b88fc8c7a951f5b6815c157c20b7551ed486ae..85705098a2df44e2ad0e39da0764f75684bc9407 100644 (file)
@@ -589,14 +589,14 @@ ncdf_beta (double x, double a, double b, double lambda)
 double
 cdf_bvnor (double x0, double x1, double r)
 {
-  double z = x0 * x0 - 2. * r * x0 * x1 + x1 * x1;
+  double z = pow2 (x0) - 2. * r * x0 * x1 + pow2 (x1);
   return exp (-z / (2. * (1 - r * r))) * (2. * M_PI * sqrt (1 - r * r));
 }
 
 double
 idf_fdist (double P, double df1, double df2)
 {
-  double temp = gslextras_cdf_beta_Pinv (P, df1 / 2, df2 / 2);
+  double temp = gsl_cdf_beta_Pinv (P, df1 / 2, df2 / 2);
   return temp * df2 / ((1. - temp) * df1);
 }
 
index 23ca315a576667eb142b034f5d0589bdbf7a29db..895ec49bc90b30eaac7b7a1b208839fc3d6905f0 100644 (file)
@@ -4,7 +4,6 @@
 #include <ctype.h>
 #include <float.h>
 #include <gsl/gsl_cdf.h>
-#include <gsl/gsl_math.h>
 #include <gsl/gsl_randist.h>
 #include <gsl/gsl_sf.h>
 #include <limits.h>
@@ -21,7 +20,6 @@
 #include <data/value.h>
 #include <data/variable.h>
 #include <data/vector.h>
-#include <gsl-extras/gsl-extras.h>
 #include <language/expressions/public.h>
 #include <libpspp/compiler.h>
 #include <libpspp/message.h>
@@ -69,7 +67,7 @@ struct substring copy_string (struct expression *,
 static inline bool
 is_valid (double d)
 {
-  return gsl_finite (d) && d != SYSMIS;
+  return isfinite (d) && d != SYSMIS;
 }
 
 size_t count_valid (double *, size_t);
index 2ec03c34e88c06ad09d4c2ef5201a21fada479ea..ea640e18e194a27aa1d99cd6676eb495417186e7 100644 (file)
@@ -647,7 +647,7 @@ function PDF.BETA (x >= 0 && x <= 1, a > 0, b > 0)
      = gsl_ran_beta_pdf (x, a, b);
 function CDF.BETA (x >= 0 && x <= 1, a > 0, b > 0) = gsl_cdf_beta_P (x, a, b);
 function IDF.BETA (P >= 0 && P <= 1, a > 0, b > 0)
-     = gslextras_cdf_beta_Pinv (P, a, b);
+     = gsl_cdf_beta_Pinv (P, a, b);
 no_opt function RV.BETA (a > 0, b > 0) = gsl_ran_beta (get_rng (), a, b);
 function NCDF.BETA (x >= 0, a > 0, b > 0, lambda > 0)
      = ncdf_beta (x, a, b, lambda);
@@ -850,7 +850,7 @@ no_opt function RV.BERNOULLI (p >= 0 && p <= 1)
 
 // Binomial distribution.
 function CDF.BINOM (k, n > 0 && n == floor (n), p >= 0 && p <= 1)
-     = gslextras_cdf_binomial_P (k, p, n);
+     = gsl_cdf_binomial_P (k, p, n);
 function PDF.BINOM (k >= 0 && k == floor (k) && k <= n,
                     n > 0 && n == floor (n),
                     p >= 0 && p <= 1)
@@ -860,7 +860,7 @@ no_opt function RV.BINOM (p > 0 && p == floor (p), n >= 0 && n <= 1)
 
 // Geometric distribution.
 function CDF.GEOM (k >= 1 && k == floor (k), p >= 0 && p <= 1)
-     = gslextras_cdf_geometric_P (k, p);
+     = gsl_cdf_geometric_P (k, p);
 function PDF.GEOM (k >= 1 && k == floor (k),
                    p >= 0 && p <= 1)
      = gsl_ran_geometric_pdf (k, p);
@@ -871,7 +871,7 @@ function CDF.HYPER (k >= 0 && k == floor (k) && k <= c,
                     a > 0 && a == floor (a),
                     b > 0 && b == floor (b) && b <= a,
                     c > 0 && c == floor (c) && c <= a)
-     = gslextras_cdf_hypergeometric_P (k, c, a - c, b);
+     = gsl_cdf_hypergeometric_P (k, c, a - c, b);
 function PDF.HYPER (k >= 0 && k == floor (k) && k <= c,
                     a > 0 && a == floor (a),
                     b > 0 && b == floor (b) && b <= a,
@@ -890,7 +890,7 @@ no_opt extension function RV.LOG (p > 0 && p <= 1)
 
 // Negative binomial distribution.
 function CDF.NEGBIN (k >= 1, n == floor (n), p > 0 && p <= 1)
-     = gslextras_cdf_negative_binomial_P (k, p, n);
+     = gsl_cdf_negative_binomial_P (k, p, n);
 function PDF.NEGBIN (k >= 1, n == floor (n), p > 0 && p <= 1)
      = gsl_ran_negative_binomial_pdf (k, p, n);
 no_opt function RV.NEGBIN (n == floor (n), p > 0 && p <= 1) 
@@ -898,7 +898,7 @@ no_opt function RV.NEGBIN (n == floor (n), p > 0 && p <= 1)
 
 // Poisson distribution.
 function CDF.POISSON (k >= 0 && k == floor (k), mu > 0)
-     = gslextras_cdf_poisson_P (k, mu);
+     = gsl_cdf_poisson_P (k, mu);
 function PDF.POISSON (k >= 0 && k == floor (k), mu > 0)
      = gsl_ran_poisson_pdf (k, mu);
 no_opt function RV.POISSON (mu > 0) = gsl_ran_poisson (get_rng (), mu);
diff --git a/src/language/lexer/ChangeLog b/src/language/lexer/ChangeLog
deleted file mode 100644 (file)
index aea10c5..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c (lex_match_id_n): New function.
-       (lex_match_id): Reimplement in terms of lex_match_id_n.
-
-2007-08-16  Ben Pfaff  <blp@gnu.org>
-
-       Implement journaling.  Bug #17240.
-       
-       * lexer.c (lex_get_line_raw): Pass the line read to journal_write.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       Implement missing functions for subcommand integer lists.
-       
-       * subcommand-list.c (subc_list_int_create): New function.
-       (subc_list_int_push): New function.
-       (subc_list_int_count): New function.
-       (subc_list_int_at): New function.
-       (subc_list_int_destroy): New function.
-
-2007-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Abstract the documents within a dictionary a little better.
-       Thanks to John Darrington for suggestion, initial version, and
-       review.  Patch #5917.
-
-       * lexer.c (lex_entire_line): Add const to parameter.
-       (lex_entire_line_ds): Ditto.
-       (lex_rest_of_line): Drop end_dot parameter.  Update all callers to
-       use lex_end_dot instead.
-       (lex_end_dot): New function.
-
-2007-05-03  John Darrington <john@darrington.wattle.id.au>
-       
-       * lexer.c lexer.h: Added lex_is_string function.
-       
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: Fully support lists of integer values.  Add support for
-       lists of string values.  Add some more needed declarations to
-       headers.
-
-Fri Feb 16 11:14:42 2007  Ben Pfaff  <blp@gnu.org>
-
-       Better support cross-compiling by using CC_FOR_BUILD and
-       EXEEXT_FOR_BUILD for q2c.
-       
-       * automake.mk: Use EXEEXT_FOR_BUILD and CC_FOR_BUILD to build and
-       clean q2c.
-
-       * q2c.c: Avoid external dependencies, besides the standard C
-       library.
-
-Sun Feb 11 20:31:51 2007  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: Make q2c link under mingw32, by eliminating the
-       dependency on localtime.  Gnulib replaces localtime by a fixed
-       version, but we don't link q2c against gnulib.  q2c only uses
-       localtime to put the time of processing into the output file,
-       which I've never in practice found to be useful, so the patch just
-       drops this feature.
-
-Wed Dec 13 21:00:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable-parser.c (parse_variables): If not successful, set
-       output pointer to NULL and output count to 0.
-
-Sat Dec  9 18:46:11 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable-parser.h: New PV_SAME_WIDTH variable parsing option.
-
-       * variable-parser.c (add_variable): Implement new PV_SAME_WIDTH
-       option.
-       (parse_var_set_vars) Ditto.
-       (array_var_set_lookup_var_idx) Use new var_create, var_destroy
-       functions.
-
-Sat Dec  2 21:19:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       General clean-up.
-       
-       * lexer.c: (lex_token_name) Don't use a static buffer or, rather,
-       use a separate static buffer for each possible answer.
-       (lex_token_representation) Now use lex_token_name as building
-       block.  Previously this broke lex_force_match because it uses
-       lex_token_name in a call to lex_error, which in turn uses
-       lex_token_representation.
-       (lex_force_match_id) Use lex_match_id as building block, to
-       simplify.
-       (parse_id) Rewrite to work with modified lex_id_to_token and
-       lex_id_get_length.  The computation of rest_of_line is a bit of an
-       abomination but it will get fixed later.
-       
-Sat Dec  2 20:16:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c (struct lexer): Change function signature for
-       `read_line' to take an "enum getl_syntax *" instead of "bool *".
-       (lex_create) Ditto, for argument.
-       (lex_preprocess_line) New function.
-       (lex_get_line_raw) New arg, to allow caller to obtain getl_syntax
-       of the line read.
-       (lex_get_line) Use lex_get_line_raw and lex_preprocess_line to
-       simplify.
-
-Sun Nov 19 09:20:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * range-parser.c (parse_num_range): Because data_in takes an enum
-       fmt_type now, not a struct fmt_spec, change the type of the
-       corresponding argument.  Updated all callers.
-       (parse_number) Ditto.
-
-Sun Nov 12 06:34:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * format-parser.c format-parser.h lexer.c lexer.h q2c.c range-parser.c
-         range-parser.h subcommand-list.c variable-parser.c
-         variable-parser.h:
-
-       Encapsulated the lexer into an object, and updated everything
-       accordingly.
-
-Tue Oct 31 18:09:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       * range-parser.c (parse_number): Fix error message.
-
-Sat Oct 28 16:17:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * lexer.c lexer.h: Added a line_buffer (previously an external
-       reference called getl_buf). 
-
-Thu Oct 26 20:18:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c (parse_string): Make lexing of binary, hex, and octal
-       strings work (fixes bug #17948).  Allow null bytes in strings, now
-       that there's a use for them (see tests/formats/float-format.sh).
-
-Sun Jul 16 21:03:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * format-parser.h: New file.  Moved prototypes of format-parser.c
-       functions here, from lexer.h.
-
-       * format-parser.c: (parse_format_specifier_name) Rewrote and
-       changed semantics.
-       (parse_abstract_format_specifier) New function.
-       (parse_format_specifier) Rewrote in terms of
-       parse_abstract_format_specifier.  Removed "options" parameter, so
-       callers had to be updated.  Callers that didn't want messages
-       emitted were changed to use the new msg_disable/msg_enable
-       functions.
-
-       * variables-parser.c: (parse_variables_pool) New function.
-       (register_vars_pool) New function.
-       (parse_DATA_LIST_vars_pool) New function.
-       (parse_mixed_vars_pool) Use register_vars_pool.  Assert that
-       PV_APPEND is not in the options.
-       
-Sat Jul  1 17:40:38 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #11612, "q2c documentation does not agree with code".
-       
-       * q2c.c (parse_subcommand): Make "+" mean ARITY_MANY, absence
-       mean ARITY_ONCE_ONLY.
-
-Tue Jul  4 09:45:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
-       ALL) and additional underlying system file issues.
-       
-       * variable-parser.c (add_variable): Move test earlier for clarity
-       and efficiency.
-       (parse_var_set_vars) Accept ALL within a variable list, not just
-       at the beginning of one.
-
-Tue Jun 27 22:54:30 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (src_language_lexer_liblexer_a_SOURCES): Add
-       variable-parser.h.
-
-Tue Jun 27 19:15:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       Add auxiliary data pointer to q2c parse_<command> function, and
-       pass it along to the custom parser functions.
-
-       Updated all uses of custom functions in all the existing .q files.
-       
-       * q2c.c (dump_declarations): Include auxiliary parameter in
-       function prototypes.
-       (dump_subcommand) Include aux arg in calls to custom functions.
-       (dump_parser) Include aux param in parse_<command> function
-       definition.  Include aux arg in calls to custom functions.
-
-Tue Jun 27 12:07:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * variable-parser.h: New header.  Moved the var_set and variable
-       parsing declarations here.
-
-       * q2c.c (main): Emit include for new variable-parser.h header.
-
-Sun Jun 25 22:41:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c (dump_free): For SBC_DBL_LIST, enclose the output code in
-       curly braces, because it contains a variable declaration and might
-       not be at the beginning of a block.
-
-Fri Jun  9 14:02:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * q2c.c (dump_subcommand): ds_c_str() became ds_cstr(), in
-       generated code.
-
-Wed Apr 26 13:30:41 2006  Ben Pfaff  <blp@gnu.org>
-
-       * lexer.c: (lex_discard_rest_of_command) New function.
-
-Mon Apr 24 14:12:08 2006  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: Use exit.h from gnulib instead of checking for and
-       defining EXIT_SUCCESS and EXIT_FAILURE by hand.
-
-Sat Apr 15 14:30:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: Change DEBUGGING macro to DUMP_TOKENS for clarity and to
-       avoid dumping all the tokens to stdout when --enable-debug is
-       passed to configure.
-
-Fri Mar 10 08:29:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * q2c.c: (dump_free) Free proper member for var list, instead of
-       hard-coding to v_variables.  Thanks to Jason Stover for reporting
-       this bug.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/lexer/OChangeLog b/src/language/lexer/OChangeLog
new file mode 100644 (file)
index 0000000..aea10c5
--- /dev/null
@@ -0,0 +1,235 @@
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c (lex_match_id_n): New function.
+       (lex_match_id): Reimplement in terms of lex_match_id_n.
+
+2007-08-16  Ben Pfaff  <blp@gnu.org>
+
+       Implement journaling.  Bug #17240.
+       
+       * lexer.c (lex_get_line_raw): Pass the line read to journal_write.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       Implement missing functions for subcommand integer lists.
+       
+       * subcommand-list.c (subc_list_int_create): New function.
+       (subc_list_int_push): New function.
+       (subc_list_int_count): New function.
+       (subc_list_int_at): New function.
+       (subc_list_int_destroy): New function.
+
+2007-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Abstract the documents within a dictionary a little better.
+       Thanks to John Darrington for suggestion, initial version, and
+       review.  Patch #5917.
+
+       * lexer.c (lex_entire_line): Add const to parameter.
+       (lex_entire_line_ds): Ditto.
+       (lex_rest_of_line): Drop end_dot parameter.  Update all callers to
+       use lex_end_dot instead.
+       (lex_end_dot): New function.
+
+2007-05-03  John Darrington <john@darrington.wattle.id.au>
+       
+       * lexer.c lexer.h: Added lex_is_string function.
+       
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: Fully support lists of integer values.  Add support for
+       lists of string values.  Add some more needed declarations to
+       headers.
+
+Fri Feb 16 11:14:42 2007  Ben Pfaff  <blp@gnu.org>
+
+       Better support cross-compiling by using CC_FOR_BUILD and
+       EXEEXT_FOR_BUILD for q2c.
+       
+       * automake.mk: Use EXEEXT_FOR_BUILD and CC_FOR_BUILD to build and
+       clean q2c.
+
+       * q2c.c: Avoid external dependencies, besides the standard C
+       library.
+
+Sun Feb 11 20:31:51 2007  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: Make q2c link under mingw32, by eliminating the
+       dependency on localtime.  Gnulib replaces localtime by a fixed
+       version, but we don't link q2c against gnulib.  q2c only uses
+       localtime to put the time of processing into the output file,
+       which I've never in practice found to be useful, so the patch just
+       drops this feature.
+
+Wed Dec 13 21:00:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable-parser.c (parse_variables): If not successful, set
+       output pointer to NULL and output count to 0.
+
+Sat Dec  9 18:46:11 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable-parser.h: New PV_SAME_WIDTH variable parsing option.
+
+       * variable-parser.c (add_variable): Implement new PV_SAME_WIDTH
+       option.
+       (parse_var_set_vars) Ditto.
+       (array_var_set_lookup_var_idx) Use new var_create, var_destroy
+       functions.
+
+Sat Dec  2 21:19:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       General clean-up.
+       
+       * lexer.c: (lex_token_name) Don't use a static buffer or, rather,
+       use a separate static buffer for each possible answer.
+       (lex_token_representation) Now use lex_token_name as building
+       block.  Previously this broke lex_force_match because it uses
+       lex_token_name in a call to lex_error, which in turn uses
+       lex_token_representation.
+       (lex_force_match_id) Use lex_match_id as building block, to
+       simplify.
+       (parse_id) Rewrite to work with modified lex_id_to_token and
+       lex_id_get_length.  The computation of rest_of_line is a bit of an
+       abomination but it will get fixed later.
+       
+Sat Dec  2 20:16:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c (struct lexer): Change function signature for
+       `read_line' to take an "enum getl_syntax *" instead of "bool *".
+       (lex_create) Ditto, for argument.
+       (lex_preprocess_line) New function.
+       (lex_get_line_raw) New arg, to allow caller to obtain getl_syntax
+       of the line read.
+       (lex_get_line) Use lex_get_line_raw and lex_preprocess_line to
+       simplify.
+
+Sun Nov 19 09:20:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * range-parser.c (parse_num_range): Because data_in takes an enum
+       fmt_type now, not a struct fmt_spec, change the type of the
+       corresponding argument.  Updated all callers.
+       (parse_number) Ditto.
+
+Sun Nov 12 06:34:06 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * format-parser.c format-parser.h lexer.c lexer.h q2c.c range-parser.c
+         range-parser.h subcommand-list.c variable-parser.c
+         variable-parser.h:
+
+       Encapsulated the lexer into an object, and updated everything
+       accordingly.
+
+Tue Oct 31 18:09:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * range-parser.c (parse_number): Fix error message.
+
+Sat Oct 28 16:17:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * lexer.c lexer.h: Added a line_buffer (previously an external
+       reference called getl_buf). 
+
+Thu Oct 26 20:18:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c (parse_string): Make lexing of binary, hex, and octal
+       strings work (fixes bug #17948).  Allow null bytes in strings, now
+       that there's a use for them (see tests/formats/float-format.sh).
+
+Sun Jul 16 21:03:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * format-parser.h: New file.  Moved prototypes of format-parser.c
+       functions here, from lexer.h.
+
+       * format-parser.c: (parse_format_specifier_name) Rewrote and
+       changed semantics.
+       (parse_abstract_format_specifier) New function.
+       (parse_format_specifier) Rewrote in terms of
+       parse_abstract_format_specifier.  Removed "options" parameter, so
+       callers had to be updated.  Callers that didn't want messages
+       emitted were changed to use the new msg_disable/msg_enable
+       functions.
+
+       * variables-parser.c: (parse_variables_pool) New function.
+       (register_vars_pool) New function.
+       (parse_DATA_LIST_vars_pool) New function.
+       (parse_mixed_vars_pool) Use register_vars_pool.  Assert that
+       PV_APPEND is not in the options.
+       
+Sat Jul  1 17:40:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #11612, "q2c documentation does not agree with code".
+       
+       * q2c.c (parse_subcommand): Make "+" mean ARITY_MANY, absence
+       mean ARITY_ONCE_ONLY.
+
+Tue Jul  4 09:45:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
+       ALL) and additional underlying system file issues.
+       
+       * variable-parser.c (add_variable): Move test earlier for clarity
+       and efficiency.
+       (parse_var_set_vars) Accept ALL within a variable list, not just
+       at the beginning of one.
+
+Tue Jun 27 22:54:30 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (src_language_lexer_liblexer_a_SOURCES): Add
+       variable-parser.h.
+
+Tue Jun 27 19:15:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       Add auxiliary data pointer to q2c parse_<command> function, and
+       pass it along to the custom parser functions.
+
+       Updated all uses of custom functions in all the existing .q files.
+       
+       * q2c.c (dump_declarations): Include auxiliary parameter in
+       function prototypes.
+       (dump_subcommand) Include aux arg in calls to custom functions.
+       (dump_parser) Include aux param in parse_<command> function
+       definition.  Include aux arg in calls to custom functions.
+
+Tue Jun 27 12:07:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * variable-parser.h: New header.  Moved the var_set and variable
+       parsing declarations here.
+
+       * q2c.c (main): Emit include for new variable-parser.h header.
+
+Sun Jun 25 22:41:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c (dump_free): For SBC_DBL_LIST, enclose the output code in
+       curly braces, because it contains a variable declaration and might
+       not be at the beginning of a block.
+
+Fri Jun  9 14:02:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * q2c.c (dump_subcommand): ds_c_str() became ds_cstr(), in
+       generated code.
+
+Wed Apr 26 13:30:41 2006  Ben Pfaff  <blp@gnu.org>
+
+       * lexer.c: (lex_discard_rest_of_command) New function.
+
+Mon Apr 24 14:12:08 2006  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: Use exit.h from gnulib instead of checking for and
+       defining EXIT_SUCCESS and EXIT_FAILURE by hand.
+
+Sat Apr 15 14:30:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: Change DEBUGGING macro to DUMP_TOKENS for clarity and to
+       avoid dumping all the tokens to stdout when --enable-debug is
+       passed to configure.
+
+Fri Mar 10 08:29:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * q2c.c: (dump_free) Free proper member for var list, instead of
+       hard-coding to v_variables.  Thanks to Jason Stover for reporting
+       this bug.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index f8d6996349752cb186cb31b040022d533710bb64..0ce371afb8b6c37c36b81478c76108ec70eab3fb 100644 (file)
@@ -17,7 +17,9 @@ EXTRA_DIST += src/language/lexer/q2c.c
 
 src/language/lexer/q2c$(EXEEXT_FOR_BUILD): $(top_srcdir)/src/language/lexer/q2c.c 
        @$(MKDIR_P) `dirname $@`
-       $(CC_FOR_BUILD) $(top_srcdir)/src/language/lexer/q2c.c -o $(top_builddir)/src/language/lexer/q2c
+       $(CC_FOR_BUILD) $(top_srcdir)/src/language/lexer/q2c.c -o $(top_builddir)/src/language/lexer/q2c$(EXEEXT_FOR_BUILD)
 
 
 CLEANFILES += src/language/lexer/q2c$(EXEEXT_FOR_BUILD)
+
+EXTRA_DIST += src/language/lexer/OChangeLog
index 1c9542d78ed54ccf5271811b5cc27be54337aeae..cc8cab808948973b08e9145f337edf8028afb70b 100644 (file)
@@ -295,6 +295,7 @@ lex_get (struct lexer *lexer)
          break;
 
        case '(': case ')': case ',': case '=': case '+': case '/':
+        case '[': case ']':
          lexer->token = *lexer->prog++;
          break;
 
@@ -1304,3 +1305,28 @@ lex_tokstr (const struct lexer *lexer)
 {
   return &lexer->tokstr;
 }
+
+/* If the lexer is positioned at the (pseudo)identifier S, which
+   may contain a hyphen ('-'), skips it and returns true.  Each
+   half of the identifier may be abbreviated to its first three
+   letters.
+   Otherwise, returns false. */
+bool
+lex_match_hyphenated_word (struct lexer *lexer, const char *s)
+{
+  const char *hyphen = strchr (s, '-');
+  if (hyphen == NULL)
+    return lex_match_id (lexer, s);
+  else if (lexer->token != T_ID
+          || !lex_id_match (ss_buffer (s, hyphen - s), ss_cstr (lexer->tokid))
+          || lex_look_ahead (lexer) != '-')
+    return false;
+  else
+    {
+      lex_get (lexer);
+      lex_force_match (lexer, '-');
+      lex_force_match_id (lexer, hyphen + 1);
+      return true;
+    }
+}
+
index 53732b49995f5fb60429e96f65e89a61ca108f4c..9e5d09aec03f8dee7f96dcd73e7067f650ca9a22 100644 (file)
@@ -55,6 +55,8 @@ bool lex_match (struct lexer *, int);
 bool lex_match_id (struct lexer *, const char *);
 bool lex_match_id_n (struct lexer *, const char *, size_t n);
 bool lex_match_int (struct lexer *, int);
+bool lex_match_hyphenated_word (struct lexer *lexer, const char *s);
+
 
 /* Forcible matching functions. */
 bool lex_force_match (struct lexer *, int);
index d14c69d0febec3d7d14b36f87bc94477fd0ecb7e..ea4e348148b29febf66718075ca8aabfef77eb29 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2008 Free Software Foundation, Inc.
 
    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
@@ -357,6 +357,44 @@ dump_token (void)
 }
 #endif /* DUMP_TOKENS */
 
+
+const char hyphen_proxy = '_';
+
+static void
+id_cpy (char **cp)
+{
+  char *dest = tokstr;
+  char *src = *cp;
+
+  while (*src == '_' || *src == '-' || isalnum ((unsigned char) *src))
+    {
+      *dest++ = *src == '-' ? hyphen_proxy :toupper ((unsigned char) (*src));
+      src++;
+    }
+
+  *cp = src;
+  *dest++ = '\0';
+}
+
+static char *
+unmunge (const char *s)
+{
+  char *dest = xmalloc (strlen (s));
+  char *d = dest;
+
+  while (*s)
+    {
+      if (*s == hyphen_proxy)
+       *d = '-';
+      else
+       *d = *s;
+      s++;
+      d++;
+    }
+
+  return dest;
+}
+
 /* Reads a token from the input file. */
 static int
 lex_get (void)
@@ -398,9 +436,8 @@ lex_get (void)
     {
       char *dest = tokstr;
       token = T_ID;
-      while (*cp == '_' || isalnum ((unsigned char) *cp))
-       *dest++ = toupper ((unsigned char) (*cp++));
-      *dest++ = '\0';
+
+      id_cpy (&cp);
     }
   else
     token = *cp++;
@@ -1374,7 +1411,11 @@ make_match (const char *t)
   else if (isdigit ((unsigned char) t[0]))
     sprintf (s, "lex_match_int (lexer, %s)", t);
   else
-    sprintf (s, "lex_match_id (lexer, \"%s\")", t);
+    {
+      char *c = unmunge (t);
+      sprintf (s, "lex_match_hyphenated_word (lexer, \"%s\")", c);
+      free (c);
+    }
 
   return s;
 }
index d3d5a40f9683deff33be24a8a60a457906aea0b2..6df3f96b69a980626f1fcffee0d6d91f038345ba 100644 (file)
@@ -2,9 +2,11 @@ correlations.c
 crosstabs.c
 examine.c
 frequencies.c
+glm.c
 means.c
 npar.c
 oneway.c
 rank.c
 regression.c
+reliability.c
 t-test.c
diff --git a/src/language/stats/ChangeLog b/src/language/stats/ChangeLog
deleted file mode 100644 (file)
index 58e96fb..0000000
+++ /dev/null
@@ -1,632 +0,0 @@
-2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (reg_stats_coeff): Use new accessor function
-       pspp_coeff_get_sd. Fixed bug 23567. No longer call compute_moments
-       in run_regression. Pass entire design_matrix to pspp_linreg ().
-
-2008-05-29  John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q: Fixed bug where incorrect levels of dereferencing
-       were applied to pointers.
-
-2008-04-09  John Darrington <john@darrington.wattle.id.au>
-
-       * regression.q: Fix display of degrees of freedom.
-
-2008-04-08  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (identify_indep_vars): Don't panic unless
-       n_indep_vars is 0.
-
-2008-03-16  Ben Pfaff  <blp@gnu.org>
-
-       Bug #22037.  Thanks to John Darrington for reporting this bug.
-       
-       * crosstabs.q (calc_general): Only the short string prefix of long
-       string variables are tabulated, so we must not copy or zero out
-       more data than that.
-
-2008-03-10  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (run_regression): Removed code for EXPORT
-       subcommand. Remove use of coefficient 0 as the intercept.
-
-2008-02-14  John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q: Fixed counts of missing variables.  Thanks to 
-       Jason Stover for reporting this problem.
-
-2008-01-02  John Darrington <john@darrington.wattle.id.au>
-
-       *  binomial.c chisquare.c examine.q frequencies.q oneway.q regression.q : updated
-       all users of var_get_value_name to use replacement function var_append_value_name.
-
-2007-12-07  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6302.
-
-       * crosstabs.q (precalc): Initialize data structures even if the
-       first case cannot be read.  
-
-       * frequencies.q (precalc): Ditto.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * aggregate.c (cmd_aggregate): Manage file handle reference
-       counts.
-
-       * correlations.q (internal_cmd_frequencies): Ditto.
-       (cor_custom_matrix): Ditto.
-
-       * regression.q (regression_custom_export): Ditto.
-       (cmd_regression): Ditto.
-
-2007-10-12  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (flip_file): No need to conditionally substitute for
-       "fseeko" and "off_t" manually anymore, as gnulib takes care of it
-       for us.
-
-2007-09-21  Jason Stover  <jhs@wonko.gcsu.edu>
-
-       * regression.q (run_regression): Partial fix of memory leak, bug
-       21056.
-
-2007-09-19  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #21108.
-       
-       * aggregate.c (cmd_aggregate): Destroy casereader consistently,
-       even if casereader fails.
-
-       * examine.q (run_examine): Ditto.
-        
-       * glm.q (run_glm): Ditto.
-
-       * oneway.q (run_oneway): Ditto.
-
-       * regression.q (run_regression): Ditto.
-
-       * t-test.q (calculate): Ditto.
-
-       * descriptives.c (calc_descriptives): Ditto.  Also avoid
-       gratuitous casereader_clone.
-
-2007-09-13  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (cmd_regression): Move declaration of models in to
-       definition of cmd_regression.
-
-       * regression.q (run_regression): Free mom to fix memory leak.
-
-2007-09-12  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q (postcalc): Free sorted_tab and the structures that
-       it points to, to plug a memory leak.  Fixes bug #20910.  Thanks to
-       John Darrington for reporting this bug and for review.
-
-2007-09-04  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q (cmd_crosstabs): Free xtab and the structures that
-       it points to, to plug a memory leak.  Fixes bug #18315.
-
-2007-08-15  Jason Stover  <jhs@wonko.gcsu.edu>
-
-       * regression.q (identify_indep_vars): Print an error if dependent
-       and independent variables are the same. Fixes bug 19819.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c: Drop use of dict_get_compacted_dict_index_to_case_index
-       and just use the ordinary case indexes.  There seemed to be no
-       reason for the former method.
-
-2007-08-03  Ben Pfaff  <blp@gnu.org>
-
-       * rank.q (rank_cmd): Instead of sorting by SPLIT FILE vars, group
-       by them.  Fixes bug #17239.
-       Reviewed by John Darrington.
-
-2007-08-01  Ben Pfaff  <blp@gnu.org>
-
-       Clean up handling of median, by treating it almost like any other
-       percentile.  Fixes bug #17424.  Thanks to John Darrington for
-       review.
-       * frequencies.q (internal_cmd_frequencies): Fix handling of bit
-       masks for `stats' variable.  If median is selected, turn it off
-       and add a 50th percentile.
-       (add_percentile): Simplify code a little.
-       (calc_stats): Drop special casing of median.
-       (dump_statistics): Ditto, except that we label the 50th percentile
-       as "50 (Median)" to make it clear that it's also the median.    
-
-2007-07-31  Ben Pfaff  <blp@gnu.org>
-
-       Remove integer mode from FREQUENCIES and incidentally fix bug
-       #17421.  Reviewed by John Darrington.
-       * frequencies.q (int_pool): Rename data_pool.
-       (gen_pool): Rename syntax_pool.
-       (enum FRQM_*): Removed.
-       (struct freq_tab): Removed `mode', `vector', `min', `max',
-       `out_of_range', `sysmis' members.
-       (calc): Delete support for integer mode.
-       (precalc): Ditto.
-       (postprocess_freq_tab): Ditto.
-       (cleanup_freq_tab): Ditto.
-       (frq_custom_variables): Ditto.
-
-2007-07-28 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q: Moved the order in which groups are displayed in the 
-       independent samples case, where a cut point is given.
-
-2007-07-27  Ben Pfaff  <blp@gnu.org>
-
-       * regression.q (run_regression): Move casereader_destroy call so
-       that it always gets called, not just if there was some valid
-       data.  Fixes bug #19581.
-       Reviewed by Jason Stover.
-
-2007-07-24  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (struct flip_pgm): Remove `case_size' member (now
-       unused).
-       (cmd_flip): Pass var_cnt as number of cases instead of case_cnt,
-       to fix bug #20494.  Don't assign to `case_size' member, which was
-       unused after assignment.
-       (build_dictionary): When NEWNAMES not used, get the number of
-       variables right, to fix bug #20493.
-
-2007-07-10  Jason Stover  <jhs@math.gcsu.edu>
-
-       * glm.q: Initial version of the GLM procedure.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-       
-       * aggregate.c: Simplify greatly since everything is more uniform
-       now.
-
-       * autorecode.c: Adapt to new procedure code.
-       * binomial.c: Ditto.
-       * chisquare.c: Ditto.
-       * crosstabs.q: Ditto.
-       * descriptives.c: Ditto.
-       * examine.q: Ditto.
-       * npar-summary.c: Ditto.
-       * frequencies.q: Ditto.
-       * npar.q: Ditto.
-       * oneway.q: Ditto.
-       * regression.q: Ditto.
-       * sort-cases.c: Ditto.
-       * t-test.c: Ditto.
-
-       * sort-criteria.c: Rewrite to output a struct case_ordering.
-       
-       * flip.c: Rewrite to be a casereader.
-
-       * rank.q: Simplify greatly since casereaders are much more
-       flexible than what we had before.
-       
-2007-05-15  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (run_regression): Tell the user when the data
-       contain no valid cases.
-
-2007-05-08  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: Partial fix of bug which caused a crash if
-       dependent variable and independent variable were the same.
-
-2007-04-16 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q: Changed the output width of reported counts and 
-       degrees of freedom, to avoid truncating these values.  Thanks
-        to Seth Woolley for reporting this problem.  A proper fix involves
-        re-thinking the output driver.
-
-2007-04-12  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (run_regression): Added if (n_data >0) to fix bug
-       19581.
-
-2007-03-29  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (prepare_data): New function.
-
-       * regression.q (compute_moments): New function.
-
-2007-03-18  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q (static var write): Rename write_style to avoid
-       conflict with POSIX function of same name.
-
-2007-03-16  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (run_regression): Added support for moments.
-
-Sat Feb 17 08:16:00 2007  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (flip_sink_create): Improve error message when temporary
-       file cannot be created.
-
-Tue Feb  6 19:58:03 2007  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (flip_file): Give better error message on end-of-file.
-
-2007-02-04  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: Fixed p-value computation in the test for
-       individual regression coefficients.
-
-Mon Jan 15 11:03:20 2007  Ben Pfaff  <blp@gnu.org>
-
-       Fix bugs found by valgrind when --enable-debug is used with the
-       new case code.  These bugs are hidden when the data set is small
-       enough to find in memory; if a bigger data set that would overflow
-       to disk were used, then data corruption would occur.
-
-       * chisquare.c (create_freq_hash): Pass free_freq_mutable_hash to
-       hsh_create as free function.  Make copy of data put into hash.
-
-       * oneway.q (free_value): New function.
-       (run_oneway): Use free_value as arg to hsh_create.  Make copy of
-       data put into hash.
-
-       * rank.q (rank_cases): Don't access data in case after we've given
-       away the case.
-
-Tue Jan  9 19:16:11 2007  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #18739.
-       
-       * aggregate.c (parse_aggregate_functions) Initialize
-       function_name.
-
-Fri Dec 22 14:04:09 2006  Ben Pfaff  <blp@gnu.org>
-
-       Simplify missing value handling.
-       
-       * aggregate.c (struct agr_var): Remove `bool include_missing', add
-       `enum mv_class exclude'.  Remove `int missing', add `bool
-       saw_missing'.  Update users.
-
-       * descriptives.c (struct dsc_trns): Removed `int
-       include_user_missing', add `enum mv_class exclude'.  Update users.
-       (struct dsc_proc): Ditto.
-
-       * examine.q: (static var value_is_missing): Rename
-       `exclude_values', change type to `enum mv_class'.  Update users.
-
-       * rank.q: Ditto.
-
-Fri Dec 22 19:22:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * frequencies.q : Fixed bug #17420, where the table bounds were overun
-       when /FORMAT=nolabels was given.
-
-Wed Dec 20 18:45:31 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * binomial.c binomial.h : New files.  Thanks to Jason Stover 
-          for assistance with these.
-
-       * chisquare.c chisquare.h freq.c freq.h npar-summary.c npar-summary.h 
-         npar.h npar.q: New files.  Implementing NPAR TESTS.
-
-       * frequencies.q  : Moved  structure definitions into freq.[ch]
-
-Sat Dec 16 22:26:44 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make it possible to pull cases from the active file with a
-       function call, instead of requiring indirection through a callback
-       function.
-
-       * aggregate.c (cmd_aggregate): Take advantage of new procedure
-       interface.
-       (agr_to_active_file): Removed.
-       (presorted_agr_to_sysfile): Removed.
-
-       * autorecode.c (cmd_autorecode): Take advantage of new procedure
-       interface.
-       (autorecode_proc_func): Removed.
-
-       * flip.c (struct flip_pgm): New members to allow conformance with
-       new case_source_class interface.
-       (cmd_flip): Adapt to new case_source_class interface.
-       (flip_source_read): Ditto.
-       (flip_source_destroy): Ditto.
-
-Sat Dec 16 12:54:27 2006  Ben Pfaff  <blp@gnu.org>
-
-       * rank.q (rank_custom_variables): Allow grouping variables to be
-       strings.  Fixes bug #18533.  Thanks to John Darrington for review.
-
-Sat Dec  9 18:47:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       * regression.q (is_depvar): Compare variable pointers instead of
-       variable names.
-
-Thu Dec  7 15:26:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * examine.q: Allocated the categorical values for the dependent and 
-       independent variables, on the heap.  Hence they can be of any width.
-
-Wed Dec  6 21:14:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       * regression.q (reg_inserted): Compare variable pointers instead
-       of variable indexes.
-
-Mon Dec  4 22:33:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q (insert_summary): Use var_to_string for labeling.
-       (output_pivot_table) Ditto.
-       (submit) Ditto.
-
-       * frequencies.q (setup_z_trns): Ditto.
-       (dump_full) Ditto.
-       (dump_condensed) Ditto.
-       (dump_statistics) Ditto.
-       
-
-Sun Nov  5 08:31:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * t-test.q, oneway.q: Changed to use the new casefilter structure.
-
-Sat Oct 14 16:52:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       * rank.q: (rank_sorted_casefile) Add some missing case_destroy()
-       calls to fix a memory leak.
-
-Sun Oct  8 09:45:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * rank.q: Plugged a small memory leak which occurred under error
-       conditions.
-       
-Sat Oct  7 11:06:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * rank.q: Implemented most of the RANK command.
-
-2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (run_regression): New function to move knowledge of
-       pspp_linreg_cache out of math/coefficient.[ch].
-
-Sat Jul  1 17:41:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #11612, "q2c documentation does not agree with code".
-       
-       * examine.q: Audit use of q2c "+" prefixes that indicate that a
-       command may appear multiple times.
-
-       * frequencies.q: Ditto.
-
-       * oneway.q: Ditto.
-
-       * regression.q: Ditto.
-
-       * t-test.q: Ditto.
-
-Fri Jun 23 14:18:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       Support long string variables on FREQUENCIES, as
-       an extension when in enhanced algorithms mode.  For Greg Hunt
-       <greg@firmansyah.com>.
-       
-       * frequencies.q: (struct freq) Change `v' member from union value
-       to union value *.  Update all references.
-       (struct var_freqs) Add width, print members to represent effective
-       variable width and display format.
-       (calc) Copy entire long string value into the hash table.
-       (frq_custom_variables) Set new width, print members.
-       (hash_value_alpha) Get width from var_freqs.
-       (compare_value_alpha_a) Ditto.
-       (compare_freq_alpha_a) Ditto.
-       (compare_freq_alpha_d) Ditto.
-       (dump_full) Get display format from var_freqs.
-       (dump_condensed) Ditto.
-
-Mon Jun 19 22:07:13 2006  Ben Pfaff  <blp@gnu.org>
-
-       * frequencies.q: (dump_full) Only put the first MAX_SHORT_STRING
-       bytes of string variables into the output cells, seeing as we only
-       copy that many.
-       (dump_condensed) Ditto.
-
-Mon Jun 19 21:52:05 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fixes a bug reported by Greg Hunt <greg@firmansyah.com>.
-       
-       * frequencies.q: (hsh_hash_bytes) We only copy the first
-       MAX_SHORT_STRING bytes of string variables, so we must only
-       compare that many bytes, even if the string variable is longer.
-       (compare_value_alpha_a) Ditto.
-       (compare_freq_alpha_a) Ditto.
-       (compare_freq_alpha_d) Ditto.
-
-2006-05-11  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: Adjusted code to account for cache->coeff being a
-       pspp_linreg_coeff **.
-
-Sun May  7 18:31:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix memory leak.
-       
-       * aggregate.c (cmd_aggregate): Free default_dict before replacing
-       it.
-
-Sun May  7 17:09:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (flip_file): Check return value of pool_fclose().
-
-Sat May  6 16:00:13 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of `char *c' member in union value, for cleanliness.
-       
-       * aggregate.c: (union agr_argument) New union.
-       (struct agr_var) Change element type of arg[] from union value to
-       union agr_argument.
-       (parse_aggregate_functions) Change local variable types likewise.
-
-       * autorecode.c: (union arc_value) New union.
-       (struct arc_item) Change "from" from union value to union
-       arc_value.
-       (recode) Change local variable from union value to union
-       arc_value.
-       (autorecode_trns_proc) Ditto.
-       (compare_alpha_value) Ditto.
-       (hash_alpha_value) Ditto.
-       (compare_numeric_value) Ditto.
-       (hash_numeric_value) Ditto.
-       (autorecode_proc_func) Ditto.
-
-Sat May  6 10:43:33 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       the output code for SPLIT FILE groups in procedure.c, which really
-       shouldn't be doing any output.  Move it into the individual
-       procedures instead.  This also adds some flexibility.
-
-       * crosstabs.q (precalc): Call output_split_file_values().
-
-       * descriptives.c (calc_descriptives): Ditto.
-
-       * examine.q (run_examine): Ditto.
-       
-       * frequencies.q (precalc): Ditto.
-
-       * oneway.q (run_oneway): Ditto.
-
-       * regression.q (run_regression): Ditto.
-
-       * t-test.q (calculate): Ditto.
-
-Wed May  3 23:05:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * aggregate.c (cmd_aggregate) Use discard_variables().
-       
-2006-04-28  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (regression_trns_resid_proc): Pass only the
-       variables used in the model to (*model->residual)().
-
-       * regression.q (regression_trns_pred_proc): Pass only the
-       variables used in the model to (*model->pred)().
-
-2006-04-26  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: Added support for multiple transformations.
-       
-       * regression.q (regression_trns_resid_proc): New function.
-
-       * regression.q (regression_trns_pred_proc): New function.
-
-       * regression.q (subcommand_save): Added support for saving
-       predicted values.
-
-       * regression.q (regression_trns_free): New function. 
-
-       * regression.q (reg_get_name): New function.
-
-       * regression.q (reg_save_var): New function.
-
-Tue Apr 25 13:18:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * rank.q (parse_rank_function): Use SE instead of ME for parse
-       errors.
-
-Tue Apr 25 13:16:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       * flip.c (flip_sink_write): Use snprintf() to simplify a bit of
-       code.
-
-2006-04-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (try_name): New function. (Partly copied from
-       try_name in descriptives.c.)
-
-       * regression.q (subcommand_save): Choose residual variable names
-       correctly. 
-
-2006-04-20  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (cmd_regression): Moved call to subcommand_save()
-       outside multipass_procedure_with_splits().
-       
-       * regression.q (regression_trns_proc): Fixed value counter n_vals
-       before calling *model->residual().
-
-2006-04-19  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (regression_trns_proc): Fixed the look-up of the
-       number of variables.
-
-2006-04-18  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (regression_trns_proc): Look up the residual
-       variable in the linear regression cache.
-
-       * regression.q (subcommand_save): Set the residual variable in the
-       linear regression cache.
-
-2006-04-17  Jason Stover  <jason@wonko.gcsu.edu>
-
-       * regression.q (regression_trns_proc): Accept case_idx as an int
-       to match the definition of trns_proc_func.
-
-2006-04-17  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (regression_trns_proc): New function.
-
-       * regression.q (subcommand_save): Create variable residuals and
-       add a transformation to assign values to them. Also free the
-       linreg_cache if the SAVE command was not called. Removed the
-       casereading loop. Placed actual computation of residuals in
-       regression_trns_proc.
-
-       * regression.q (run_regression): Moved call to free
-       pspp_linreg_cache to subcommand_save.
-
-Sat Apr 15 18:01:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       * examine.q (output_examine): Add casts to fix warnings.
-
-2006-04-07  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q (subcommand_save): New function.
-
-2006-04-04  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: New function reg_has_categorical () to tell
-       whether a pspp_linreg_struct was made with any variables of type
-       ALPHA.
-
-       * regression.q: (subcommand_export): Call
-       reg_print_categorical_encoding() only if the model uses any
-       categorical variables.
-
-Mon Mar 27 16:00:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.q: (output_pivot_table) Drop spurious space from
-       message.
-
-2006-03-15  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.q: Added custom syntax parser for VARIABLES subcommand
-
-       * regression.q: Moved most instructions for run_regression ()
-       inside the loop over dependent variables.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/stats/OChangeLog b/src/language/stats/OChangeLog
new file mode 100644 (file)
index 0000000..9dfdb06
--- /dev/null
@@ -0,0 +1,644 @@
+2008-07-24  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * glm.q (run_glm): Dropped weight argument.
+
+2008-07-22  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * glm.q (run_glm): Re-written to form covariance matrix rather
+       than store entire data set in memory.
+
+       * glm.q (data_pass_one): Renamed prepare_categories() to
+       data_pass_one(). Accumulate mean and variance.
+
+2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (reg_stats_coeff): Use new accessor function
+       pspp_coeff_get_sd. Fixed bug 23567. No longer call compute_moments
+       in run_regression. Pass entire design_matrix to pspp_linreg ().
+
+2008-05-29  John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q: Fixed bug where incorrect levels of dereferencing
+       were applied to pointers.
+
+2008-04-09  John Darrington <john@darrington.wattle.id.au>
+
+       * regression.q: Fix display of degrees of freedom.
+
+2008-04-08  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (identify_indep_vars): Don't panic unless
+       n_indep_vars is 0.
+
+2008-03-16  Ben Pfaff  <blp@gnu.org>
+
+       Bug #22037.  Thanks to John Darrington for reporting this bug.
+       
+       * crosstabs.q (calc_general): Only the short string prefix of long
+       string variables are tabulated, so we must not copy or zero out
+       more data than that.
+
+2008-03-10  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (run_regression): Removed code for EXPORT
+       subcommand. Remove use of coefficient 0 as the intercept.
+
+2008-02-14  John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q: Fixed counts of missing variables.  Thanks to 
+       Jason Stover for reporting this problem.
+
+2008-01-02  John Darrington <john@darrington.wattle.id.au>
+
+       *  binomial.c chisquare.c examine.q frequencies.q oneway.q regression.q : updated
+       all users of var_get_value_name to use replacement function var_append_value_name.
+
+2007-12-07  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6302.
+
+       * crosstabs.q (precalc): Initialize data structures even if the
+       first case cannot be read.  
+
+       * frequencies.q (precalc): Ditto.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * aggregate.c (cmd_aggregate): Manage file handle reference
+       counts.
+
+       * correlations.q (internal_cmd_frequencies): Ditto.
+       (cor_custom_matrix): Ditto.
+
+       * regression.q (regression_custom_export): Ditto.
+       (cmd_regression): Ditto.
+
+2007-10-12  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (flip_file): No need to conditionally substitute for
+       "fseeko" and "off_t" manually anymore, as gnulib takes care of it
+       for us.
+
+2007-09-21  Jason Stover  <jhs@wonko.gcsu.edu>
+
+       * regression.q (run_regression): Partial fix of memory leak, bug
+       21056.
+
+2007-09-19  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #21108.
+       
+       * aggregate.c (cmd_aggregate): Destroy casereader consistently,
+       even if casereader fails.
+
+       * examine.q (run_examine): Ditto.
+        
+       * glm.q (run_glm): Ditto.
+
+       * oneway.q (run_oneway): Ditto.
+
+       * regression.q (run_regression): Ditto.
+
+       * t-test.q (calculate): Ditto.
+
+       * descriptives.c (calc_descriptives): Ditto.  Also avoid
+       gratuitous casereader_clone.
+
+2007-09-13  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (cmd_regression): Move declaration of models in to
+       definition of cmd_regression.
+
+       * regression.q (run_regression): Free mom to fix memory leak.
+
+2007-09-12  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q (postcalc): Free sorted_tab and the structures that
+       it points to, to plug a memory leak.  Fixes bug #20910.  Thanks to
+       John Darrington for reporting this bug and for review.
+
+2007-09-04  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q (cmd_crosstabs): Free xtab and the structures that
+       it points to, to plug a memory leak.  Fixes bug #18315.
+
+2007-08-15  Jason Stover  <jhs@wonko.gcsu.edu>
+
+       * regression.q (identify_indep_vars): Print an error if dependent
+       and independent variables are the same. Fixes bug 19819.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c: Drop use of dict_get_compacted_dict_index_to_case_index
+       and just use the ordinary case indexes.  There seemed to be no
+       reason for the former method.
+
+2007-08-03  Ben Pfaff  <blp@gnu.org>
+
+       * rank.q (rank_cmd): Instead of sorting by SPLIT FILE vars, group
+       by them.  Fixes bug #17239.
+       Reviewed by John Darrington.
+
+2007-08-01  Ben Pfaff  <blp@gnu.org>
+
+       Clean up handling of median, by treating it almost like any other
+       percentile.  Fixes bug #17424.  Thanks to John Darrington for
+       review.
+       * frequencies.q (internal_cmd_frequencies): Fix handling of bit
+       masks for `stats' variable.  If median is selected, turn it off
+       and add a 50th percentile.
+       (add_percentile): Simplify code a little.
+       (calc_stats): Drop special casing of median.
+       (dump_statistics): Ditto, except that we label the 50th percentile
+       as "50 (Median)" to make it clear that it's also the median.    
+
+2007-07-31  Ben Pfaff  <blp@gnu.org>
+
+       Remove integer mode from FREQUENCIES and incidentally fix bug
+       #17421.  Reviewed by John Darrington.
+       * frequencies.q (int_pool): Rename data_pool.
+       (gen_pool): Rename syntax_pool.
+       (enum FRQM_*): Removed.
+       (struct freq_tab): Removed `mode', `vector', `min', `max',
+       `out_of_range', `sysmis' members.
+       (calc): Delete support for integer mode.
+       (precalc): Ditto.
+       (postprocess_freq_tab): Ditto.
+       (cleanup_freq_tab): Ditto.
+       (frq_custom_variables): Ditto.
+
+2007-07-28 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q: Moved the order in which groups are displayed in the 
+       independent samples case, where a cut point is given.
+
+2007-07-27  Ben Pfaff  <blp@gnu.org>
+
+       * regression.q (run_regression): Move casereader_destroy call so
+       that it always gets called, not just if there was some valid
+       data.  Fixes bug #19581.
+       Reviewed by Jason Stover.
+
+2007-07-24  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (struct flip_pgm): Remove `case_size' member (now
+       unused).
+       (cmd_flip): Pass var_cnt as number of cases instead of case_cnt,
+       to fix bug #20494.  Don't assign to `case_size' member, which was
+       unused after assignment.
+       (build_dictionary): When NEWNAMES not used, get the number of
+       variables right, to fix bug #20493.
+
+2007-07-10  Jason Stover  <jhs@math.gcsu.edu>
+
+       * glm.q: Initial version of the GLM procedure.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+       
+       * aggregate.c: Simplify greatly since everything is more uniform
+       now.
+
+       * autorecode.c: Adapt to new procedure code.
+       * binomial.c: Ditto.
+       * chisquare.c: Ditto.
+       * crosstabs.q: Ditto.
+       * descriptives.c: Ditto.
+       * examine.q: Ditto.
+       * npar-summary.c: Ditto.
+       * frequencies.q: Ditto.
+       * npar.q: Ditto.
+       * oneway.q: Ditto.
+       * regression.q: Ditto.
+       * sort-cases.c: Ditto.
+       * t-test.c: Ditto.
+
+       * sort-criteria.c: Rewrite to output a struct case_ordering.
+       
+       * flip.c: Rewrite to be a casereader.
+
+       * rank.q: Simplify greatly since casereaders are much more
+       flexible than what we had before.
+       
+2007-05-15  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (run_regression): Tell the user when the data
+       contain no valid cases.
+
+2007-05-08  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: Partial fix of bug which caused a crash if
+       dependent variable and independent variable were the same.
+
+2007-04-16 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q: Changed the output width of reported counts and 
+       degrees of freedom, to avoid truncating these values.  Thanks
+        to Seth Woolley for reporting this problem.  A proper fix involves
+        re-thinking the output driver.
+
+2007-04-12  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (run_regression): Added if (n_data >0) to fix bug
+       19581.
+
+2007-03-29  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (prepare_data): New function.
+
+       * regression.q (compute_moments): New function.
+
+2007-03-18  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q (static var write): Rename write_style to avoid
+       conflict with POSIX function of same name.
+
+2007-03-16  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (run_regression): Added support for moments.
+
+Sat Feb 17 08:16:00 2007  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (flip_sink_create): Improve error message when temporary
+       file cannot be created.
+
+Tue Feb  6 19:58:03 2007  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (flip_file): Give better error message on end-of-file.
+
+2007-02-04  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: Fixed p-value computation in the test for
+       individual regression coefficients.
+
+Mon Jan 15 11:03:20 2007  Ben Pfaff  <blp@gnu.org>
+
+       Fix bugs found by valgrind when --enable-debug is used with the
+       new case code.  These bugs are hidden when the data set is small
+       enough to find in memory; if a bigger data set that would overflow
+       to disk were used, then data corruption would occur.
+
+       * chisquare.c (create_freq_hash): Pass free_freq_mutable_hash to
+       hsh_create as free function.  Make copy of data put into hash.
+
+       * oneway.q (free_value): New function.
+       (run_oneway): Use free_value as arg to hsh_create.  Make copy of
+       data put into hash.
+
+       * rank.q (rank_cases): Don't access data in case after we've given
+       away the case.
+
+Tue Jan  9 19:16:11 2007  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #18739.
+       
+       * aggregate.c (parse_aggregate_functions) Initialize
+       function_name.
+
+Fri Dec 22 14:04:09 2006  Ben Pfaff  <blp@gnu.org>
+
+       Simplify missing value handling.
+       
+       * aggregate.c (struct agr_var): Remove `bool include_missing', add
+       `enum mv_class exclude'.  Remove `int missing', add `bool
+       saw_missing'.  Update users.
+
+       * descriptives.c (struct dsc_trns): Removed `int
+       include_user_missing', add `enum mv_class exclude'.  Update users.
+       (struct dsc_proc): Ditto.
+
+       * examine.q: (static var value_is_missing): Rename
+       `exclude_values', change type to `enum mv_class'.  Update users.
+
+       * rank.q: Ditto.
+
+Fri Dec 22 19:22:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * frequencies.q : Fixed bug #17420, where the table bounds were overun
+       when /FORMAT=nolabels was given.
+
+Wed Dec 20 18:45:31 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * binomial.c binomial.h : New files.  Thanks to Jason Stover 
+          for assistance with these.
+
+       * chisquare.c chisquare.h freq.c freq.h npar-summary.c npar-summary.h 
+         npar.h npar.q: New files.  Implementing NPAR TESTS.
+
+       * frequencies.q  : Moved  structure definitions into freq.[ch]
+
+Sat Dec 16 22:26:44 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make it possible to pull cases from the active file with a
+       function call, instead of requiring indirection through a callback
+       function.
+
+       * aggregate.c (cmd_aggregate): Take advantage of new procedure
+       interface.
+       (agr_to_active_file): Removed.
+       (presorted_agr_to_sysfile): Removed.
+
+       * autorecode.c (cmd_autorecode): Take advantage of new procedure
+       interface.
+       (autorecode_proc_func): Removed.
+
+       * flip.c (struct flip_pgm): New members to allow conformance with
+       new case_source_class interface.
+       (cmd_flip): Adapt to new case_source_class interface.
+       (flip_source_read): Ditto.
+       (flip_source_destroy): Ditto.
+
+Sat Dec 16 12:54:27 2006  Ben Pfaff  <blp@gnu.org>
+
+       * rank.q (rank_custom_variables): Allow grouping variables to be
+       strings.  Fixes bug #18533.  Thanks to John Darrington for review.
+
+Sat Dec  9 18:47:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       * regression.q (is_depvar): Compare variable pointers instead of
+       variable names.
+
+Thu Dec  7 15:26:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * examine.q: Allocated the categorical values for the dependent and 
+       independent variables, on the heap.  Hence they can be of any width.
+
+Wed Dec  6 21:14:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       * regression.q (reg_inserted): Compare variable pointers instead
+       of variable indexes.
+
+Mon Dec  4 22:33:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q (insert_summary): Use var_to_string for labeling.
+       (output_pivot_table) Ditto.
+       (submit) Ditto.
+
+       * frequencies.q (setup_z_trns): Ditto.
+       (dump_full) Ditto.
+       (dump_condensed) Ditto.
+       (dump_statistics) Ditto.
+       
+
+Sun Nov  5 08:31:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * t-test.q, oneway.q: Changed to use the new casefilter structure.
+
+Sat Oct 14 16:52:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       * rank.q: (rank_sorted_casefile) Add some missing case_destroy()
+       calls to fix a memory leak.
+
+Sun Oct  8 09:45:40 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * rank.q: Plugged a small memory leak which occurred under error
+       conditions.
+       
+Sat Oct  7 11:06:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * rank.q: Implemented most of the RANK command.
+
+2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (run_regression): New function to move knowledge of
+       pspp_linreg_cache out of math/coefficient.[ch].
+
+Sat Jul  1 17:41:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #11612, "q2c documentation does not agree with code".
+       
+       * examine.q: Audit use of q2c "+" prefixes that indicate that a
+       command may appear multiple times.
+
+       * frequencies.q: Ditto.
+
+       * oneway.q: Ditto.
+
+       * regression.q: Ditto.
+
+       * t-test.q: Ditto.
+
+Fri Jun 23 14:18:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       Support long string variables on FREQUENCIES, as
+       an extension when in enhanced algorithms mode.  For Greg Hunt
+       <greg@firmansyah.com>.
+       
+       * frequencies.q: (struct freq) Change `v' member from union value
+       to union value *.  Update all references.
+       (struct var_freqs) Add width, print members to represent effective
+       variable width and display format.
+       (calc) Copy entire long string value into the hash table.
+       (frq_custom_variables) Set new width, print members.
+       (hash_value_alpha) Get width from var_freqs.
+       (compare_value_alpha_a) Ditto.
+       (compare_freq_alpha_a) Ditto.
+       (compare_freq_alpha_d) Ditto.
+       (dump_full) Get display format from var_freqs.
+       (dump_condensed) Ditto.
+
+Mon Jun 19 22:07:13 2006  Ben Pfaff  <blp@gnu.org>
+
+       * frequencies.q: (dump_full) Only put the first MAX_SHORT_STRING
+       bytes of string variables into the output cells, seeing as we only
+       copy that many.
+       (dump_condensed) Ditto.
+
+Mon Jun 19 21:52:05 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fixes a bug reported by Greg Hunt <greg@firmansyah.com>.
+       
+       * frequencies.q: (hsh_hash_bytes) We only copy the first
+       MAX_SHORT_STRING bytes of string variables, so we must only
+       compare that many bytes, even if the string variable is longer.
+       (compare_value_alpha_a) Ditto.
+       (compare_freq_alpha_a) Ditto.
+       (compare_freq_alpha_d) Ditto.
+
+2006-05-11  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: Adjusted code to account for cache->coeff being a
+       pspp_linreg_coeff **.
+
+Sun May  7 18:31:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix memory leak.
+       
+       * aggregate.c (cmd_aggregate): Free default_dict before replacing
+       it.
+
+Sun May  7 17:09:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (flip_file): Check return value of pool_fclose().
+
+Sat May  6 16:00:13 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of `char *c' member in union value, for cleanliness.
+       
+       * aggregate.c: (union agr_argument) New union.
+       (struct agr_var) Change element type of arg[] from union value to
+       union agr_argument.
+       (parse_aggregate_functions) Change local variable types likewise.
+
+       * autorecode.c: (union arc_value) New union.
+       (struct arc_item) Change "from" from union value to union
+       arc_value.
+       (recode) Change local variable from union value to union
+       arc_value.
+       (autorecode_trns_proc) Ditto.
+       (compare_alpha_value) Ditto.
+       (hash_alpha_value) Ditto.
+       (compare_numeric_value) Ditto.
+       (hash_numeric_value) Ditto.
+       (autorecode_proc_func) Ditto.
+
+Sat May  6 10:43:33 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       the output code for SPLIT FILE groups in procedure.c, which really
+       shouldn't be doing any output.  Move it into the individual
+       procedures instead.  This also adds some flexibility.
+
+       * crosstabs.q (precalc): Call output_split_file_values().
+
+       * descriptives.c (calc_descriptives): Ditto.
+
+       * examine.q (run_examine): Ditto.
+       
+       * frequencies.q (precalc): Ditto.
+
+       * oneway.q (run_oneway): Ditto.
+
+       * regression.q (run_regression): Ditto.
+
+       * t-test.q (calculate): Ditto.
+
+Wed May  3 23:05:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * aggregate.c (cmd_aggregate) Use discard_variables().
+       
+2006-04-28  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (regression_trns_resid_proc): Pass only the
+       variables used in the model to (*model->residual)().
+
+       * regression.q (regression_trns_pred_proc): Pass only the
+       variables used in the model to (*model->pred)().
+
+2006-04-26  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: Added support for multiple transformations.
+       
+       * regression.q (regression_trns_resid_proc): New function.
+
+       * regression.q (regression_trns_pred_proc): New function.
+
+       * regression.q (subcommand_save): Added support for saving
+       predicted values.
+
+       * regression.q (regression_trns_free): New function. 
+
+       * regression.q (reg_get_name): New function.
+
+       * regression.q (reg_save_var): New function.
+
+Tue Apr 25 13:18:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * rank.q (parse_rank_function): Use SE instead of ME for parse
+       errors.
+
+Tue Apr 25 13:16:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       * flip.c (flip_sink_write): Use snprintf() to simplify a bit of
+       code.
+
+2006-04-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (try_name): New function. (Partly copied from
+       try_name in descriptives.c.)
+
+       * regression.q (subcommand_save): Choose residual variable names
+       correctly. 
+
+2006-04-20  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (cmd_regression): Moved call to subcommand_save()
+       outside multipass_procedure_with_splits().
+       
+       * regression.q (regression_trns_proc): Fixed value counter n_vals
+       before calling *model->residual().
+
+2006-04-19  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (regression_trns_proc): Fixed the look-up of the
+       number of variables.
+
+2006-04-18  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (regression_trns_proc): Look up the residual
+       variable in the linear regression cache.
+
+       * regression.q (subcommand_save): Set the residual variable in the
+       linear regression cache.
+
+2006-04-17  Jason Stover  <jason@wonko.gcsu.edu>
+
+       * regression.q (regression_trns_proc): Accept case_idx as an int
+       to match the definition of trns_proc_func.
+
+2006-04-17  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (regression_trns_proc): New function.
+
+       * regression.q (subcommand_save): Create variable residuals and
+       add a transformation to assign values to them. Also free the
+       linreg_cache if the SAVE command was not called. Removed the
+       casereading loop. Placed actual computation of residuals in
+       regression_trns_proc.
+
+       * regression.q (run_regression): Moved call to free
+       pspp_linreg_cache to subcommand_save.
+
+Sat Apr 15 18:01:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       * examine.q (output_examine): Add casts to fix warnings.
+
+2006-04-07  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q (subcommand_save): New function.
+
+2006-04-04  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: New function reg_has_categorical () to tell
+       whether a pspp_linreg_struct was made with any variables of type
+       ALPHA.
+
+       * regression.q: (subcommand_export): Call
+       reg_print_categorical_encoding() only if the model uses any
+       categorical variables.
+
+Mon Mar 27 16:00:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.q: (output_pivot_table) Drop spurious space from
+       message.
+
+2006-03-15  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.q: Added custom syntax parser for VARIABLES subcommand
+
+       * regression.q: Moved most instructions for run_regression ()
+       inside the loop over dependent variables.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index f58b97cf8994c4eebcef4509c5cc1b8267f7f871..e1dcd12342ff2b42ff94dcbf472affeb58bb51c1 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2008 Free Software Foundation, Inc.
 
    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
@@ -43,6 +43,8 @@
 #include <libpspp/str.h>
 #include <math/moments.h>
 #include <math/sort.h>
+#include <math/statistic.h>
+#include <math/percentiles.h>
 
 #include "minmax.h"
 #include "xalloc.h"
@@ -75,12 +77,17 @@ struct agr_var
     char *string;
     bool saw_missing;
     struct moments1 *moments;
+    double cc;
+
+    struct variable *subject;
+    struct variable *weight;
+    struct casewriter *writer;
   };
 
 /* Aggregation functions. */
 enum
   {
-    NONE, SUM, MEAN, SD, MAX, MIN, PGT, PLT, PIN, POUT, FGT, FLT, FIN,
+    NONE, SUM, MEAN, MEDIAN, SD, MAX, MIN, PGT, PLT, PIN, POUT, FGT, FLT, FIN,
     FOUT, N, NU, NMISS, NUMISS, FIRST, LAST,
     N_AGR_FUNCS, N_NO_VARS, NU_NO_VARS,
     FUNC = 0x1f, /* Function mask. */
@@ -102,6 +109,7 @@ static const struct agr_func agr_func_tab[] =
     {"<NONE>",  0, -1,          {0, 0, 0}},
     {"SUM",     0, -1,          {FMT_F, 8, 2}},
     {"MEAN",   0, -1,          {FMT_F, 8, 2}},
+    {"MEDIAN", 0, -1,          {FMT_F, 8, 2}},
     {"SD",      0, -1,          {FMT_F, 8, 2}},
     {"MAX",     0, VAL_STRING,  {-1, -1, -1}},
     {"MIN",     0, VAL_STRING,  {-1, -1, -1}},
@@ -135,7 +143,7 @@ enum missing_treatment
 struct agr_proc
   {
     /* Break variables. */
-    struct case_ordering *sort;         /* Sort criteria. */
+    struct case_ordering *sort;         /* Sort criteria (break variable). */
     const struct variable **break_vars;       /* Break variables. */
     size_t break_var_cnt;               /* Number of break variables. */
     struct ccase break_case;            /* Last values of break variables. */
@@ -149,6 +157,7 @@ struct agr_proc
 
 static void initialize_aggregate_info (struct agr_proc *,
                                        const struct ccase *);
+
 static void accumulate_aggregate_info (struct agr_proc *,
                                        const struct ccase *);
 /* Prototypes. */
@@ -344,7 +353,8 @@ error:
 
 /* Parse all the aggregate functions. */
 static bool
-parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, struct agr_proc *agr)
+parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict,
+                          struct agr_proc *agr)
 {
   struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
 
@@ -545,7 +555,7 @@ parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, s
          variables. */
       for (i = 0; i < n_dest; i++)
        {
-         struct agr_var *v = xmalloc (sizeof *v);
+         struct agr_var *v = xzalloc (sizeof *v);
 
          /* Add variable to chain. */
          if (agr->agr_vars != NULL)
@@ -703,6 +713,10 @@ agr_destroy (struct agr_proc *agr)
        }
       else if (iter->function == SD)
         moments1_destroy (iter->moments);
+
+      var_destroy (iter->subject);
+      var_destroy (iter->weight);
+
       free (iter);
     }
   if (agr->dict != NULL)
@@ -755,6 +769,25 @@ accumulate_aggregate_info (struct agr_proc *agr, const struct ccase *input)
             iter->dbl[0] += v->f * weight;
             iter->dbl[1] += weight;
             break;
+         case MEDIAN:
+           {
+             double wv ;
+             struct ccase cout;
+             case_create (&cout, 2);
+
+             case_data_rw (&cout, iter->subject)->f =
+               case_data (input, iter->src)->f;
+
+             wv = dict_get_case_weight (agr->src_dict, input, NULL);
+
+             case_data_rw (&cout, iter->weight)->f = wv;
+
+             iter->cc += wv;
+
+             casewriter_write (iter->writer, &cout);
+             case_destroy (&cout);
+           }
+           break;
          case SD:
             moments1_add (iter->moments, v->f, weight);
             break;
@@ -911,6 +944,7 @@ dump_aggregate_info (struct agr_proc *agr, struct casewriter *output)
       {
        union value *v = case_data_rw (&c, i->dest);
 
+
        if (agr->missing == COLUMNWISE && i->saw_missing
            && (i->function & FUNC) != N && (i->function & FUNC) != NU
            && (i->function & FUNC) != NMISS && (i->function & FUNC) != NUMISS)
@@ -919,6 +953,9 @@ dump_aggregate_info (struct agr_proc *agr, struct casewriter *output)
              memset (v->s, ' ', var_get_width (i->dest));
            else
              v->f = SYSMIS;
+
+           casewriter_destroy (i->writer);
+
            continue;
          }
 
@@ -930,6 +967,25 @@ dump_aggregate_info (struct agr_proc *agr, struct casewriter *output)
          case MEAN:
            v->f = i->dbl[1] != 0.0 ? i->dbl[0] / i->dbl[1] : SYSMIS;
            break;
+         case MEDIAN:
+           {
+             struct casereader *sorted_reader;
+             struct order_stats *median = percentile_create (0.5, i->cc);
+
+             sorted_reader = casewriter_make_reader (i->writer);
+
+             order_stats_accumulate (&median, 1,
+                                     sorted_reader,
+                                     i->weight,
+                                     i->subject,
+                                     i->exclude);
+
+             v->f = percentile_calculate ((struct percentile *) median,
+                                          PC_HAVERAGE);
+
+             statistic_destroy ((struct statistic *) median);
+           }
+           break;
          case SD:
             {
               double variance;
@@ -1044,6 +1100,22 @@ initialize_aggregate_info (struct agr_proc *agr, const struct ccase *input)
        case MAX | FSTRING:
          memset (iter->string, 0, var_get_width (iter->src));
          break;
+       case MEDIAN:
+         {
+           struct case_ordering *ordering = case_ordering_create ();
+
+           if ( ! iter->subject)
+             iter->subject = var_create_internal (0);
+
+           if ( ! iter->weight)
+             iter->weight = var_create_internal (1);
+
+           case_ordering_add_var (ordering, iter->subject, SRT_ASCEND);
+
+           iter->writer = sort_create_writer (ordering, 2);
+           iter->cc = 0;
+         }
+         break;
         case SD:
           if (iter->moments == NULL)
             iter->moments = moments1_create (MOMENT_VARIANCE);
index 10738fdcaa147d5d268b89522713b1de974c0c2b..3e9ab232a29a66368f6995ccf18340a2e9d5eeb8 100644 (file)
@@ -13,6 +13,7 @@ src_language_stats_built_sources = \
        src/language/stats/oneway.c \
        src/language/stats/rank.c \
        src/language/stats/regression.c \
+       src/language/stats/reliability.c \
        src/language/stats/t-test.c
 
 language_stats_sources = \
@@ -31,9 +32,12 @@ language_stats_sources = \
        src/language/stats/freq.c \
        src/language/stats/freq.h \
        src/language/stats/npar-summary.c \
-       src/language/stats/npar-summary.h 
+       src/language/stats/npar-summary.h \
+       src/language/stats/wilcoxon.c \
+       src/language/stats/wilcoxon.h
 
 all_q_sources += $(src_language_stats_built_sources:.c=.q)
 EXTRA_DIST += $(src_language_stats_built_sources:.c=.q)
 CLEANFILES += $(src_language_stats_built_sources)
 
+EXTRA_DIST += src/language/stats/OChangeLog
index 39b8506d53edb7f184df01831522e0da7511217e..5022cebddd35dbe98994ff193e878e6dcb87d4dd 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <gsl/gsl_cdf.h>
 #include <gsl/gsl_randist.h>
-#include <gsl-extras/gsl-extras.h>
 
 #include <minmax.h>
 
@@ -79,7 +78,7 @@ calculate_binomial_internal (double n1, double n2, double p)
   /* SPSS Statistical Algorithms has completely different and WRONG
      advice here. */
 
-  double sig1tailed = gslextras_cdf_binomial_P (n1, n1 + n2, p);
+  double sig1tailed = gsl_cdf_binomial_P (n1, p, n1 + n2);
 
   if ( p == 0.5 )
     return sig1tailed > 0.5 ? 1.0 :sig1tailed * 2.0;
@@ -120,14 +119,14 @@ do_binomial (const struct dictionary *dict,
              cat1[v].value = value_dup (value, width);
              cat1[v].count = w;
            }
-         else if ( 0 == compare_values (cat1[v].value, value, width))
+         else if ( 0 == compare_values (cat1[v].value, value, var))
            cat1[v].count += w;
          else if ( NULL == cat2[v].value )
            {
              cat2[v].value = value_dup (value, width);
              cat2[v].count = w;
            }
-         else if ( 0 == compare_values (cat2[v].value, value, width))
+         else if ( 0 == compare_values (cat2[v].value, value, var))
            cat2[v].count += w;
          else if ( bst->category1 == SYSMIS)
            msg (ME, _("Variable %s is not dichotomous"), var_get_name (var));
@@ -144,7 +143,9 @@ void
 binomial_execute (const struct dataset *ds,
                  struct casereader *input,
                   enum mv_class exclude,
-                 const struct npar_test *test)
+                 const struct npar_test *test,
+                 bool exact UNUSED,
+                 double timer UNUSED)
 {
   int v;
   const struct binomial_test *bst = (const struct binomial_test *) test;
index a8360330aa43d4a49c53f93fbd1f4798bf35d77e..df01a13bc56dbeb221b532267fae53b5ecb301ed 100644 (file)
@@ -40,6 +40,7 @@ struct dataset;
 void binomial_execute (const struct dataset *,
                       struct casereader *,
                        enum mv_class,
-                      const struct npar_test *);
+                      const struct npar_test *,
+                      bool, double);
 
 #endif
index 158064dcf920b6f539017c57d2bb9203e2c90457..ed143824187593f984324bc39afeaf810c0080df 100644 (file)
@@ -320,7 +320,9 @@ void
 chisquare_execute (const struct dataset *ds,
                   struct casereader *input,
                    enum mv_class exclude,
-                  const struct npar_test *test)
+                  const struct npar_test *test,
+                  bool exact UNUSED,
+                  double timer UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
   int v, i;
@@ -344,7 +346,8 @@ chisquare_execute (const struct dataset *ds,
          struct hsh_table *freq_hash = NULL;
           struct casereader *reader =
             casereader_create_filter_missing (casereader_clone (input),
-                                              &ost->vars[v], 1, exclude, NULL);
+                                              &ost->vars[v], 1, exclude,
+                                             NULL, NULL);
          struct tab_table *freq_table =
             create_variable_frequency_table(dict, reader, cst, v, &freq_hash);
 
@@ -414,7 +417,8 @@ chisquare_execute (const struct dataset *ds,
          double total_obs = 0.0;
           struct casereader *reader =
             casereader_create_filter_missing (casereader_clone (input),
-                                              &ost->vars[v], 1, exclude, NULL);
+                                              &ost->vars[v], 1, exclude,
+                                             NULL, NULL);
          struct hsh_table *freq_hash =
            create_freq_hash_with_range (dict, reader,
                                          ost->vars[v], cst->lo, cst->hi);
index 916a26392e9e1c6ebea43ad7eef47c423e3726fc..91a17d1a14fc23e89e5d0cd2984b8888d6eba51b 100644 (file)
@@ -46,7 +46,9 @@ void chisquare_insert_variables (const struct npar_test *test,
 void chisquare_execute (const struct dataset *ds,
                        struct casereader *input,
                         enum mv_class exclude,
-                       const struct npar_test *test);
+                       const struct npar_test *test,
+                       bool,
+                       double);
 
 
 
index fcfccc39a251c2fbbfffbda7a6913207a70d1757..801b128b8a4ad1c5e0398caa897a4cee0a869f08 100644 (file)
@@ -1861,7 +1861,6 @@ display_crosstabulation (void)
     tab_offset (table, -1, tab_row (table) - num_cells * n_rows);
     for (r = 0; r < n_rows; r++)
       {
-        char suffix = 0;
         bool mark_missing = false;
 
         if (cmd.miss == CRS_REPORT
@@ -1870,6 +1869,7 @@ display_crosstabulation (void)
 
         for (i = 0; i < num_cells; i++)
           {
+            char suffix = 0;
             double v;
 
             switch (cells[i])
@@ -1878,7 +1878,7 @@ display_crosstabulation (void)
                 v = row_tot[r];
                 break;
               case CRS_CL_ROW:
-                v = 100.;
+                v = 100.0;
                 suffix = '%';
                 break;
               case CRS_CL_COLUMN:
@@ -1916,7 +1916,6 @@ display_crosstabulation (void)
       {
        double ct = c < n_cols ? col_tot[c] : W;
         bool mark_missing = false;
-        char suffix = 0;
         int i;
 
         if (cmd.miss == CRS_REPORT && c < n_cols
@@ -1925,13 +1924,13 @@ display_crosstabulation (void)
 
         for (i = 0; i < num_cells; i++)
          {
+            char suffix = 0;
            double v;
 
            switch (cells[i])
              {
              case CRS_CL_COUNT:
                v = ct;
-                suffix = '%';
                break;
              case CRS_CL_ROW:
                v = ct / W * 100.;
@@ -1954,7 +1953,7 @@ display_crosstabulation (void)
                 NOT_REACHED ();
              }
 
-            format_cell_entry (table, c, i, v, suffix, mark_missing);
+           format_cell_entry (table, c, i, v, suffix, mark_missing);
          }
         last_row = i;
       }
@@ -2456,7 +2455,7 @@ calc_r (double *X, double *Y, double *r, double *ase_0, double *ase_1)
   for (sum_Xr = sum_X2r = 0., i = 0; i < n_rows; i++)
     {
       sum_Xr += X[i] * row_tot[i];
-      sum_X2r += X[i] * X[i] * row_tot[i];
+      sum_X2r += pow2 (X[i]) * row_tot[i];
     }
   Xbar = sum_Xr / W;
 
@@ -2468,11 +2467,11 @@ calc_r (double *X, double *Y, double *r, double *ase_0, double *ase_1)
   Ybar = sum_Yc / W;
 
   S = sum_XYf - sum_Xr * sum_Yc / W;
-  SX = sum_X2r - sum_Xr * sum_Xr / W;
-  SY = sum_Y2c - sum_Yc * sum_Yc / W;
+  SX = sum_X2r - pow2 (sum_Xr) / W;
+  SY = sum_Y2c - pow2 (sum_Yc) / W;
   T = sqrt (SX * SY);
   *r = S / T;
-  *ase_0 = sqrt ((sum_X2Y2f - (sum_XYf * sum_XYf) / W) / (sum_X2r * sum_Y2c));
+  *ase_0 = sqrt ((sum_X2Y2f - pow2 (sum_XYf) / W) / (sum_X2r * sum_Y2c));
 
   {
     double s, c, y, t;
@@ -2562,9 +2561,9 @@ calc_symmetric (double v[N_SYMMETRIC], double ase[N_SYMMETRIC],
 
        Dr = Dc = W * W;
        for (r = 0; r < n_rows; r++)
-         Dr -= row_tot[r] * row_tot[r];
+         Dr -= pow2 (row_tot[r]);
        for (c = 0; c < n_cols; c++)
-         Dc -= col_tot[c] * col_tot[c];
+         Dc -= pow2 (col_tot[c]);
       }
 
       {
@@ -3073,10 +3072,10 @@ calc_directional (double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
            }
 
        for (sum_ri2 = 0., i = 0; i < n_rows; i++)
-         sum_ri2 += row_tot[i] * row_tot[i];
+         sum_ri2 += pow2 (row_tot[i]);
 
        for (sum_cj2 = 0., j = 0; j < n_cols; j++)
-         sum_cj2 += col_tot[j] * col_tot[j];
+         sum_cj2 += pow2 (col_tot[j]);
 
        v[3] = (W * sum_fij2_ci - sum_ri2) / (W * W - sum_ri2);
        v[4] = (W * sum_fij2_ri - sum_cj2) / (W * W - sum_cj2);
@@ -3166,9 +3165,9 @@ calc_directional (double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
        for (sum_Xr = sum_X2r = 0., i = 0; i < n_rows; i++)
          {
            sum_Xr += rows[i].f * row_tot[i];
-           sum_X2r += rows[i].f * rows[i].f * row_tot[i];
+           sum_X2r += pow2 (rows[i].f) * row_tot[i];
          }
-       SX = sum_X2r - sum_Xr * sum_Xr / W;
+       SX = sum_X2r - pow2 (sum_Xr) / W;
 
        for (SXW = 0., j = 0; j < n_cols; j++)
          {
@@ -3176,7 +3175,7 @@ calc_directional (double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
 
            for (cum = 0., i = 0; i < n_rows; i++)
              {
-               SXW += rows[i].f * rows[i].f * mat[j + i * n_cols];
+               SXW += pow2 (rows[i].f) * mat[j + i * n_cols];
                cum += rows[i].f * mat[j + i * n_cols];
              }
 
@@ -3193,7 +3192,7 @@ calc_directional (double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
        for (sum_Yc = sum_Y2c = 0., i = 0; i < n_cols; i++)
          {
            sum_Yc += cols[i].f * col_tot[i];
-           sum_Y2c += cols[i].f * cols[i].f * col_tot[i];
+           sum_Y2c += pow2 (cols[i].f) * col_tot[i];
          }
        SY = sum_Y2c - sum_Yc * sum_Yc / W;
 
@@ -3203,7 +3202,7 @@ calc_directional (double v[N_DIRECTIONAL], double ase[N_DIRECTIONAL],
 
            for (cum = 0., j = 0; j < n_cols; j++)
              {
-               SYW += cols[j].f * cols[j].f * mat[j + i * n_cols];
+               SYW += pow2 (cols[j].f) * mat[j + i * n_cols];
                cum += cols[j].f * mat[j + i * n_cols];
              }
 
index 9315e7e89bab621daeae47477ee2762a7b9341a5..e341b18a352f294298a4fbb004eb9c2672412fd6 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2008 Free Software Foundation, Inc.
 
    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
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <math/sort.h>
+#include <math/order-stats.h>
+#include <math/percentiles.h>
+#include <math/tukey-hinges.h>
+#include <math/box-whisker.h>
+#include <math/trimmed-mean.h>
+#include <math/extrema.h>
+#include <math/np.h>
 #include <data/case.h>
 #include <data/casegrouper.h>
 #include <data/casereader.h>
+#include <data/casewriter.h>
+#include <data/case-ordering.h>
 #include <data/dictionary.h>
 #include <data/procedure.h>
 #include <data/value-labels.h>
@@ -37,9 +47,7 @@
 #include <libpspp/message.h>
 #include <libpspp/misc.h>
 #include <libpspp/str.h>
-#include <math/factor-stats.h>
 #include <math/moments.h>
-#include <math/percentiles.h>
 #include <output/charts/box-whisker.h>
 #include <output/charts/cartesian.h>
 #include <output/manager.h>
@@ -56,6 +64,7 @@
 #include <output/chart.h>
 #include <output/charts/plot-hist.h>
 #include <output/charts/plot-chart.h>
+#include <math/histogram.h>
 
 /* (specification)
    "EXAMINE" (xmn_):
@@ -63,8 +72,8 @@
    +total=custom;
    +nototal=custom;
    missing=miss:pairwise/!listwise,
-           rep:report/!noreport,
-           incl:include/!exclude;
+   rep:report/!noreport,
+   incl:include/!exclude;
    +compare=cmp:variables/!groups;
    +percentiles=custom;
    +id=var;
 /* (functions) */
 
 
-
 static struct cmd_examine cmd;
 
 static const struct variable **dependent_vars;
-
 static size_t n_dependent_vars;
 
+/* PERCENTILES */
+
+static subc_list_double percentile_list;
+static enum pc_alg percentile_algorithm;
 
-struct factor
+struct factor_metrics
 {
-  /* The independent variable */
-  struct variable *indep_var[2];
+  struct moments1 *moments;
+
+  struct percentile **ptl;
+  size_t n_ptiles;
+
+  struct statistic *tukey_hinges;
+  struct statistic *box_whisker;
+  struct statistic *trimmed_mean;
+  struct statistic *histogram;
+  struct order_stats *np;
+
+  /* Three quartiles indexing into PTL */
+  struct percentile **quartiles;
+
+  /* A reader sorted in ASCENDING order */
+  struct casereader *up_reader;
+
+  /* The minimum value of all the weights */
+  double cmin;
+
+  /* Sum of all weights, including those for missing values */
+  double n;
+
+  double mean;
 
+  double variance;
 
-  /* Hash table of factor stats indexed by 2 values */
-  struct hsh_table *fstats;
+  double skewness;
 
-  /* The hash table after it has been crunched */
-  struct factor_statistics **fs;
+  double kurtosis;
 
-  struct factor *next;
+  double se_mean;
 
+  struct extrema *minima;
+  struct extrema *maxima;
 };
 
-/* Linked list of factors */
-static struct factor *factors = 0;
+struct factor_result
+{
+  struct ll ll;
 
-static struct metrics *totals = 0;
+  union value *value[2];
 
-/* Parse the clause specifying the factors */
-static int examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd);
+  /* An array of factor metrics, one for each variable */
+  struct factor_metrics *metrics;
+};
 
+struct xfactor
+{
+  /* We need to make a list of this structure */
+  struct ll ll;
 
+  /* The independent variable */
+  const struct variable const* indep_var[2];
 
-/* Output functions */
-static void show_summary (const struct variable **dependent_var, int n_dep_var,
-                        const struct factor *f);
+  /* A list of results for this factor */
+  struct ll_list result_list ;
+};
 
-static void show_extremes (const struct variable **dependent_var,
-                         int n_dep_var,
-                         const struct factor *factor,
-                         int n_extremities);
 
-static void show_descriptives (const struct variable **dependent_var,
-                             int n_dep_var,
-                             struct factor *factor);
+static void
+factor_destroy (struct xfactor *fctr)
+{
+  struct ll *ll = ll_head (&fctr->result_list);
+  while (ll != ll_null (&fctr->result_list))
+    {
+      int v;
+      struct factor_result *result =
+       ll_data (ll, struct factor_result, ll);
 
-static void show_percentiles (const struct variable **dependent_var,
-                            int n_dep_var,
-                            struct factor *factor);
+      for (v = 0; v < n_dependent_vars; ++v)
+       {
+         int i;
+         moments1_destroy (result->metrics[v].moments);
+         extrema_destroy (result->metrics[v].minima);
+         extrema_destroy (result->metrics[v].maxima);
+         statistic_destroy (result->metrics[v].trimmed_mean);
+         statistic_destroy (result->metrics[v].tukey_hinges);
+         statistic_destroy (result->metrics[v].box_whisker);
+         statistic_destroy (result->metrics[v].histogram);
+         for (i = 0 ; i < result->metrics[v].n_ptiles; ++i)
+           statistic_destroy ((struct statistic *) result->metrics[v].ptl[i]);
+         free (result->metrics[v].ptl);
+         free (result->metrics[v].quartiles);
+         casereader_destroy (result->metrics[v].up_reader);
+       }
 
+      free (result->value[0]);
+      free (result->value[1]);
+      free (result->metrics);
+      ll = ll_next (ll);
+      free (result);
+    }
+}
 
+static struct xfactor level0_factor;
+static struct ll_list factor_list = LL_INITIALIZER (factor_list);
 
+/* Parse the clause specifying the factors */
+static int examine_parse_independent_vars (struct lexer *lexer,
+                                          const struct dictionary *dict,
+                                          struct cmd_examine *cmd);
 
-void np_plot (const struct metrics *m, const char *factorname);
+/* Output functions */
+static void show_summary (const struct variable **dependent_var, int n_dep_var,
+                         const struct xfactor *f);
 
 
-void box_plot_group (const struct factor *fctr,
-                   const struct variable **vars, int n_vars,
-                   const struct variable *id
-                   ) ;
+static void show_descriptives (const struct variable **dependent_var,
+                              int n_dep_var,
+                              const struct xfactor *f);
 
 
-void box_plot_variables (const struct factor *fctr,
-                       const struct variable **vars, int n_vars,
-                       const struct variable *id
-                       );
+static void show_percentiles (const struct variable **dependent_var,
+                              int n_dep_var,
+                              const struct xfactor *f);
+
+
+static void show_extremes (const struct variable **dependent_var,
+                          int n_dep_var,
+                          const struct xfactor *f);
+
 
 
 
@@ -161,34 +237,24 @@ void factor_calc (const struct ccase *c, int case_no,
 
 /* Represent a factor as a string, so it can be
    printed in a human readable fashion */
-static void factor_to_string (const struct factor *fctr,
-                              const struct factor_statistics *fs,
-                             const struct variable *var,
-                             struct string *str
-                             );
+static void factor_to_string (const struct xfactor *fctr,
+                             const struct factor_result *result,
+                             struct string *str);
 
 /* Represent a factor as a string, so it can be
    printed in a human readable fashion,
    but sacrificing some readablility for the sake of brevity */
-static void factor_to_string_concise (const struct factor *fctr,
-                                     const struct factor_statistics *fs,
-                                     struct string *);
-
+static void
+factor_to_string_concise (const struct xfactor *fctr,
+                         const struct factor_result *result,
+                         struct string *str
+                         );
 
 
 
 /* Categories of missing values to exclude. */
 static enum mv_class exclude_values;
 
-/* PERCENTILES */
-
-static subc_list_double percentile_list;
-
-static enum pc_alg percentile_algorithm;
-
-static short sbc_percentile;
-
-
 int
 cmd_examine (struct lexer *lexer, struct dataset *ds)
 {
@@ -224,225 +290,404 @@ cmd_examine (struct lexer *lexer, struct dataset *ds)
     }
 
   grouper = casegrouper_create_splits (proc_open (ds), dataset_dict (ds));
+
   while (casegrouper_get_next_group (grouper, &group))
-    run_examine (&cmd, group, ds);
+    {
+      struct casereader *reader =
+       casereader_create_arithmetic_sequence (group, 1, 1);
+
+      run_examine (&cmd, reader, ds);
+    }
+
   ok = casegrouper_destroy (grouper);
   ok = proc_commit (ds) && ok;
 
-  if ( totals )
+  if ( dependent_vars )
+    free (dependent_vars);
+
+  subc_list_double_destroy (&percentile_list);
+
+  return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
+};
+
+
+/* Plot the normal and detrended normal plots for RESULT.
+   Label the plots with LABEL */
+static void
+np_plot (struct np *np, const char *label)
+{
+  double yfirst = 0, ylast = 0;
+
+  double x_lower;
+  double x_upper;
+  double slack;
+
+  /* Normal Plot */
+  struct chart *np_chart;
+
+  /* Detrended Normal Plot */
+  struct chart *dnp_chart;
+
+  /* The slope and intercept of the ideal normal probability line */
+  const double slope = 1.0 / np->stddev;
+  const double intercept = -np->mean / np->stddev;
+
+  if ( np->n < 1.0 )
     {
-      free ( totals );
+      msg (MW, _("Not creating plot because data set is empty."));
+      return ;
     }
 
-  if ( dependent_vars )
-    free (dependent_vars);
+  np_chart = chart_create ();
+  dnp_chart = chart_create ();
+
+  if ( !np_chart || ! dnp_chart )
+    return ;
+
+  chart_write_title (np_chart, _("Normal Q-Q Plot of %s"), label);
+  chart_write_xlabel (np_chart, _("Observed Value"));
+  chart_write_ylabel (np_chart, _("Expected Normal"));
+
+  chart_write_title (dnp_chart, _("Detrended Normal Q-Q Plot of %s"),
+                    label);
+  chart_write_xlabel (dnp_chart, _("Observed Value"));
+  chart_write_ylabel (dnp_chart, _("Dev from Normal"));
+
+  yfirst = gsl_cdf_ugaussian_Pinv (1 / (np->n + 1));
+  ylast = gsl_cdf_ugaussian_Pinv (np->n / (np->n + 1));
+
+  /* Need to make sure that both the scatter plot and the ideal fit into the
+     plot */
+  x_lower = MIN (np->y_min, (yfirst - intercept) / slope) ;
+  x_upper = MAX (np->y_max, (ylast  - intercept) / slope) ;
+  slack = (x_upper - x_lower)  * 0.05 ;
+
+  chart_write_xscale (np_chart, x_lower - slack, x_upper + slack, 5);
+  chart_write_xscale (dnp_chart, np->y_min, np->y_max, 5);
+
+  chart_write_yscale (np_chart, yfirst, ylast, 5);
+  chart_write_yscale (dnp_chart, np->dns_min, np->dns_max, 5);
 
   {
-    struct factor *f = factors ;
-    while ( f )
+    struct ccase c;
+    struct casereader *reader = casewriter_make_reader (np->writer);
+    while (casereader_read (reader, &c))
       {
-       struct factor *ff = f;
+       chart_datum (np_chart, 0, case_data_idx (&c, NP_IDX_Y)->f, case_data_idx (&c, NP_IDX_NS)->f);
+       chart_datum (dnp_chart, 0, case_data_idx (&c, NP_IDX_Y)->f, case_data_idx (&c, NP_IDX_DNS)->f);
 
-       f = f->next;
-       free ( ff->fs );
-       hsh_destroy ( ff->fstats ) ;
-       free ( ff ) ;
+       case_destroy (&c);
       }
-    factors = 0;
+    casereader_destroy (reader);
   }
 
-  subc_list_double_destroy (&percentile_list);
-
-  return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
-};
+  chart_line (dnp_chart, 0, 0, np->y_min, np->y_max , CHART_DIM_X);
+  chart_line (np_chart, slope, intercept, yfirst, ylast , CHART_DIM_Y);
 
+  chart_submit (np_chart);
+  chart_submit (dnp_chart);
+}
 
 
-/* Show all the appropriate tables */
 static void
-output_examine (void)
+show_npplot (const struct variable **dependent_var,
+            int n_dep_var,
+            const struct xfactor *fctr)
 {
-  struct factor *fctr;
+  int v;
 
-  /* Show totals if appropriate */
-  if ( ! cmd.sbc_nototal || factors == 0 )
+  for (v = 0; v < n_dep_var; ++v)
     {
-      show_summary (dependent_vars, n_dependent_vars, 0);
+      struct ll *ll;
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list);
+          ll = ll_next (ll))
+       {
+         struct string str;
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
+
+         ds_init_empty (&str);
+         ds_put_format (&str, "%s ", var_get_name (dependent_var[v]));
+
+         factor_to_string (fctr, result, &str);
+
+         np_plot ((struct np*) result->metrics[v].np, ds_cstr(&str));
+
+         statistic_destroy ((struct statistic *)result->metrics[v].np);
 
-      if ( cmd.sbc_statistics )
+         ds_destroy (&str);
+       }
+    }
+}
+
+
+static void
+show_histogram (const struct variable **dependent_var,
+               int n_dep_var,
+               const struct xfactor *fctr)
+{
+  int v;
+
+  for (v = 0; v < n_dep_var; ++v)
+    {
+      struct ll *ll;
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list);
+          ll = ll_next (ll))
        {
-         if ( cmd.a_statistics[XMN_ST_EXTREME])
-           show_extremes (dependent_vars, n_dependent_vars, 0, cmd.st_n);
+         struct string str;
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
+
+         ds_init_empty (&str);
+         ds_put_format (&str, "%s ", var_get_name (dependent_var[v]));
+
+         factor_to_string (fctr, result, &str);
 
-         if ( cmd.a_statistics[XMN_ST_DESCRIPTIVES])
-           show_descriptives (dependent_vars, n_dependent_vars, 0);
+         histogram_plot ((struct histogram *) result->metrics[v].histogram,
+                         ds_cstr (&str),
+                         (struct moments1 *) result->metrics[v].moments);
 
+         ds_destroy (&str);
        }
-      if ( sbc_percentile )
-       show_percentiles (dependent_vars, n_dependent_vars, 0);
+    }
+}
+
+
 
-      if ( cmd.sbc_plot)
+static void
+show_boxplot_groups (const struct variable **dependent_var,
+                    int n_dep_var,
+                    const struct xfactor *fctr)
+{
+  int v;
+
+  for (v = 0; v < n_dep_var; ++v)
+    {
+      struct ll *ll;
+      int f = 0;
+      struct chart *ch = chart_create ();
+      double y_min = DBL_MAX;
+      double y_max = -DBL_MAX;
+
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list);
+          ll = ll_next (ll))
        {
-         int v;
-         if ( cmd.a_plot[XMN_PLT_STEMLEAF] )
-           msg (SW, _ ("%s is not currently supported."), "STEMLEAF");
+         const struct extremum  *max, *min;
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
-         if ( cmd.a_plot[XMN_PLT_SPREADLEVEL] )
-           msg (SW, _ ("%s is not currently supported."), "SPREADLEVEL");
+         const struct ll_list *max_list =
+           extrema_list (result->metrics[v].maxima);
 
-         if ( cmd.a_plot[XMN_PLT_NPPLOT] )
-           {
-             for ( v = 0 ; v < n_dependent_vars; ++v )
-               np_plot (&totals[v], var_to_string (dependent_vars[v]));
-           }
+         const struct ll_list *min_list =
+           extrema_list (result->metrics[v].minima);
 
-         if ( cmd.a_plot[XMN_PLT_BOXPLOT] )
+         if ( ll_is_empty (max_list))
            {
-             if ( cmd.cmp == XMN_GROUPS )
-               {
-                 box_plot_group (0, (const struct variable **) dependent_vars,
-                                  n_dependent_vars, cmd.v_id);
-               }
-             else
-               box_plot_variables (0,
-                                    (const struct variable **) dependent_vars,
-                                    n_dependent_vars, cmd.v_id);
+             msg (MW, _("Not creating plot because data set is empty."));
+             continue;
            }
 
-         if ( cmd.a_plot[XMN_PLT_HISTOGRAM] )
-           {
-             for ( v = 0 ; v < n_dependent_vars; ++v )
-               {
-                 struct normal_curve normal;
+         max = (const struct extremum *)
+           ll_data (ll_head(max_list), struct extremum, ll);
 
-                 normal.N      = totals[v].n;
-                 normal.mean   = totals[v].mean;
-                 normal.stddev = totals[v].stddev;
+          min = (const struct extremum *)
+           ll_data (ll_head (min_list), struct extremum, ll);
 
-                 histogram_plot (totals[v].histogram,
-                                var_to_string (dependent_vars[v]),
-                                &normal, 0);
-               }
-           }
+         y_max = MAX (y_max, max->value);
+         y_min = MIN (y_min, min->value);
+       }
+
+      boxplot_draw_yscale (ch, y_max, y_min);
+
+      if ( fctr->indep_var[0])
+       chart_write_title (ch, _("Boxplot of %s vs. %s"),
+                          var_to_string (dependent_var[v]),
+                          var_to_string (fctr->indep_var[0]) );
+      else
+       chart_write_title (ch, _("Boxplot of %s"),
+                          var_to_string (dependent_var[v]));
+
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list);
+          ll = ll_next (ll))
+       {
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
+         struct string str;
+         const double box_width = (ch->data_right - ch->data_left)
+           / (ll_count (&fctr->result_list) * 2.0 ) ;
+
+         const double box_centre = (f++ * 2 + 1) * box_width + ch->data_left;
+
+         ds_init_empty (&str);
+         factor_to_string_concise (fctr, result, &str);
+
+         boxplot_draw_boxplot (ch,
+                               box_centre, box_width,
+                               (const struct box_whisker *)
+                                result->metrics[v].box_whisker,
+                               ds_cstr (&str));
+
+         ds_destroy (&str);
        }
 
+      chart_submit (ch);
     }
+}
 
 
-  /* Show grouped statistics  as appropriate */
-  fctr = factors;
-  while ( fctr )
-    {
-      show_summary (dependent_vars, n_dependent_vars, fctr);
 
-      if ( cmd.sbc_statistics )
-       {
-         if ( cmd.a_statistics[XMN_ST_EXTREME])
-           show_extremes (dependent_vars, n_dependent_vars, fctr, cmd.st_n);
+static void
+show_boxplot_variables (const struct variable **dependent_var,
+                       int n_dep_var,
+                       const struct xfactor *fctr
+                       )
 
-         if ( cmd.a_statistics[XMN_ST_DESCRIPTIVES])
-           show_descriptives (dependent_vars, n_dependent_vars, fctr);
-       }
+{
+  int v;
+  struct ll *ll;
+  const struct ll_list *result_list = &fctr->result_list;
+
+  for (ll = ll_head (result_list);
+       ll != ll_null (result_list);
+       ll = ll_next (ll))
+
+    {
+      struct string title;
+      struct chart *ch = chart_create ();
+      double y_min = DBL_MAX;
+      double y_max = -DBL_MAX;
 
-      if ( sbc_percentile )
-       show_percentiles (dependent_vars, n_dependent_vars, fctr);
+      const struct factor_result *result =
+       ll_data (ll, struct factor_result, ll);
 
+      const double box_width = (ch->data_right - ch->data_left)
+       / (n_dep_var * 2.0 ) ;
 
-      if ( cmd.sbc_plot)
+      for (v = 0; v < n_dep_var; ++v)
        {
-         size_t v;
+         const struct ll *max_ll =
+           ll_head (extrema_list (result->metrics[v].maxima));
+         const struct ll *min_ll =
+           ll_head (extrema_list (result->metrics[v].minima));
 
-         struct factor_statistics **fs = fctr->fs ;
+         const struct extremum  *max =
+           (const struct extremum *) ll_data (max_ll, struct extremum, ll);
 
-         if ( cmd.a_plot[XMN_PLT_BOXPLOT] )
-           {
-             if ( cmd.cmp == XMN_VARIABLES )
-               box_plot_variables (fctr,
-                                    (const struct variable **) dependent_vars,
-                                    n_dependent_vars, cmd.v_id);
-             else
-               box_plot_group (fctr,
-                                (const struct variable **) dependent_vars,
-                                n_dependent_vars, cmd.v_id);
-           }
+          const struct extremum  *min =
+           (const struct extremum *) ll_data (min_ll, struct extremum, ll);
 
-         for ( v = 0 ; v < n_dependent_vars; ++v )
-           {
+         y_max = MAX (y_max, max->value);
+         y_min = MIN (y_min, min->value);
+       }
 
-             for ( fs = fctr->fs ; *fs ; ++fs )
-               {
-                 struct string str;
-                 ds_init_empty (&str);
-                 factor_to_string (fctr, *fs, dependent_vars[v], &str);
 
-                 if ( cmd.a_plot[XMN_PLT_NPPLOT] )
-                   np_plot (& (*fs)->m[v], ds_cstr (&str));
+      boxplot_draw_yscale (ch, y_max, y_min);
 
-                 if ( cmd.a_plot[XMN_PLT_HISTOGRAM] )
-                   {
-                     struct normal_curve normal;
+      ds_init_empty (&title);
+      factor_to_string (fctr, result, &title);
 
-                     normal.N      = (*fs)->m[v].n;
-                     normal.mean   = (*fs)->m[v].mean;
-                     normal.stddev = (*fs)->m[v].stddev;
+#if 0
+      ds_put_format (&title, "%s = ", var_get_name (fctr->indep_var[0]));
+      var_append_value_name (fctr->indep_var[0], result->value[0], &title);
+#endif
 
-                     histogram_plot ((*fs)->m[v].histogram,
-                                    ds_cstr (&str) ,  &normal, 0);
-                   }
+      chart_write_title (ch, ds_cstr (&title));
+      ds_destroy (&title);
 
-                 ds_destroy (&str);
+      for (v = 0; v < n_dep_var; ++v)
+       {
+         struct string str;
+         const double box_centre = (v * 2 + 1) * box_width + ch->data_left;
 
-               } /* for ( fs .... */
+         ds_init_empty (&str);
+         ds_init_cstr (&str, var_get_name (dependent_var[v]));
 
-           } /* for ( v = 0 ..... */
+         boxplot_draw_boxplot (ch,
+                               box_centre, box_width,
+                               (const struct box_whisker *) result->metrics[v].box_whisker,
+                               ds_cstr (&str));
 
+         ds_destroy (&str);
        }
 
-      fctr = fctr->next;
+      chart_submit (ch);
     }
-
 }
 
 
-/* Create a hash table of percentiles and their values from the list of
-   percentiles */
-static struct hsh_table *
-list_to_ptile_hash (const subc_list_double *l)
+/* Show all the appropriate tables */
+static void
+output_examine (void)
 {
-  int i;
+  struct ll *ll;
+
+  show_summary (dependent_vars, n_dependent_vars, &level0_factor);
 
-  struct hsh_table *h ;
+  if ( cmd.a_statistics[XMN_ST_EXTREME] )
+    show_extremes (dependent_vars, n_dependent_vars, &level0_factor);
 
-  h = hsh_create (subc_list_double_count (l),
-                (hsh_compare_func *) ptile_compare,
-                (hsh_hash_func *) ptile_hash,
-                (hsh_free_func *) free,
-                0);
+  if ( cmd.a_statistics[XMN_ST_DESCRIPTIVES] )
+    show_descriptives (dependent_vars, n_dependent_vars, &level0_factor);
 
+  if ( cmd.sbc_percentiles)
+    show_percentiles (dependent_vars, n_dependent_vars, &level0_factor);
 
-  for ( i = 0 ; i < subc_list_double_count (l) ; ++i )
+  if ( cmd.sbc_plot)
     {
-      struct percentile *p = xmalloc (sizeof *p);
-
-      p->p = subc_list_double_at (l,i);
-      p->v = SYSMIS;
+      if (cmd.a_plot[XMN_PLT_BOXPLOT])
+       show_boxplot_groups (dependent_vars, n_dependent_vars, &level0_factor);
 
-      hsh_insert (h, p);
+      if (cmd.a_plot[XMN_PLT_HISTOGRAM])
+       show_histogram (dependent_vars, n_dependent_vars, &level0_factor);
 
+      if (cmd.a_plot[XMN_PLT_NPPLOT])
+       show_npplot (dependent_vars, n_dependent_vars, &level0_factor);
     }
 
-  return h;
+  for (ll = ll_head (&factor_list);
+       ll != ll_null (&factor_list); ll = ll_next (ll))
+    {
+      struct xfactor *factor = ll_data (ll, struct xfactor, ll);
+      show_summary (dependent_vars, n_dependent_vars, factor);
+
+      if ( cmd.a_statistics[XMN_ST_EXTREME] )
+       show_extremes (dependent_vars, n_dependent_vars, factor);
+
+      if ( cmd.a_statistics[XMN_ST_DESCRIPTIVES] )
+       show_descriptives (dependent_vars, n_dependent_vars, factor);
+
+      if ( cmd.sbc_percentiles)
+       show_percentiles (dependent_vars, n_dependent_vars, factor);
+
+      if (cmd.a_plot[XMN_PLT_BOXPLOT] &&
+         cmd.cmp == XMN_GROUPS)
+       show_boxplot_groups (dependent_vars, n_dependent_vars, factor);
+
+
+      if (cmd.a_plot[XMN_PLT_BOXPLOT] &&
+         cmd.cmp == XMN_VARIABLES)
+       show_boxplot_variables (dependent_vars, n_dependent_vars,
+                               factor);
+
+      if (cmd.a_plot[XMN_PLT_HISTOGRAM])
+       show_histogram (dependent_vars, n_dependent_vars, factor);
 
+      if (cmd.a_plot[XMN_PLT_NPPLOT])
+       show_npplot (dependent_vars, n_dependent_vars, factor);
+    }
 }
 
 /* Parse the PERCENTILES subcommand */
 static int
 xmn_custom_percentiles (struct lexer *lexer, struct dataset *ds UNUSED,
-                      struct cmd_examine *p UNUSED, void *aux UNUSED)
+                       struct cmd_examine *p UNUSED, void *aux UNUSED)
 {
-  sbc_percentile = 1;
-
   lex_match (lexer, '=');
 
   lex_match (lexer, '(');
@@ -494,11 +739,12 @@ xmn_custom_percentiles (struct lexer *lexer, struct dataset *ds UNUSED,
 
 /* TOTAL and NOTOTAL are simple, mutually exclusive flags */
 static int
-xmn_custom_total (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, struct cmd_examine *p, void *aux UNUSED)
+xmn_custom_total (struct lexer *lexer UNUSED, struct dataset *ds UNUSED,
+                 struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_nototal )
     {
-      msg (SE, _ ("%s and %s are mutually exclusive"),"TOTAL","NOTOTAL");
+      msg (SE, _("%s and %s are mutually exclusive"),"TOTAL","NOTOTAL");
       return 0;
     }
 
@@ -511,7 +757,7 @@ xmn_custom_nototal (struct lexer *lexer UNUSED, struct dataset *ds UNUSED,
 {
   if ( p->sbc_total )
     {
-      msg (SE, _ ("%s and %s are mutually exclusive"),"TOTAL","NOTOTAL");
+      msg (SE, _("%s and %s are mutually exclusive"), "TOTAL", "NOTOTAL");
       return 0;
     }
 
@@ -523,19 +769,21 @@ xmn_custom_nototal (struct lexer *lexer UNUSED, struct dataset *ds UNUSED,
 /* Parser for the variables sub command
    Returns 1 on success */
 static int
-xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examine *cmd, void *aux UNUSED)
+xmn_custom_variables (struct lexer *lexer, struct dataset *ds,
+                     struct cmd_examine *cmd,
+                     void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
   lex_match (lexer, '=');
 
   if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
-      && lex_token (lexer) != T_ALL)
+       && lex_token (lexer) != T_ALL)
     {
       return 2;
     }
 
   if (!parse_variables_const (lexer, dict, &dependent_vars, &n_dependent_vars,
-                       PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
+                             PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (dependent_vars);
       return 0;
@@ -543,16 +791,15 @@ xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examin
 
   assert (n_dependent_vars);
 
-  totals = xnmalloc (n_dependent_vars, sizeof *totals);
 
   if ( lex_match (lexer, T_BY))
     {
       int success ;
       success =  examine_parse_independent_vars (lexer, dict, cmd);
-      if ( success != 1 ) {
-        free (dependent_vars);
-       free (totals) ;
-      }
+      if ( success != 1 )
+       {
+         free (dependent_vars);
+       }
       return success;
     }
 
@@ -563,47 +810,44 @@ xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_examin
 
 /* Parse the clause specifying the factors */
 static int
-examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *dict, struct cmd_examine *cmd)
+examine_parse_independent_vars (struct lexer *lexer,
+                               const struct dictionary *dict,
+                               struct cmd_examine *cmd)
 {
   int success;
-  struct factor *sf = xmalloc (sizeof *sf);
+  struct xfactor *sf = xmalloc (sizeof *sf);
 
-  if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
-      && lex_token (lexer) != T_ALL)
+  ll_init (&sf->result_list);
+
+  if ( (lex_token (lexer) != T_ID ||
+       dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+       && lex_token (lexer) != T_ALL)
     {
       free ( sf ) ;
       return 2;
     }
 
-
   sf->indep_var[0] = parse_variable (lexer, dict);
-  sf->indep_var[1] = 0;
+  sf->indep_var[1] = NULL;
 
   if ( lex_token (lexer) == T_BY )
     {
-
       lex_match (lexer, T_BY);
 
-      if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
-         && lex_token (lexer) != T_ALL)
+      if ( (lex_token (lexer) != T_ID ||
+           dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+          && lex_token (lexer) != T_ALL)
        {
-         free ( sf ) ;
+         free (sf);
          return 2;
        }
 
       sf->indep_var[1] = parse_variable (lexer, dict);
 
+      ll_push_tail (&factor_list, &sf->ll);
     }
-
-
-  sf->fstats = hsh_create (4,
-                         (hsh_compare_func *) factor_statistics_compare,
-                         (hsh_hash_func *) factor_statistics_hash,
-                         (hsh_free_func *) factor_statistics_free,
-                         0);
-
-  sf->next = factors;
-  factors = sf;
+  else
+    ll_push_tail (&factor_list, &sf->ll);
 
   lex_match (lexer, ',');
 
@@ -618,335 +862,378 @@ examine_parse_independent_vars (struct lexer *lexer, const struct dictionary *di
   return success;
 }
 
+static void
+examine_group (struct cmd_examine *cmd, struct casereader *reader, int level,
+              const struct dictionary *dict, struct xfactor *factor)
+{
+  struct ccase c;
+  const struct variable *wv = dict_get_weight (dict);
+  int v;
+  int n_extrema = 1;
+  struct factor_result *result = xzalloc (sizeof (*result));
+
+  result->metrics = xcalloc (n_dependent_vars, sizeof (*result->metrics));
 
+  if ( cmd->a_statistics[XMN_ST_EXTREME] )
+    n_extrema = cmd->st_n;
 
 
-void populate_percentiles (struct tab_table *tbl, int col, int row,
-                         const struct metrics *m);
+  if (casereader_peek (reader, 0, &c))
+    {
+      if ( level > 0)
+       {
+         result->value[0] =
+           value_dup (case_data (&c, factor->indep_var[0]),
+                      var_get_width (factor->indep_var[0]));
+
+         if ( level > 1)
+           result->value[1] =
+             value_dup (case_data (&c, factor->indep_var[1]),
+                        var_get_width (factor->indep_var[1]));
+       }
+      case_destroy (&c);
+    }
+
+  for (v = 0; v < n_dependent_vars; ++v)
+    {
+      struct casewriter *writer;
+      struct casereader *input = casereader_clone (reader);
+
+      result->metrics[v].moments = moments1_create (MOMENT_KURTOSIS);
+      result->metrics[v].minima = extrema_create (n_extrema, EXTREME_MINIMA);
+      result->metrics[v].maxima = extrema_create (n_extrema, EXTREME_MAXIMA);
+      result->metrics[v].cmin = DBL_MAX;
+
+      if (cmd->a_statistics[XMN_ST_DESCRIPTIVES] ||
+         cmd->a_plot[XMN_PLT_BOXPLOT] ||
+         cmd->a_plot[XMN_PLT_NPPLOT] ||
+         cmd->sbc_percentiles)
+       {
+         /* In this case, we need to sort the data, so we create a sorting
+            casewriter */
+         struct case_ordering *up_ordering = case_ordering_create ();
 
-void populate_descriptives (struct tab_table *t, int col, int row,
-                          const struct metrics *fs);
+         case_ordering_add_var (up_ordering, dependent_vars[v], SRT_ASCEND);
+         writer = sort_create_writer (up_ordering,
+                                      casereader_get_value_cnt (reader));
+       }
+      else
+       {
+         /* but in this case, sorting is unnecessary, so an ordinary
+            casewriter is sufficient */
+         writer =
+           autopaging_writer_create (casereader_get_value_cnt (reader));
+       }
 
-void populate_extremes (struct tab_table *t, int col, int row, int n,
-                      const struct metrics *m);
 
-void populate_summary (struct tab_table *t, int col, int row,
-                     const struct metrics *m);
+      /* Sort or just iterate, whilst calculating moments etc */
+      while (casereader_read (input, &c))
+       {
+         const casenumber loc =
+             case_data_idx (&c, casereader_get_value_cnt (reader) - 1)->f;
 
+         const double weight = wv ? case_data (&c, wv)->f : 1.0;
 
+         if (weight != SYSMIS)
+           minimize (&result->metrics[v].cmin, weight);
 
+         moments1_add (result->metrics[v].moments,
+                       case_data (&c, dependent_vars[v])->f,
+                       weight);
 
-/* Perform calculations for the sub factors */
-void
-factor_calc (const struct ccase *c, int case_no, double weight,
-            bool case_missing)
-{
-  size_t v;
-  struct factor *fctr = factors;
+         result->metrics[v].n += weight;
 
-  while ( fctr)
-    {
-      struct factor_statistics **foo ;
-      union value *indep_vals[2] ;
+         extrema_add (result->metrics[v].maxima,
+                      case_data (&c, dependent_vars[v])->f,
+                      weight,
+                      loc);
 
-      indep_vals[0] = value_dup (
-                                case_data (c, fctr->indep_var[0]),
-                                var_get_width (fctr->indep_var[0])
-                                );
+         extrema_add (result->metrics[v].minima,
+                      case_data (&c, dependent_vars[v])->f,
+                      weight,
+                      loc);
 
-      if ( fctr->indep_var[1] )
-       indep_vals[1] = value_dup (
-                                  case_data (c, fctr->indep_var[1]),
-                                  var_get_width (fctr->indep_var[1])
-                                  );
-      else
-       {
-         const union value sm = {SYSMIS};
-         indep_vals[1] = value_dup (&sm, 0);
+         casewriter_write (writer, &c);
        }
+      casereader_destroy (input);
+      result->metrics[v].up_reader = casewriter_make_reader (writer);
+    }
 
-      assert (fctr->fstats);
+  /* If percentiles or descriptives have been requested, then a
+     second pass through the data (which has now been sorted)
+     is necessary */
+  if ( cmd->a_statistics[XMN_ST_DESCRIPTIVES] ||
+       cmd->a_plot[XMN_PLT_BOXPLOT] ||
+       cmd->a_plot[XMN_PLT_NPPLOT] ||
+       cmd->sbc_percentiles)
+    {
+      for (v = 0; v < n_dependent_vars; ++v)
+       {
+         int i;
+         int n_os;
+         struct order_stats **os ;
+         struct factor_metrics *metric = &result->metrics[v];
 
-      foo = ( struct factor_statistics ** )
-       hsh_probe (fctr->fstats, (void *) &indep_vals);
+         metric->n_ptiles = percentile_list.n_data;
 
-      if ( !*foo )
-       {
+         metric->ptl = xcalloc (metric->n_ptiles,
+                                sizeof (struct percentile *));
 
-         *foo = create_factor_statistics (n_dependent_vars,
-                                         indep_vals[0],
-                                         indep_vals[1]);
+         metric->quartiles = xcalloc (3, sizeof (*metric->quartiles));
 
-         for ( v =  0 ; v  < n_dependent_vars ; ++v )
+         for (i = 0 ; i < metric->n_ptiles; ++i)
            {
-             metrics_precalc ( & (*foo)->m[v] );
+             metric->ptl[i] = (struct percentile *)
+               percentile_create (percentile_list.data[i] / 100.0, metric->n);
+
+             if ( percentile_list.data[i] == 25)
+               metric->quartiles[0] = metric->ptl[i];
+             else if ( percentile_list.data[i] == 50)
+               metric->quartiles[1] = metric->ptl[i];
+             else if ( percentile_list.data[i] == 75)
+               metric->quartiles[2] = metric->ptl[i];
            }
 
-       }
-      else
-       {
-         free (indep_vals[0]);
-         free (indep_vals[1]);
-       }
+         metric->tukey_hinges = tukey_hinges_create (metric->n, metric->cmin);
+         metric->trimmed_mean = trimmed_mean_create (metric->n, 0.05);
 
-      for ( v =  0 ; v  < n_dependent_vars ; ++v )
-       {
-         const struct variable *var = dependent_vars[v];
-         union value *val = value_dup (
-                                       case_data (c, var),
-                                       var_get_width (var)
-                                       );
+         n_os = metric->n_ptiles + 2;
 
-         if (case_missing || var_is_value_missing (var, val, exclude_values))
+        if ( cmd->a_plot[XMN_PLT_NPPLOT] )
            {
-             free (val);
-             val = NULL;
+             metric->np = np_create (metric->moments);
+             n_os ++;
            }
 
-         metrics_calc ( & (*foo)->m[v], val, weight, case_no);
+         os = xcalloc (sizeof (struct order_stats *), n_os);
 
-         free (val);
-       }
+         for (i = 0 ; i < metric->n_ptiles ; ++i )
+           {
+             os[i] = (struct order_stats *) metric->ptl[i];
+           }
 
-      fctr = fctr->next;
+         os[i] = (struct order_stats *) metric->tukey_hinges;
+         os[i+1] = (struct order_stats *) metric->trimmed_mean;
+
+         if (cmd->a_plot[XMN_PLT_NPPLOT])
+           os[i+2] = metric->np;
+
+         order_stats_accumulate (os, n_os,
+                                 casereader_clone (metric->up_reader),
+                                 wv, dependent_vars[v], MV_ANY);
+         free (os);
+       }
     }
-}
 
-static void
-run_examine (struct cmd_examine *cmd, struct casereader *input,
-             struct dataset *ds)
-{
-  struct dictionary *dict = dataset_dict (ds);
-  casenumber case_no;
-  struct ccase c;
-  int v;
-  bool ok;
-
-  struct factor *fctr;
-
-  if (!casereader_peek (input, 0, &c))
-    {
-      casereader_destroy (input);
-      return;
-    }
-  output_split_file_values (ds, &c);
-  case_destroy (&c);
-
-  input = casereader_create_filter_weight (input, dict, NULL, NULL);
-  input = casereader_create_counter (input, &case_no, 0);
-
-  /* Make sure we haven't got rubbish left over from a
-     previous split. */
-  fctr = factors;
-  while (fctr)
+  /* FIXME: Do this in the above loop */
+  if ( cmd->a_plot[XMN_PLT_HISTOGRAM] )
     {
-      struct factor *next = fctr->next;
+      struct ccase c;
+      struct casereader *input = casereader_clone (reader);
 
-      hsh_clear (fctr->fstats);
+      for (v = 0; v < n_dependent_vars; ++v)
+       {
+         const struct extremum  *max, *min;
+         struct factor_metrics *metric = &result->metrics[v];
 
-      fctr->fs = 0;
+         const struct ll_list *max_list =
+           extrema_list (result->metrics[v].maxima);
 
-      fctr = next;
-    }
+         const struct ll_list *min_list =
+           extrema_list (result->metrics[v].minima);
 
-  for ( v = 0 ; v < n_dependent_vars ; ++v )
-    metrics_precalc (&totals[v]);
+         if ( ll_is_empty (max_list))
+           {
+             msg (MW, _("Not creating plot because data set is empty."));
+             continue;
+           }
 
-  for (; casereader_read (input, &c); case_destroy (&c))
-    {
-      bool case_missing = false;
-      const double weight = dict_get_case_weight (dict, &c, NULL);
+         assert (! ll_is_empty (min_list));
 
-      if ( cmd->miss == XMN_LISTWISE )
-       {
-         for ( v = 0 ; v < n_dependent_vars ; ++v )
-           {
-             const struct variable *var = dependent_vars[v];
-             union value *val = value_dup (
-                                                 case_data (&c, var),
-                                                 var_get_width (var)
-                                                 );
+         max = (const struct extremum *)
+           ll_data (ll_head(max_list), struct extremum, ll);
 
-             if ( var_is_value_missing (var, val, exclude_values))
-               case_missing = true;
+          min = (const struct extremum *)
+           ll_data (ll_head (min_list), struct extremum, ll);
 
-             free (val);
-           }
+         metric->histogram = histogram_create (10, min->value, max->value);
        }
 
-      for ( v = 0 ; v < n_dependent_vars ; ++v )
+      while (casereader_read (input, &c))
        {
-         const struct variable *var = dependent_vars[v];
-         union value *val = value_dup (
-                                       case_data (&c, var),
-                                       var_get_width (var)
-                                       );
-
-         if ( var_is_value_missing (var, val, exclude_values)
-               || case_missing )
+         const double weight = wv ? case_data (&c, wv)->f : 1.0;
+
+         for (v = 0; v < n_dependent_vars; ++v)
            {
-             free (val) ;
-             val = NULL;
+             struct factor_metrics *metric = &result->metrics[v];
+             if ( metric->histogram)
+               histogram_add ((struct histogram *) metric->histogram,
+                              case_data (&c, dependent_vars[v])->f, weight);
            }
-
-         metrics_calc (&totals[v], val, weight, case_no);
-
-         free (val);
+         case_destroy (&c);
        }
-
-      factor_calc (&c, case_no, weight, case_missing);
+      casereader_destroy (input);
     }
-  ok = casereader_destroy (input);
 
-  for ( v = 0 ; v < n_dependent_vars ; ++v)
+  /* In this case, a third iteration is required */
+  if (cmd->a_plot[XMN_PLT_BOXPLOT])
     {
-      fctr = factors;
-      while ( fctr )
+      for (v = 0; v < n_dependent_vars; ++v)
        {
-         struct hsh_iterator hi;
-         struct factor_statistics *fs;
+         struct factor_metrics *metric = &result->metrics[v];
+
+         metric->box_whisker =
+           box_whisker_create ((struct tukey_hinges *) metric->tukey_hinges,
+                               cmd->v_id,
+                               casereader_get_value_cnt (metric->up_reader)
+                               - 1);
+
+         order_stats_accumulate ((struct order_stats **) &metric->box_whisker,
+                                 1,
+                                 casereader_clone (metric->up_reader),
+                                 wv, dependent_vars[v], MV_ANY);
+       }
+    }
 
-         for ( fs = hsh_first (fctr->fstats, &hi);
-               fs != 0 ;
-               fs = hsh_next (fctr->fstats, &hi))
-           {
+  ll_push_tail (&factor->result_list, &result->ll);
+  casereader_destroy (reader);
+}
 
-             fs->m[v].ptile_hash = list_to_ptile_hash (&percentile_list);
-             fs->m[v].ptile_alg = percentile_algorithm;
-             metrics_postcalc (&fs->m[v]);
-           }
 
-         fctr = fctr->next;
-       }
+static void
+run_examine (struct cmd_examine *cmd, struct casereader *input,
+             struct dataset *ds)
+{
+  struct ll *ll;
+  const struct dictionary *dict = dataset_dict (ds);
+  struct ccase c;
+  struct casereader *level0 = casereader_clone (input);
 
-      totals[v].ptile_hash = list_to_ptile_hash (&percentile_list);
-      totals[v].ptile_alg = percentile_algorithm;
-      metrics_postcalc (&totals[v]);
+  if (!casereader_peek (input, 0, &c))
+    {
+      casereader_destroy (input);
+      return;
     }
 
+  output_split_file_values (ds, &c);
+  case_destroy (&c);
+
+  ll_init (&level0_factor.result_list);
 
-  /* Make sure that the combination of factors are complete */
+  examine_group (cmd, level0, 0, dict, &level0_factor);
 
-  fctr = factors;
-  while ( fctr )
+  for (ll = ll_head (&factor_list);
+       ll != ll_null (&factor_list);
+       ll = ll_next (ll))
     {
-      struct hsh_iterator hi;
-      struct hsh_iterator hi0;
-      struct hsh_iterator hi1;
-      struct factor_statistics *fs;
+      struct xfactor *factor = ll_data (ll, struct xfactor, ll);
 
-      struct hsh_table *idh0 = NULL;
-      struct hsh_table *idh1 = NULL;
-      union value **val0;
-      union value **val1;
+      struct casereader *group = NULL;
+      struct casereader *level1;
+      struct casegrouper *grouper1 = NULL;
+      struct case_ordering *ordering1 = case_ordering_create ();
+      case_ordering_add_var (ordering1, factor->indep_var[0], SRT_ASCEND);
 
-      idh0 = hsh_create (4, (hsh_compare_func *) compare_ptr_values,
-                        (hsh_hash_func *) hash_ptr_value,
-                       0,0);
+      level1 = casereader_clone (input);
 
-      idh1 = hsh_create (4, (hsh_compare_func *) compare_ptr_values,
-                        (hsh_hash_func *) hash_ptr_value,
-                       0,0);
+      level1 = sort_execute (level1,
+                            case_ordering_clone (ordering1));
+      grouper1 = casegrouper_create_case_ordering (level1, ordering1);
+      case_ordering_destroy (ordering1);
 
-
-      for ( fs = hsh_first (fctr->fstats, &hi);
-           fs != 0 ;
-           fs = hsh_next (fctr->fstats, &hi))
+      while (casegrouper_get_next_group (grouper1, &group))
        {
-         hsh_insert (idh0, &fs->id[0]);
-         hsh_insert (idh1, &fs->id[1]);
-       }
+         struct casereader *group_copy = casereader_clone (group);
 
-      /* Ensure that the factors combination is complete */
-      for ( val0 = hsh_first (idh0, &hi0);
-           val0 != 0 ;
-           val0 = hsh_next (idh0, &hi0))
-       {
-         for ( val1 = hsh_first (idh1, &hi1);
-               val1 != 0 ;
-               val1 = hsh_next (idh1, &hi1))
+         if ( !factor->indep_var[1])
+           examine_group (cmd, group_copy, 1, dict, factor);
+         else
            {
-             struct factor_statistics **ffs;
-             union value *key[2];
-             key[0] = *val0;
-             key[1] = *val1;
-
-             ffs = (struct factor_statistics **)
-               hsh_probe (fctr->fstats, &key );
-
-             if ( !*ffs ) {
-               size_t i;
-                (*ffs) = create_factor_statistics (n_dependent_vars,
-                                                  key[0], key[1]);
-               for ( i = 0 ; i < n_dependent_vars ; ++i )
-                 metrics_precalc ( & (*ffs)->m[i]);
-             }
-           }
-       }
+             int n_groups = 0;
+             struct casereader *group2 = NULL;
+             struct casegrouper *grouper2 = NULL;
+             struct case_ordering *ordering2 = case_ordering_create ();
+
+             case_ordering_add_var (ordering2,
+                                    factor->indep_var[1], SRT_ASCEND);
+             group_copy = sort_execute (group_copy,
+                                    case_ordering_clone (ordering2));
+             grouper2 =
+               casegrouper_create_case_ordering (group_copy, ordering2);
 
-      hsh_destroy (idh0);
-      hsh_destroy (idh1);
+             case_ordering_destroy (ordering2);
 
-      fctr->fs = (struct factor_statistics **) hsh_sort_copy (fctr->fstats);
+             while (casegrouper_get_next_group (grouper2, &group2))
+               {
+                 examine_group (cmd, group2, 2, dict, factor);
+                 n_groups++;
+               }
+             casegrouper_destroy (grouper2);
+           }
 
-      fctr = fctr->next;
+         casereader_destroy (group);
+       }
+      casegrouper_destroy (grouper1);
     }
 
-  if (ok)
-    output_examine ();
+  casereader_destroy (input);
 
+  output_examine ();
+
+  factor_destroy (&level0_factor);
+
+  {
+    struct ll *ll;
+    for (ll = ll_head (&factor_list);
+        ll != ll_null (&factor_list);
+        ll = ll_next (ll))
+      {
+       struct xfactor *f = ll_data (ll, struct xfactor, ll);
+       factor_destroy (f);
+      }
+  }
 
-  if ( totals )
-    {
-      size_t i;
-      for ( i = 0 ; i < n_dependent_vars ; ++i )
-       {
-         metrics_destroy (&totals[i]);
-       }
-    }
 }
 
 
 static void
 show_summary (const struct variable **dependent_var, int n_dep_var,
-            const struct factor *fctr)
+             const struct xfactor *fctr)
 {
   static const char *subtitle[]=
     {
-      N_ ("Valid"),
-      N_ ("Missing"),
-      N_ ("Total")
+      N_("Valid"),
+      N_("Missing"),
+      N_("Total")
     };
 
-  int i;
-  int heading_columns ;
+  int v, j;
+  int heading_columns = 1;
   int n_cols;
   const int heading_rows = 3;
   struct tab_table *tbl;
 
   int n_rows ;
-  int n_factors = 1;
+  n_rows = n_dep_var;
+
+  assert (fctr);
 
-  if ( fctr )
+  if ( fctr->indep_var[0] )
     {
       heading_columns = 2;
-      n_factors = hsh_count (fctr->fstats);
-      n_rows = n_dep_var * n_factors ;
 
       if ( fctr->indep_var[1] )
-       heading_columns = 3;
-    }
-  else
-    {
-      heading_columns = 1;
-      n_rows = n_dep_var;
+       {
+         heading_columns = 3;
+       }
     }
 
+  n_rows *= ll_count (&fctr->result_list);
   n_rows += heading_rows;
 
   n_cols = heading_columns + 6;
 
-  tbl = tab_create (n_cols,n_rows,0);
+  tbl = tab_create (n_cols, n_rows, 0);
   tab_headers (tbl, heading_columns, 0, heading_rows, 0);
 
   tab_dim (tbl, tab_natural_dimensions);
@@ -973,12 +1260,12 @@ show_summary (const struct variable **dependent_var, int n_dep_var,
   tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
 
-  tab_title (tbl, _ ("Case Processing Summary"));
+  tab_title (tbl, _("Case Processing Summary"));
 
   tab_joint_text (tbl, heading_columns, 0,
-                n_cols -1, 0,
-                TAB_CENTER | TAT_TITLE,
-                ("Cases"));
+                 n_cols -1, 0,
+                 TAB_CENTER | TAT_TITLE,
+                 _("Cases"));
 
   /* Remove lines ... */
   tab_box (tbl,
@@ -987,28 +1274,28 @@ show_summary (const struct variable **dependent_var, int n_dep_var,
           heading_columns, 0,
           n_cols - 1, 0);
 
-  for ( i = 0 ; i < 3 ; ++i )
+  for (j = 0 ; j < 3 ; ++j)
     {
-      tab_text (tbl, heading_columns + i * 2 , 2, TAB_CENTER | TAT_TITLE,
-               _ ("N"));
+      tab_text (tbl, heading_columns + j * 2 , 2, TAB_CENTER | TAT_TITLE,
+               _("N"));
 
-      tab_text (tbl, heading_columns + i * 2 + 1, 2, TAB_CENTER | TAT_TITLE,
-               _ ("Percent"));
+      tab_text (tbl, heading_columns + j * 2 + 1, 2, TAB_CENTER | TAT_TITLE,
+               _("Percent"));
 
-      tab_joint_text (tbl, heading_columns + i*2 , 1,
-                    heading_columns + i * 2 + 1, 1,
-                    TAB_CENTER | TAT_TITLE,
-                    subtitle[i]);
+      tab_joint_text (tbl, heading_columns + j * 2 , 1,
+                     heading_columns + j * 2 + 1, 1,
+                     TAB_CENTER | TAT_TITLE,
+                     subtitle[j]);
 
       tab_box (tbl, -1, -1,
               TAL_0, TAL_0,
-              heading_columns + i * 2, 1,
-              heading_columns + i * 2 + 1, 1);
+              heading_columns + j * 2, 1,
+              heading_columns + j * 2 + 1, 1);
     }
 
 
   /* Titles for the independent variables */
-  if ( fctr )
+  if ( fctr->indep_var[0] )
     {
       tab_text (tbl, 1, heading_rows - 1, TAB_CENTER | TAT_TITLE,
                var_to_string (fctr->indep_var[0]));
@@ -1020,1275 +1307,883 @@ show_summary (const struct variable **dependent_var, int n_dep_var,
        }
     }
 
-
-  for ( i = 0 ; i < n_dep_var ; ++i )
+  for (v = 0 ; v < n_dep_var ; ++v)
     {
-      int n_factors = 1;
-      if ( fctr )
-       n_factors = hsh_count (fctr->fstats);
+      int j = 0;
+      struct ll *ll;
+      union value *last_value = NULL;
 
-      if ( i > 0 )
-       tab_hline (tbl, TAL_1, 0, n_cols -1 , i * n_factors + heading_rows);
+      if ( v > 0 )
+       tab_hline (tbl, TAL_1, 0, n_cols -1 ,
+                  v * ll_count (&fctr->result_list)
+                  + heading_rows);
 
       tab_text (tbl,
-               0, i * n_factors + heading_rows,
+               0,
+               v * ll_count (&fctr->result_list) + heading_rows,
                TAB_LEFT | TAT_TITLE,
-               var_to_string (dependent_var[i])
+               var_to_string (dependent_var[v])
                );
 
-      if ( !fctr )
-       populate_summary (tbl, heading_columns,
-                        (i * n_factors) + heading_rows,
-                        &totals[i]);
-      else
+
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list); ll = ll_next (ll))
        {
-         struct factor_statistics **fs = fctr->fs;
-         int count = 0 ;
-         const union value *prev = NULL;
+         double n;
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
-         while (*fs)
+         if ( fctr->indep_var[0] )
            {
-             if ( !prev ||
-                  0 != compare_values (prev, (*fs)->id[0],
-                                  var_get_width (fctr->indep_var[0])))
+
+             if ( last_value == NULL ||
+                  compare_values (last_value, result->value[0],
+                                  fctr->indep_var[0]))
                {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[0],
-                                     (*fs)->id[0], &vstr);
-
-                 tab_text (tbl,
-                           1,
-                           (i * n_factors ) + count +
-                           heading_rows,
+                 struct string str;
+
+                 last_value = result->value[0];
+                 ds_init_empty (&str);
+
+                 var_append_value_name (fctr->indep_var[0], result->value[0],
+                                        &str);
+
+                 tab_text (tbl, 1,
+                           heading_rows + j +
+                           v * ll_count (&fctr->result_list),
                            TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                           );
+                           ds_cstr (&str));
 
-                 ds_destroy (&vstr);
+                 ds_destroy (&str);
 
-                 if (fctr->indep_var[1] && count > 0 )
+                 if ( fctr->indep_var[1] && j > 0)
                    tab_hline (tbl, TAL_1, 1, n_cols - 1,
-                             (i * n_factors ) + count + heading_rows);
+                              heading_rows + j +
+                              v * ll_count (&fctr->result_list));
                }
 
-             prev = (*fs)->id[0];
-
              if ( fctr->indep_var[1])
                {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
+                 struct string str;
+
+                 ds_init_empty (&str);
+
                  var_append_value_name (fctr->indep_var[1],
-                                        (*fs)->id[1], &vstr);
-                 tab_text (tbl,
-                           2,
-                           (i * n_factors ) + count +
-                           heading_rows,
+                                        result->value[1], &str);
+
+                 tab_text (tbl, 2,
+                           heading_rows + j +
+                           v * ll_count (&fctr->result_list),
                            TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                           );
-                 ds_destroy (&vstr);
+                           ds_cstr (&str));
+
+                 ds_destroy (&str);
                }
+           }
 
-             populate_summary (tbl, heading_columns,
-                               (i * n_factors) + count
-                               + heading_rows,
-                               & (*fs)->m[i]);
 
-             count++ ;
-             fs++;
-           }
+         moments1_calculate (result->metrics[v].moments,
+                             &n, &result->metrics[v].mean,
+                             &result->metrics[v].variance,
+                             &result->metrics[v].skewness,
+                             &result->metrics[v].kurtosis);
+
+         result->metrics[v].se_mean = sqrt (result->metrics[v].variance / n) ;
+
+         /* Total Valid */
+         tab_float (tbl, heading_columns,
+                    heading_rows + j + v * ll_count (&fctr->result_list),
+                    TAB_LEFT,
+                    n, 8, 0);
+
+         tab_text (tbl, heading_columns + 1,
+                   heading_rows + j + v * ll_count (&fctr->result_list),
+                   TAB_RIGHT | TAT_PRINTF,
+                   "%g%%", n * 100.0 / result->metrics[v].n);
+
+         /* Total Missing */
+         tab_float (tbl, heading_columns + 2,
+                    heading_rows + j + v * ll_count (&fctr->result_list),
+                    TAB_LEFT,
+                    result->metrics[v].n - n,
+                    8, 0);
+
+         tab_text (tbl, heading_columns + 3,
+                   heading_rows + j + v * ll_count (&fctr->result_list),
+                   TAB_RIGHT | TAT_PRINTF,
+                   "%g%%",
+                   (result->metrics[v].n - n) * 100.0 / result->metrics[v].n
+                   );
+
+         /* Total Valid + Missing */
+         tab_float (tbl, heading_columns + 4,
+                    heading_rows + j + v * ll_count (&fctr->result_list),
+                    TAB_LEFT,
+                    result->metrics[v].n,
+                    8, 0);
+
+         tab_text (tbl, heading_columns + 5,
+                   heading_rows + j + v * ll_count (&fctr->result_list),
+                   TAB_RIGHT | TAT_PRINTF,
+                   "%g%%",
+                   (result->metrics[v].n) * 100.0 / result->metrics[v].n
+                   );
+
+         ++j;
        }
     }
 
-  tab_submit (tbl);
-}
-
-
-void
-populate_summary (struct tab_table *t, int col, int row,
-                const struct metrics *m)
-
-{
-  const double total = m->n + m->n_missing ;
-
-  tab_float (t, col + 0, row + 0, TAB_RIGHT, m->n, 8, 0);
-  tab_float (t, col + 2, row + 0, TAB_RIGHT, m->n_missing, 8, 0);
-  tab_float (t, col + 4, row + 0, TAB_RIGHT, total, 8, 0);
-
-
-  if ( total > 0 ) {
-    tab_text (t, col + 1, row + 0, TAB_RIGHT | TAT_PRINTF, "%2.0f%%",
-             100.0 * m->n / total );
 
-    tab_text (t, col + 3, row + 0, TAB_RIGHT | TAT_PRINTF, "%2.0f%%",
-             100.0 * m->n_missing / total );
-
-    /* This seems a bit pointless !!! */
-    tab_text (t, col + 5, row + 0, TAB_RIGHT | TAT_PRINTF, "%2.0f%%",
-             100.0 * total / total );
-  }
+  tab_submit (tbl);
 }
 
-
+#define DESCRIPTIVE_ROWS 13
 
 static void
-show_extremes (const struct variable **dependent_var, int n_dep_var,
-             const struct factor *fctr, int n_extremities)
+show_descriptives (const struct variable **dependent_var,
+                  int n_dep_var,
+                  const struct xfactor *fctr)
 {
-  int i;
-  int heading_columns ;
+  int v;
+  int heading_columns = 3;
   int n_cols;
   const int heading_rows = 1;
   struct tab_table *tbl;
 
-  int n_factors = 1;
   int n_rows ;
+  n_rows = n_dep_var;
 
-  if ( fctr )
-    {
-      heading_columns = 2;
-      n_factors = hsh_count (fctr->fstats);
+  assert (fctr);
 
-      n_rows = n_dep_var * 2 * n_extremities * n_factors;
+  if ( fctr->indep_var[0] )
+    {
+      heading_columns = 4;
 
       if ( fctr->indep_var[1] )
-       heading_columns = 3;
-    }
-  else
-    {
-      heading_columns = 1;
-      n_rows = n_dep_var * 2 * n_extremities;
+       {
+         heading_columns = 5;
+       }
     }
 
+  n_rows *= ll_count (&fctr->result_list) * DESCRIPTIVE_ROWS;
   n_rows += heading_rows;
 
-  heading_columns += 2;
   n_cols = heading_columns + 2;
 
-  tbl = tab_create (n_cols,n_rows,0);
+  tbl = tab_create (n_cols, n_rows, 0);
   tab_headers (tbl, heading_columns, 0, heading_rows, 0);
 
   tab_dim (tbl, tab_natural_dimensions);
 
-  /* Outline the box, No internal lines*/
+  /* Outline the box */
   tab_box (tbl,
           TAL_2, TAL_2,
           -1, -1,
           0, 0,
           n_cols - 1, n_rows - 1);
 
-  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
 
-  tab_title (tbl, _ ("Extreme Values"));
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
+  tab_hline (tbl, TAL_2, 1, n_cols - 1, heading_rows );
 
-  tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows -1);
-  tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows -1);
+  tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows - 1);
 
-  if ( fctr )
-    {
-      tab_text (tbl, 1, heading_rows - 1, TAB_CENTER | TAT_TITLE,
-               var_to_string (fctr->indep_var[0]));
 
-      if ( fctr->indep_var[1] )
-       tab_text (tbl, 2, heading_rows - 1, TAB_CENTER | TAT_TITLE,
-                 var_to_string (fctr->indep_var[1]));
-    }
+  if ( fctr->indep_var[0])
+    tab_text (tbl, 1, 0, TAT_TITLE, var_to_string (fctr->indep_var[0]));
 
-  tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _ ("Value"));
-  tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _ ("Case Number"));
+  if ( fctr->indep_var[1])
+    tab_text (tbl, 2, 0, TAT_TITLE, var_to_string (fctr->indep_var[1]));
 
-  for ( i = 0 ; i < n_dep_var ; ++i )
+  for (v = 0 ; v < n_dep_var ; ++v )
     {
+      struct ll *ll;
+      int i = 0;
 
-      if ( i > 0 )
-       tab_hline (tbl, TAL_1, 0, n_cols -1 ,
-                 i * 2 * n_extremities * n_factors + heading_rows);
+      const int row_var_start =
+       v * DESCRIPTIVE_ROWS * ll_count(&fctr->result_list);
 
-      tab_text (tbl, 0,
-               i * 2 * n_extremities * n_factors  + heading_rows,
+      tab_text (tbl,
+               0,
+               heading_rows + row_var_start,
                TAB_LEFT | TAT_TITLE,
-               var_to_string (dependent_var[i])
+               var_to_string (dependent_var[v])
                );
 
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list); i++, ll = ll_next (ll))
+       {
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
-      if ( !fctr )
-       populate_extremes (tbl, heading_columns - 2,
-                         i * 2 * n_extremities * n_factors  + heading_rows,
-                         n_extremities, &totals[i]);
+         const double t =
+           gsl_cdf_tdist_Qinv ((1 - cmd.n_cinterval[0] / 100.0) / 2.0,
+                                      result->metrics[v].n - 1);
 
-      else
-       {
-         struct factor_statistics **fs = fctr->fs;
-         int count = 0 ;
-         const union value *prev  = NULL;
+         if ( i > 0 || v > 0 )
+           {
+             const int left_col = (i == 0) ? 0 : 1;
+             tab_hline (tbl, TAL_1, left_col, n_cols - 1,
+                        heading_rows + row_var_start + i * DESCRIPTIVE_ROWS);
+           }
 
-         while (*fs)
+         if ( fctr->indep_var[0])
            {
-             const int row = heading_rows + ( 2 * n_extremities )  *
-                ( ( i  * n_factors  ) +  count );
+             struct string vstr;
+             ds_init_empty (&vstr);
+             var_append_value_name (fctr->indep_var[0],
+                                    result->value[0], &vstr);
+
+             tab_text (tbl, 1,
+                       heading_rows + row_var_start + i * DESCRIPTIVE_ROWS,
+                       TAB_LEFT,
+                       ds_cstr (&vstr)
+                       );
 
+             ds_destroy (&vstr);
+           }
 
-             if ( !prev || 0 != compare_values (prev, (*fs)->id[0],
-                                        var_get_width (fctr->indep_var[0])))
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[0],
-                                     (*fs)->id[0], &vstr);
 
-                 if ( count > 0 )
-                   tab_hline (tbl, TAL_1, 1, n_cols - 1, row);
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Mean"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT | TAT_PRINTF,
+                   _("%g%% Confidence Interval for Mean"),
+                   cmd.n_cinterval[0]);
+
+         tab_text (tbl, n_cols - 3,
+                   heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Lower Bound"));
+
+         tab_text (tbl, n_cols - 3,
+                   heading_rows + row_var_start + 2 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Upper Bound"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 3 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT | TAT_PRINTF,
+                   _("5%% Trimmed Mean"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 4 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Median"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 5 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Variance"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 6 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Std. Deviation"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 7 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Minimum"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 8 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Maximum"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 9 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Range"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 10 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Interquartile Range"));
+
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 11 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Skewness"));
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + 12 + i * DESCRIPTIVE_ROWS,
+                   TAB_LEFT,
+                   _("Kurtosis"));
+
+
+         /* Now the statistics ... */
+
+         tab_float (tbl, n_cols - 2,
+                   heading_rows + row_var_start + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].mean,
+                    8, 2);
+
+         tab_float (tbl, n_cols - 1,
+                   heading_rows + row_var_start + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].se_mean,
+                    8, 3);
+
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].mean - t *
+                     result->metrics[v].se_mean,
+                    8, 3);
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 2 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].mean + t *
+                     result->metrics[v].se_mean,
+                    8, 3);
+
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 3 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    trimmed_mean_calculate ((struct trimmed_mean *) result->metrics[v].trimmed_mean),
+                    8, 2);
+
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 4 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    percentile_calculate (result->metrics[v].quartiles[1], percentile_algorithm),
+                    8, 2);
+
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 5 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].variance,
+                    8, 3);
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 6 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    sqrt (result->metrics[v].variance),
+                    8, 3);
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 10 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    percentile_calculate (result->metrics[v].quartiles[2],
+                                          percentile_algorithm) -
+                    percentile_calculate (result->metrics[v].quartiles[0],
+                                          percentile_algorithm),
+                    8, 2);
+
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 11 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].skewness,
+                    8, 3);
+
+         tab_float (tbl, n_cols - 2,
+                    heading_rows + row_var_start + 12 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    result->metrics[v].kurtosis,
+                    8, 3);
+
+         tab_float (tbl, n_cols - 1,
+                    heading_rows + row_var_start + 11 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    calc_seskew (result->metrics[v].n),
+                    8, 3);
+
+         tab_float (tbl, n_cols - 1,
+                    heading_rows + row_var_start + 12 + i * DESCRIPTIVE_ROWS,
+                    TAB_CENTER,
+                    calc_sekurt (result->metrics[v].n),
+                    8, 3);
+
+         {
+           struct extremum *minimum, *maximum ;
+
+           struct ll *max_ll = ll_head (extrema_list (result->metrics[v].maxima));
+           struct ll *min_ll = ll_head (extrema_list (result->metrics[v].minima));
+
+           maximum = ll_data (max_ll, struct extremum, ll);
+           minimum = ll_data (min_ll, struct extremum, ll);
+
+           tab_float (tbl, n_cols - 2,
+                      heading_rows + row_var_start + 7 + i * DESCRIPTIVE_ROWS,
+                      TAB_CENTER,
+                      minimum->value,
+                      8, 3);
+
+           tab_float (tbl, n_cols - 2,
+                      heading_rows + row_var_start + 8 + i * DESCRIPTIVE_ROWS,
+                      TAB_CENTER,
+                      maximum->value,
+                      8, 3);
+
+           tab_float (tbl, n_cols - 2,
+                      heading_rows + row_var_start + 9 + i * DESCRIPTIVE_ROWS,
+                      TAB_CENTER,
+                      maximum->value - minimum->value,
+                      8, 3);
+         }
+       }
+    }
 
-                 tab_text (tbl,
-                           1, row,
-                           TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                           );
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
-                 ds_destroy (&vstr);
-               }
+  tab_title (tbl, _("Descriptives"));
 
-             prev = (*fs)->id[0];
+  tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE,
+           _("Statistic"));
 
-             if (fctr->indep_var[1] && count > 0 )
-               tab_hline (tbl, TAL_1, 2, n_cols - 1, row);
+  tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE,
+           _("Std. Error"));
 
-             if ( fctr->indep_var[1])
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[1], (*fs)->id[1], &vstr);
+  tab_submit (tbl);
+}
 
-               tab_text (tbl, 2, row,
-                         TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                         );
 
-                 ds_destroy (&vstr);
-               }
 
-             populate_extremes (tbl, heading_columns - 2,
-                               row, n_extremities,
-                               & (*fs)->m[i]);
+static void
+show_extremes (const struct variable **dependent_var,
+              int n_dep_var,
+              const struct xfactor *fctr)
+{
+  int v;
+  int heading_columns = 3;
+  int n_cols;
+  const int heading_rows = 1;
+  struct tab_table *tbl;
+
+  int n_rows ;
+  n_rows = n_dep_var;
 
-             count++ ;
-             fs++;
-           }
+  assert (fctr);
+
+  if ( fctr->indep_var[0] )
+    {
+      heading_columns = 4;
+
+      if ( fctr->indep_var[1] )
+       {
+         heading_columns = 5;
        }
     }
 
-  tab_submit (tbl);
-}
+  n_rows *= ll_count (&fctr->result_list) * cmd.st_n * 2;
+  n_rows += heading_rows;
 
+  n_cols = heading_columns + 2;
 
+  tbl = tab_create (n_cols, n_rows, 0);
+  tab_headers (tbl, heading_columns, 0, heading_rows, 0);
 
-/* Fill in the extremities table */
-void
-populate_extremes (struct tab_table *t,
-                 int col, int row, int n, const struct metrics *m)
-{
-  int extremity;
-  int idx=0;
+  tab_dim (tbl, tab_natural_dimensions);
 
+  /* Outline the box */
+  tab_box (tbl,
+          TAL_2, TAL_2,
+          -1, -1,
+          0, 0,
+          n_cols - 1, n_rows - 1);
 
-  tab_text (t, col, row,
-          TAB_RIGHT | TAT_TITLE ,
-          _ ("Highest")
-          );
 
-  tab_text (t, col, row + n ,
-          TAB_RIGHT | TAT_TITLE ,
-          _ ("Lowest")
-          );
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
+  tab_hline (tbl, TAL_2, 1, n_cols - 1, heading_rows );
+  tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows - 1);
 
+  if ( fctr->indep_var[0])
+    tab_text (tbl, 1, 0, TAT_TITLE, var_to_string (fctr->indep_var[0]));
 
-  tab_hline (t, TAL_1, col, col + 3, row + n );
+  if ( fctr->indep_var[1])
+    tab_text (tbl, 2, 0, TAT_TITLE, var_to_string (fctr->indep_var[1]));
 
-  for (extremity = 0; extremity < n ; ++extremity )
+  for (v = 0 ; v < n_dep_var ; ++v )
     {
-      /* Highest */
-      tab_float (t, col + 1, row + extremity,
-               TAB_RIGHT,
-               extremity + 1, 8, 0);
+      struct ll *ll;
+      int i = 0;
+      const int row_var_start = v * cmd.st_n * 2 * ll_count(&fctr->result_list);
 
+      tab_text (tbl,
+               0,
+               heading_rows + row_var_start,
+               TAB_LEFT | TAT_TITLE,
+               var_to_string (dependent_var[v])
+               );
 
-      /* Lowest */
-      tab_float (t, col + 1, row + extremity + n,
-               TAB_RIGHT,
-               extremity + 1, 8, 0);
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list); i++, ll = ll_next (ll))
+       {
+         int e ;
+         struct ll *min_ll;
+         struct ll *max_ll;
+         const int row_result_start = i * cmd.st_n * 2;
 
-    }
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
+         if (i > 0 || v > 0)
+           tab_hline (tbl, TAL_1, 1, n_cols - 1,
+                      heading_rows + row_var_start + row_result_start);
 
-  /* Lowest */
-  for (idx = 0, extremity = 0; extremity < n && idx < m->n_data ; ++idx )
-    {
-      int j;
-      const struct weighted_value *wv = m->wvp[idx];
-      struct case_node *cn = wv->case_nos;
+         tab_hline (tbl, TAL_1, heading_columns - 2, n_cols - 1,
+                    heading_rows + row_var_start + row_result_start + cmd.st_n);
 
+         for ( e = 1; e <= cmd.st_n; ++e )
+           {
+             tab_text (tbl, n_cols - 3,
+                       heading_rows + row_var_start + row_result_start + e - 1,
+                       TAB_RIGHT | TAT_PRINTF,
+                       _("%d"), e);
+
+             tab_text (tbl, n_cols - 3,
+                       heading_rows + row_var_start + row_result_start + cmd.st_n + e - 1,
+                       TAB_RIGHT | TAT_PRINTF,
+                       _("%d"), e);
+           }
 
-      for (j = 0 ; j < wv->w ; ++j  )
-       {
-         if ( extremity + j >= n )
-           break ;
 
-         tab_float (t, col + 3, row + extremity + j  + n,
-                   TAB_RIGHT,
-                   wv->v.f, 8, 2);
+         min_ll = ll_head (extrema_list (result->metrics[v].minima));
+         for (e = 0; e < cmd.st_n;)
+           {
+             struct extremum *minimum = ll_data (min_ll, struct extremum, ll);
+             double weight = minimum->weight;
 
-         tab_float (t, col + 2, row + extremity + j  + n,
-                   TAB_RIGHT,
-                   cn->num, 8, 0);
+             while (weight-- > 0 && e < cmd.st_n)
+               {
+                 tab_float (tbl, n_cols - 1,
+                            heading_rows + row_var_start + row_result_start + cmd.st_n + e,
+                            TAB_RIGHT,
+                            minimum->value,
+                            8, 2);
+
+
+                 tab_float (tbl, n_cols - 2,
+                            heading_rows + row_var_start + row_result_start + cmd.st_n + e,
+                            TAB_RIGHT,
+                            minimum->location,
+                            8, 0);
+                 ++e;
+               }
 
-         if ( cn->next )
-           cn = cn->next;
+             min_ll = ll_next (min_ll);
+           }
 
-       }
 
-      extremity +=  wv->w ;
-    }
+         max_ll = ll_head (extrema_list (result->metrics[v].maxima));
+         for (e = 0; e < cmd.st_n;)
+           {
+             struct extremum *maximum = ll_data (max_ll, struct extremum, ll);
+             double weight = maximum->weight;
 
+             while (weight-- > 0 && e < cmd.st_n)
+               {
+                 tab_float (tbl, n_cols - 1,
+                            heading_rows + row_var_start + row_result_start + e,
+                            TAB_RIGHT,
+                            maximum->value,
+                            8, 2);
+
+
+                 tab_float (tbl, n_cols - 2,
+                            heading_rows + row_var_start + row_result_start + e,
+                            TAB_RIGHT,
+                            maximum->location,
+                            8, 0);
+                 ++e;
+               }
 
-  /* Highest */
-  for (idx = m->n_data - 1, extremity = 0; extremity < n && idx >= 0; --idx )
-    {
-      int j;
-      const struct weighted_value *wv = m->wvp[idx];
-      struct case_node *cn = wv->case_nos;
+             max_ll = ll_next (max_ll);
+           }
 
-      for (j = 0 ; j < wv->w ; ++j  )
-       {
-         if ( extremity + j >= n )
-           break ;
 
-         tab_float (t, col + 3, row + extremity + j,
+         if ( fctr->indep_var[0])
+           {
+             struct string vstr;
+             ds_init_empty (&vstr);
+             var_append_value_name (fctr->indep_var[0],
+                                    result->value[0], &vstr);
+
+             tab_text (tbl, 1,
+                       heading_rows + row_var_start + row_result_start,
+                       TAB_LEFT,
+                       ds_cstr (&vstr)
+                       );
+
+             ds_destroy (&vstr);
+           }
+
+
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + row_result_start,
                    TAB_RIGHT,
-                   wv->v.f, 8, 2);
+                   _("Highest"));
 
-         tab_float (t, col + 2, row + extremity + j,
+         tab_text (tbl, n_cols - 4,
+                   heading_rows + row_var_start + row_result_start + cmd.st_n,
                    TAB_RIGHT,
-                   cn->num, 8, 0);
+                   _("Lowest"));
+       }
+    }
 
-         if ( cn->next )
-           cn = cn->next;
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
-       }
 
-      extremity +=  wv->w ;
-    }
+  tab_title (tbl, _("Extreme Values"));
+
+
+  tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE,
+           _("Case Number"));
+
+
+  tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE,
+           _("Value"));
+
+  tab_submit (tbl);
 }
 
+#define PERCENTILE_ROWS 2
 
-/* Show the descriptives table */
-void
-show_descriptives (const struct variable **dependent_var,
+static void
+show_percentiles (const struct variable **dependent_var,
                  int n_dep_var,
-                 struct factor *fctr)
+                 const struct xfactor *fctr)
 {
   int i;
-  int heading_columns ;
+  int v;
+  int heading_columns = 2;
   int n_cols;
-  const int n_stat_rows = 13;
-
-  const int heading_rows = 1;
-
+  const int n_percentiles = subc_list_double_count (&percentile_list);
+  const int heading_rows = 2;
   struct tab_table *tbl;
 
-  int n_factors = 1;
   int n_rows ;
+  n_rows = n_dep_var;
 
-  if ( fctr )
-    {
-      heading_columns = 4;
-      n_factors = hsh_count (fctr->fstats);
-
-      n_rows = n_dep_var * n_stat_rows * n_factors;
+  assert (fctr);
 
-      if ( fctr->indep_var[1] )
-       heading_columns = 5;
-    }
-  else
+  if ( fctr->indep_var[0] )
     {
       heading_columns = 3;
-      n_rows = n_dep_var * n_stat_rows;
+
+      if ( fctr->indep_var[1] )
+       {
+         heading_columns = 4;
+       }
     }
 
+  n_rows *= ll_count (&fctr->result_list) * PERCENTILE_ROWS;
   n_rows += heading_rows;
 
-  n_cols = heading_columns + 2;
-
+  n_cols = heading_columns + n_percentiles;
 
   tbl = tab_create (n_cols, n_rows, 0);
-
-  tab_headers (tbl, heading_columns + 1, 0, heading_rows, 0);
+  tab_headers (tbl, heading_columns, 0, heading_rows, 0);
 
   tab_dim (tbl, tab_natural_dimensions);
 
-  /* Outline the box and have no internal lines*/
+  /* Outline the box */
   tab_box (tbl,
           TAL_2, TAL_2,
           -1, -1,
           0, 0,
           n_cols - 1, n_rows - 1);
 
-  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
-
-  tab_vline (tbl, TAL_1, heading_columns, 0, n_rows - 1);
-  tab_vline (tbl, TAL_2, n_cols - 2, 0, n_rows - 1);
-  tab_vline (tbl, TAL_1, n_cols - 1, 0, n_rows - 1);
 
-  tab_text (tbl, n_cols - 2, 0, TAB_CENTER | TAT_TITLE, _ ("Statistic"));
-  tab_text (tbl, n_cols - 1, 0, TAB_CENTER | TAT_TITLE, _ ("Std. Error"));
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows );
+  tab_hline (tbl, TAL_2, 1, n_cols - 1, heading_rows );
 
-  tab_title (tbl, _ ("Descriptives"));
+  if ( fctr->indep_var[0])
+    tab_text (tbl, 1, 1, TAT_TITLE, var_to_string (fctr->indep_var[0]));
 
+  if ( fctr->indep_var[1])
+    tab_text (tbl, 2, 1, TAT_TITLE, var_to_string (fctr->indep_var[1]));
 
-  for ( i = 0 ; i < n_dep_var ; ++i )
+  for (v = 0 ; v < n_dep_var ; ++v )
     {
-      const int row = heading_rows + i * n_stat_rows * n_factors ;
+      double hinges[3];
+      struct ll *ll;
+      int i = 0;
 
-      if ( i > 0 )
-       tab_hline (tbl, TAL_1, 0, n_cols - 1, row );
+      const int row_var_start =
+       v * PERCENTILE_ROWS * ll_count(&fctr->result_list);
 
-      tab_text (tbl, 0,
-               i * n_stat_rows * n_factors  + heading_rows,
+      tab_text (tbl,
+               0,
+               heading_rows + row_var_start,
                TAB_LEFT | TAT_TITLE,
-               var_to_string (dependent_var[i])
+               var_to_string (dependent_var[v])
                );
 
-
-      if ( fctr  )
+      for (ll = ll_head (&fctr->result_list);
+          ll != ll_null (&fctr->result_list); i++, ll = ll_next (ll))
        {
-         const union value *prev = NULL;
+         int j;
+         const struct factor_result *result =
+           ll_data (ll, struct factor_result, ll);
 
-         struct factor_statistics **fs = fctr->fs;
-         int count = 0;
+         if ( i > 0 || v > 0 )
+           {
+             const int left_col = (i == 0) ? 0 : 1;
+             tab_hline (tbl, TAL_1, left_col, n_cols - 1,
+                        heading_rows + row_var_start + i * PERCENTILE_ROWS);
+           }
 
-         tab_text (tbl, 1, heading_rows - 1, TAB_CENTER | TAT_TITLE,
-                   var_to_string (fctr->indep_var[0]));
+         if ( fctr->indep_var[0])
+           {
+             struct string vstr;
+             ds_init_empty (&vstr);
+             var_append_value_name (fctr->indep_var[0],
+                                    result->value[0], &vstr);
+
+             tab_text (tbl, 1,
+                       heading_rows + row_var_start + i * PERCENTILE_ROWS,
+                       TAB_LEFT,
+                       ds_cstr (&vstr)
+                       );
 
+             ds_destroy (&vstr);
+           }
 
-         if ( fctr->indep_var[1])
-           tab_text (tbl, 2, heading_rows - 1, TAB_CENTER | TAT_TITLE,
-                     var_to_string (fctr->indep_var[1]));
 
-         while ( *fs )
-           {
-             const int row = heading_rows + n_stat_rows  *
-                ( ( i  * n_factors  ) +  count );
+         tab_text (tbl, n_cols - n_percentiles - 1,
+                   heading_rows + row_var_start + i * PERCENTILE_ROWS,
+                   TAB_LEFT,
+                   ptile_alg_desc [percentile_algorithm]);
 
 
-             if ( !prev || 0 != compare_values (prev, (*fs)->id[0],
-                                        var_get_width (fctr->indep_var[0])))
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[0],
-                                     (*fs)->id[0], &vstr);
-
-                 if ( count > 0 )
-                   tab_hline (tbl, TAL_1, 1, n_cols - 1, row);
-
-                 tab_text (tbl,
-                           1, row,
-                           TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                           );
-
-                 ds_destroy (&vstr);
-               }
-
-             prev = (*fs)->id[0];
-
-             if (fctr->indep_var[1] && count > 0 )
-               tab_hline (tbl, TAL_1, 2, n_cols - 1, row);
-
-             if ( fctr->indep_var[1])
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[1], (*fs)->id[1], &vstr);
-
-               tab_text (tbl, 2, row,
-                         TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                         );
-
-                 ds_destroy (&vstr);
-               }
-
-             populate_descriptives (tbl, heading_columns - 2,
-                                   row, & (*fs)->m[i]);
-
-             count++ ;
-             fs++;
-           }
-
-       }
-
-      else
-       {
-
-         populate_descriptives (tbl, heading_columns - 2,
-                               i * n_stat_rows * n_factors  + heading_rows,
-                               &totals[i]);
-       }
-    }
-
-  tab_submit (tbl);
-
-}
-
-
-/* Fill in the descriptives data */
-void
-populate_descriptives (struct tab_table *tbl, int col, int row,
-                     const struct metrics *m)
-{
-  const double t = gsl_cdf_tdist_Qinv ((1 - cmd.n_cinterval[0] / 100.0)/2.0,
-                                     m->n -1);
-
-  tab_text (tbl, col,
-           row,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Mean"));
-
-  tab_float (tbl, col + 2,
-            row,
-            TAB_CENTER,
-            m->mean,
-            8,2);
-
-  tab_float (tbl, col + 3,
-            row,
-            TAB_CENTER,
-            m->se_mean,
-            8,3);
-
-
-  tab_text (tbl, col,
-           row + 1,
-           TAB_LEFT | TAT_TITLE | TAT_PRINTF,
-           _ ("%g%% Confidence Interval for Mean"), cmd.n_cinterval[0]);
-
-
-  tab_text (tbl, col + 1,
-           row  + 1,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Lower Bound"));
-
-  tab_float (tbl, col + 2,
-            row + 1,
-            TAB_CENTER,
-            m->mean - t * m->se_mean,
-            8,3);
-
-  tab_text (tbl, col + 1,
-           row + 2,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Upper Bound"));
-
-
-  tab_float (tbl, col + 2,
-            row + 2,
-            TAB_CENTER,
-            m->mean + t * m->se_mean,
-            8,3);
-
-  tab_text (tbl, col,
-           row + 3,
-           TAB_LEFT | TAT_TITLE | TAT_PRINTF,
-           _ ("5%% Trimmed Mean"));
-
-  tab_float (tbl, col + 2,
-            row + 3,
-            TAB_CENTER,
-            m->trimmed_mean,
-            8,2);
-
-  tab_text (tbl, col,
-           row + 4,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Median"));
-
-  {
-    struct percentile *p;
-    double d = 50;
-
-    p = hsh_find (m->ptile_hash, &d);
-
-    assert (p);
-
-
-    tab_float (tbl, col + 2,
-              row + 4,
-              TAB_CENTER,
-              p->v,
-              8, 2);
-  }
-
-
-  tab_text (tbl, col,
-           row + 5,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Variance"));
-
-  tab_float (tbl, col + 2,
-            row + 5,
-            TAB_CENTER,
-            m->var,
-            8,3);
-
-
-  tab_text (tbl, col,
-           row + 6,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Std. Deviation"));
-
-
-  tab_float (tbl, col + 2,
-            row + 6,
-            TAB_CENTER,
-            m->stddev,
-            8,3);
-
-
-  tab_text (tbl, col,
-           row + 7,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Minimum"));
-
-  tab_float (tbl, col + 2,
-            row + 7,
-            TAB_CENTER,
-            m->min,
-            8,3);
-
-  tab_text (tbl, col,
-           row + 8,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Maximum"));
-
-  tab_float (tbl, col + 2,
-            row + 8,
-            TAB_CENTER,
-            m->max,
-            8,3);
-
-
-  tab_text (tbl, col,
-           row + 9,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Range"));
-
-
-  tab_float (tbl, col + 2,
-            row + 9,
-            TAB_CENTER,
-            m->max - m->min,
-            8,3);
-
-  tab_text (tbl, col,
-           row + 10,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Interquartile Range"));
-
-  {
-    struct percentile *p1;
-    struct percentile *p2;
-
-    double d = 75;
-    p1 = hsh_find (m->ptile_hash, &d);
-
-    d = 25;
-    p2 = hsh_find (m->ptile_hash, &d);
-
-    assert (p1);
-    assert (p2);
-
-    tab_float (tbl, col + 2,
-              row + 10,
-              TAB_CENTER,
-              p1->v - p2->v,
-              8, 2);
-  }
-
-
-
-  tab_text (tbl, col,
-           row + 11,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Skewness"));
-
-
-  tab_float (tbl, col + 2,
-            row + 11,
-            TAB_CENTER,
-            m->skewness,
-            8,3);
-
-  /* stderr of skewness */
-  tab_float (tbl, col + 3,
-            row + 11,
-            TAB_CENTER,
-            calc_seskew (m->n),
-            8,3);
-
-
-  tab_text (tbl, col,
-           row + 12,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Kurtosis"));
-
-
-  tab_float (tbl, col + 2,
-            row + 12,
-            TAB_CENTER,
-            m->kurtosis,
-            8,3);
-
-  /* stderr of kurtosis */
-  tab_float (tbl, col + 3,
-            row + 12,
-            TAB_CENTER,
-            calc_sekurt (m->n),
-            8,3);
-
-
-}
-
-
-
-void
-box_plot_variables (const struct factor *fctr,
-                  const struct variable **vars, int n_vars,
-                  const struct variable *id)
-{
+         tab_text (tbl, n_cols - n_percentiles - 1,
+                   heading_rows + row_var_start + 1 + i * PERCENTILE_ROWS,
+                   TAB_LEFT,
+                   _("Tukey's Hinges"));
 
-  int i;
-  struct factor_statistics **fs ;
 
-  if ( ! fctr )
-    {
-      box_plot_group (fctr, vars, n_vars, id);
-      return;
-    }
+         tab_vline (tbl, TAL_1, n_cols - n_percentiles -1, heading_rows, n_rows - 1);
 
-  for ( fs = fctr->fs ; *fs ; ++fs )
-    {
-      struct string str;
-      double y_min = DBL_MAX;
-      double y_max = -DBL_MAX;
-      struct chart *ch = chart_create ();
-      ds_init_empty (&str);
-      factor_to_string (fctr, *fs, 0, &str );
+         tukey_hinges_calculate ((struct tukey_hinges *) result->metrics[v].tukey_hinges,
+                                 hinges);
 
-      chart_write_title (ch, ds_cstr (&str));
-
-      for ( i = 0 ; i < n_vars ; ++i )
-       {
-         y_max = MAX (y_max, (*fs)->m[i].max);
-         y_min = MIN (y_min, (*fs)->m[i].min);
-       }
-
-      boxplot_draw_yscale (ch, y_max, y_min);
-
-      for ( i = 0 ; i < n_vars ; ++i )
-       {
-
-         const double box_width = (ch->data_right - ch->data_left)
-           / (n_vars * 2.0 ) ;
-
-         const double box_centre = ( i * 2 + 1) * box_width
-           + ch->data_left;
-
-         boxplot_draw_boxplot (ch,
-                              box_centre, box_width,
-                              & (*fs)->m[i],
-                              var_to_string (vars[i]));
-
-
-       }
-
-      chart_submit (ch);
-      ds_destroy (&str);
-    }
-}
-
-
-
-/* Do a box plot, grouping all factors into one plot ;
-   each dependent variable has its own plot.
-*/
-void
-box_plot_group (const struct factor *fctr,
-              const struct variable **vars,
-              int n_vars,
-              const struct variable *id UNUSED)
-{
-
-  int i;
-
-  for ( i = 0 ; i < n_vars ; ++i )
-    {
-      struct factor_statistics **fs ;
-      struct chart *ch;
-
-      ch = chart_create ();
-
-      boxplot_draw_yscale (ch, totals[i].max, totals[i].min);
-
-      if ( fctr )
-       {
-         int n_factors = 0;
-         int f=0;
-         for ( fs = fctr->fs ; *fs ; ++fs )
-           ++n_factors;
-
-         chart_write_title (ch, _ ("Boxplot of %s vs. %s"),
-                           var_to_string (vars[i]), var_to_string (fctr->indep_var[0]) );
-
-         for ( fs = fctr->fs ; *fs ; ++fs )
+         for (j = 0; j < n_percentiles; ++j)
            {
-             struct string str;
-             const double box_width = (ch->data_right - ch->data_left)
-               / (n_factors * 2.0 ) ;
-
-             const double box_centre = ( f++ * 2 + 1) * box_width
-               + ch->data_left;
+             double hinge = SYSMIS;
+             tab_float (tbl, n_cols - n_percentiles + j,
+                        heading_rows + row_var_start + i * PERCENTILE_ROWS,
+                        TAB_CENTER,
+                        percentile_calculate (result->metrics[v].ptl[j],
+                                              percentile_algorithm),
+                        8, 2
+                        );
+
+             if ( result->metrics[v].ptl[j]->ptile == 0.5)
+               hinge = hinges[1];
+             else if ( result->metrics[v].ptl[j]->ptile == 0.25)
+               hinge = hinges[0];
+             else if ( result->metrics[v].ptl[j]->ptile == 0.75)
+               hinge = hinges[2];
+
+             if ( hinge != SYSMIS)
+               tab_float (tbl, n_cols - n_percentiles + j,
+                          heading_rows + row_var_start + 1 + i * PERCENTILE_ROWS,
+                          TAB_CENTER,
+                          hinge,
+                          8, 2
+                          );
 
-             ds_init_empty (&str);
-             factor_to_string_concise (fctr, *fs, &str);
-
-             boxplot_draw_boxplot (ch,
-                                  box_centre, box_width,
-                                  & (*fs)->m[i],
-                                  ds_cstr (&str));
-              ds_destroy (&str);
            }
        }
-      else if ( ch )
-       {
-         const double box_width = (ch->data_right - ch->data_left) / 3.0;
-         const double box_centre = (ch->data_right + ch->data_left) / 2.0;
-
-         chart_write_title (ch, _ ("Boxplot"));
-
-         boxplot_draw_boxplot (ch,
-                              box_centre,    box_width,
-                              &totals[i],
-                              var_to_string (vars[i]) );
-
-       }
-
-      chart_submit (ch);
     }
-}
-
-
-/* Plot the normal and detrended normal plots for m
-   Label the plots with factorname */
-void
-np_plot (const struct metrics *m, const char *factorname)
-{
-  int i;
-  double yfirst=0, ylast=0;
-
-  /* Normal Plot */
-  struct chart *np_chart;
-
-  /* Detrended Normal Plot */
-  struct chart *dnp_chart;
-
-  /* The slope and intercept of the ideal normal probability line */
-  const double slope = 1.0 / m->stddev;
-  const double intercept = - m->mean / m->stddev;
-
-  /* Cowardly refuse to plot an empty data set */
-  if ( m->n_data == 0 )
-    return ;
-
-  np_chart = chart_create ();
-  dnp_chart = chart_create ();
-
-  if ( !np_chart || ! dnp_chart )
-    return ;
-
-  chart_write_title (np_chart, _ ("Normal Q-Q Plot of %s"), factorname);
-  chart_write_xlabel (np_chart, _ ("Observed Value"));
-  chart_write_ylabel (np_chart, _ ("Expected Normal"));
-
-
-  chart_write_title (dnp_chart, _ ("Detrended Normal Q-Q Plot of %s"),
-                   factorname);
-  chart_write_xlabel (dnp_chart, _ ("Observed Value"));
-  chart_write_ylabel (dnp_chart, _ ("Dev from Normal"));
-
-  yfirst = gsl_cdf_ugaussian_Pinv (m->wvp[0]->rank / ( m->n + 1));
-  ylast =  gsl_cdf_ugaussian_Pinv (m->wvp[m->n_data-1]->rank / ( m->n + 1));
-
-
-  {
-    /* Need to make sure that both the scatter plot and the ideal fit into the
-       plot */
-    double x_lower = MIN (m->min, (yfirst - intercept) / slope) ;
-    double x_upper = MAX (m->max, (ylast  - intercept) / slope) ;
-    double slack = (x_upper - x_lower)  * 0.05 ;
 
-    chart_write_xscale (np_chart, x_lower - slack, x_upper + slack, 5);
-
-    chart_write_xscale (dnp_chart, m->min, m->max, 5);
-
-  }
-
-  chart_write_yscale (np_chart, yfirst, ylast, 5);
-
-  {
-    /* We have to cache the detrended data, beacause we need to
-       find its limits before we can plot it */
-    double *d_data = xnmalloc (m->n_data, sizeof *d_data);
-    double d_max = -DBL_MAX;
-    double d_min = DBL_MAX;
-    for ( i = 0 ; i < m->n_data; ++i )
-      {
-       const double ns = gsl_cdf_ugaussian_Pinv (m->wvp[i]->rank / ( m->n + 1));
-
-       chart_datum (np_chart, 0, m->wvp[i]->v.f, ns);
-
-       d_data[i] = (m->wvp[i]->v.f - m->mean) / m->stddev  - ns;
-
-       if ( d_data[i] < d_min ) d_min = d_data[i];
-       if ( d_data[i] > d_max ) d_max = d_data[i];
-      }
-    chart_write_yscale (dnp_chart, d_min, d_max, 5);
-
-    for ( i = 0 ; i < m->n_data; ++i )
-      chart_datum (dnp_chart, 0, m->wvp[i]->v.f, d_data[i]);
-
-    free (d_data);
-  }
-
-  chart_line (np_chart, slope, intercept, yfirst, ylast , CHART_DIM_Y);
-  chart_line (dnp_chart, 0, 0, m->min, m->max , CHART_DIM_X);
-
-  chart_submit (np_chart);
-  chart_submit (dnp_chart);
-}
-
-
-
-
-/* Show the percentiles */
-void
-show_percentiles (const struct variable **dependent_var,
-                int n_dep_var,
-                struct factor *fctr)
-{
-  struct tab_table *tbl;
-  int i;
-
-  int n_cols, n_rows;
-  int n_factors;
-
-  struct hsh_table *ptiles ;
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
 
-  int n_heading_columns;
-  const int n_heading_rows = 2;
-  const int n_stat_rows = 2;
+  tab_title (tbl, _("Percentiles"));
 
-  int n_ptiles ;
 
-  if ( fctr )
+  for (i = 0 ; i < n_percentiles; ++i )
     {
-      struct factor_statistics **fs = fctr->fs ;
-      n_heading_columns = 3;
-      n_factors = hsh_count (fctr->fstats);
-
-      ptiles = (*fs)->m[0].ptile_hash;
+      tab_text (tbl, n_cols - n_percentiles + i, 1,
+               TAB_CENTER | TAT_TITLE | TAT_PRINTF,
+               _("%g"),
+               subc_list_double_at (&percentile_list, i)
+               );
 
-      if ( fctr->indep_var[1] )
-       n_heading_columns = 4;
-    }
-  else
-    {
-      n_factors = 1;
-      n_heading_columns = 2;
 
-      ptiles = totals[0].ptile_hash;
     }
 
-  n_ptiles = hsh_count (ptiles);
-
-  n_rows = n_heading_rows + n_dep_var * n_stat_rows * n_factors;
-
-  n_cols = n_heading_columns + n_ptiles ;
-
-  tbl = tab_create (n_cols, n_rows, 0);
-
-  tab_headers (tbl, n_heading_columns + 1, 0, n_heading_rows, 0);
-
-  tab_dim (tbl, tab_natural_dimensions);
-
-  /* Outline the box and have no internal lines*/
-  tab_box (tbl,
-          TAL_2, TAL_2,
-          -1, -1,
-          0, 0,
-          n_cols - 1, n_rows - 1);
-
-  tab_hline (tbl, TAL_2, 0, n_cols - 1, n_heading_rows );
-
-  tab_vline (tbl, TAL_2, n_heading_columns, 0, n_rows - 1);
-
-
-  tab_title (tbl, _ ("Percentiles"));
-
-
-  tab_hline (tbl, TAL_1, n_heading_columns, n_cols - 1, 1 );
-
-
-  tab_box (tbl,
-          -1, -1,
-          -1, TAL_1,
-          0, n_heading_rows,
-          n_heading_columns - 1, n_rows - 1);
-
+  tab_joint_text (tbl,
+                 n_cols - n_percentiles, 0,
+                 n_cols - 1, 0,
+                 TAB_CENTER | TAT_TITLE,
+                 _("Percentiles"));
 
+  /* Vertical lines for the data only */
   tab_box (tbl,
           -1, -1,
           -1, TAL_1,
-          n_heading_columns, n_heading_rows - 1,
+          n_cols - n_percentiles, 1,
           n_cols - 1, n_rows - 1);
 
-  tab_joint_text (tbl, n_heading_columns + 1, 0,
-                n_cols - 1 , 0,
-                TAB_CENTER | TAT_TITLE ,
-                _ ("Percentiles"));
-
-
-  {
-    /* Put in the percentile break points as headings */
-
-    struct percentile **p = (struct percentile **) hsh_sort (ptiles);
-
-    i = 0;
-    while ( (*p)  )
-      {
-       tab_float (tbl, n_heading_columns + i++ , 1,
-                 TAB_CENTER,
-                 (*p)->p, 8, 0);
-
-       p++;
-      }
-
-  }
-
-  for ( i = 0 ; i < n_dep_var ; ++i )
-    {
-      const int n_stat_rows = 2;
-      const int row = n_heading_rows + i * n_stat_rows * n_factors ;
-
-      if ( i > 0 )
-       tab_hline (tbl, TAL_1, 0, n_cols - 1, row );
-
-      tab_text (tbl, 0,
-               i * n_stat_rows * n_factors  + n_heading_rows,
-               TAB_LEFT | TAT_TITLE,
-               var_to_string (dependent_var[i])
-               );
-
-      if ( fctr  )
-       {
-         const union value *prev  = NULL ;
-         struct factor_statistics **fs = fctr->fs;
-         int count = 0;
-
-         tab_text (tbl, 1, n_heading_rows - 1,
-                   TAB_CENTER | TAT_TITLE,
-                   var_to_string (fctr->indep_var[0]));
-
-
-         if ( fctr->indep_var[1])
-           tab_text (tbl, 2, n_heading_rows - 1, TAB_CENTER | TAT_TITLE,
-                     var_to_string (fctr->indep_var[1]));
-
-         while ( *fs )
-           {
-             const int row = n_heading_rows + n_stat_rows  *
-                ( ( i  * n_factors  ) +  count );
-
-
-             if ( !prev || 0 != compare_values (prev, (*fs)->id[0],
-                                        var_get_width (fctr->indep_var[0])))
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[0],
-                                     (*fs)->id[0], &vstr);
-
-
-                 if ( count > 0 )
-                   tab_hline (tbl, TAL_1, 1, n_cols - 1, row);
-
-                 tab_text (tbl,
-                           1, row,
-                           TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                           );
-
-                 ds_destroy (&vstr);
-               }
-
-             prev = (*fs)->id[0];
-
-             if (fctr->indep_var[1] && count > 0 )
-               tab_hline (tbl, TAL_1, 2, n_cols - 1, row);
-
-             if ( fctr->indep_var[1])
-               {
-                 struct string vstr;
-                 ds_init_empty (&vstr);
-                 var_append_value_name (fctr->indep_var[1], (*fs)->id[1], &vstr);
-
-               tab_text (tbl, 2, row,
-                         TAB_LEFT | TAT_TITLE,
-                           ds_cstr (&vstr)
-                         );
-
-                 ds_destroy (&vstr);
-               }
-
-
-             populate_percentiles (tbl, n_heading_columns - 1,
-                                  row, & (*fs)->m[i]);
-
-
-             count++ ;
-             fs++;
-           }
-
-
-       }
-      else
-       {
-         populate_percentiles (tbl, n_heading_columns - 1,
-                              i * n_stat_rows * n_factors  + n_heading_rows,
-                              &totals[i]);
-       }
-
-
-    }
+  tab_hline (tbl, TAL_1, n_cols - n_percentiles, n_cols - 1, 1);
 
 
   tab_submit (tbl);
-
-
 }
 
 
-
-
-void
-populate_percentiles (struct tab_table *tbl, int col, int row,
-                    const struct metrics *m)
+static void
+factor_to_string_concise (const struct xfactor *fctr,
+                         const struct factor_result *result,
+                         struct string *str
+                         )
 {
-  int i;
-
-  struct percentile **p = (struct percentile **) hsh_sort (m->ptile_hash);
-
-  tab_text (tbl,
-           col, row + 1,
-           TAB_LEFT | TAT_TITLE,
-           _ ("Tukey\'s Hinges")
-           );
-
-  tab_text (tbl,
-           col, row,
-           TAB_LEFT | TAT_TITLE,
-           ptile_alg_desc[m->ptile_alg]
-           );
-
-
-  i = 0;
-  while ( (*p)  )
+  if (fctr->indep_var[0])
     {
-      tab_float (tbl, col + i + 1 , row,
-               TAB_CENTER,
-                (*p)->v, 8, 2);
-      if ( (*p)->p == 25 )
-       tab_float (tbl, col + i + 1 , row + 1,
-                 TAB_CENTER,
-                 m->hinge[0], 8, 2);
-
-      if ( (*p)->p == 50 )
-       tab_float (tbl, col + i + 1 , row + 1,
-                 TAB_CENTER,
-                 m->hinge[1], 8, 2);
-
-      if ( (*p)->p == 75 )
-       tab_float (tbl, col + i + 1 , row + 1,
-                 TAB_CENTER,
-                 m->hinge[2], 8, 2);
+      var_append_value_name (fctr->indep_var[0], result->value[0], str);
 
+      if ( fctr->indep_var[1] )
+       {
+         ds_put_cstr (str, ",");
 
-      i++;
+         var_append_value_name (fctr->indep_var[1], result->value[1], str);
 
-      p++;
+         ds_put_cstr (str, ")");
+       }
     }
-
 }
 
+
 static void
-factor_to_string (const struct factor *fctr,
-                 const struct factor_statistics *fs,
-                 const struct variable *var,
+factor_to_string (const struct xfactor *fctr,
+                 const struct factor_result *result,
                  struct string *str
                  )
 {
-  if (var)
-    ds_put_format (str, "%s (",var_to_string (var) );
-
-
-  ds_put_format (str,  "%s = ",
-                var_to_string (fctr->indep_var[0]));
+  if (fctr->indep_var[0])
+    {
+      ds_put_format (str, "(%s = ", var_get_name (fctr->indep_var[0]));
 
-  var_append_value_name (fctr->indep_var[0], fs->id[0], str);
+      var_append_value_name (fctr->indep_var[0], result->value[0], str);
 
-  if ( fctr->indep_var[1] )
-    {
-      ds_put_format (str, "; %s = )",
-                    var_to_string (fctr->indep_var[1]));
+      if ( fctr->indep_var[1] )
+       {
+         ds_put_cstr (str, ",");
+         ds_put_format (str, "%s = ", var_get_name (fctr->indep_var[1]));
 
-      var_append_value_name (fctr->indep_var[1], fs->id[1], str);
-    }
-  else
-    {
-      if ( var )
-       ds_put_cstr (str, ")");
+         var_append_value_name (fctr->indep_var[1], result->value[1], str);
+       }
+      ds_put_cstr (str, ")");
     }
 }
 
 
-static void
-factor_to_string_concise (const struct factor *fctr,
-                         const struct factor_statistics *fs,
-                         struct string *str
-                         )
-
-{
-  var_append_value_name (fctr->indep_var[0], fs->id[0], str);
-
-  if ( fctr->indep_var[1] )
-    {
-      ds_put_cstr (str, ",");
-
-      var_append_value_name (fctr->indep_var[1],fs->id[1], str);
 
-      ds_put_cstr (str, ")");
-    }
-}
 
 /*
   Local Variables:
index f2054380b8807fff50107d3a5b8902a484a6e742..afad84ee4bcdc6f0a93c83a6f71c71494cb03895 100644 (file)
@@ -30,16 +30,15 @@ compare_freq ( const void *_f1, const void *_f2, const void *_var)
   const struct freq *f2 = _f2;
   const struct variable *var = _var;
 
-  return  compare_values (f1->value, f2->value, var_get_width (var) );
+  return  compare_values (f1->value, f2->value, var );
 }
 
 unsigned int
-hash_freq (const void *_f, const void *_var)
+hash_freq (const void *_f, const void *var)
 {
   const struct freq *f = _f;
-  const struct variable *var  = _var;
 
-  return hash_value (f->value, var_get_width (var));
+  return hash_value (f->value, var);
 }
 
 /* Free function to be used on FR whose value parameter has been copied */
index e7509052b05b2aa93dfadbe3eb72a6cc97383e35..94b2bcf9e6edd2303632342d6fa8e80304c62018 100644 (file)
@@ -268,7 +268,7 @@ static hsh_compare_func compare_freq_numeric_d, compare_freq_alpha_d;
 static void do_piechart(const struct variable *var,
                        const struct freq_tab *frq_tab);
 
-gsl_histogram *
+struct histogram *
 freq_tab_to_hist(const struct freq_tab *ft, const struct variable *var);
 
 
@@ -606,31 +606,26 @@ postcalc (void)
       if ( chart == GFT_HIST)
        {
          double d[frq_n_stats];
-         struct normal_curve norm;
-         gsl_histogram *hist ;
-
-
-         norm.N = vf->tab.valid_cases;
+         struct histogram *hist ;
 
          calc_stats (v, d);
-         norm.mean = d[frq_mean];
-         norm.stddev = d[frq_stddev];
 
-         hist = freq_tab_to_hist(ft,v);
+         hist = freq_tab_to_hist (ft,v);
 
-         histogram_plot(hist, var_to_string(v), &norm, normal);
+         histogram_plot_n (hist, var_to_string(v),
+                         vf->tab.valid_cases,
+                         d[frq_mean],
+                         d[frq_stddev],
+                         normal);
 
-         gsl_histogram_free(hist);
+         statistic_destroy ((struct statistic *)hist);
        }
 
-
       if ( chart == GFT_PIE)
        {
          do_piechart(v_variables[i], ft);
        }
 
-
-
       cleanup_freq_tab (v);
 
     }
@@ -1437,14 +1432,14 @@ dump_statistics (const struct variable *v, int show_varname)
 
 
 /* Create a gsl_histogram from a freq_tab */
-gsl_histogram *
-freq_tab_to_hist(const struct freq_tab *ft, const struct variable *var)
+struct histogram *
+freq_tab_to_hist (const struct freq_tab *ft, const struct variable *var)
 {
   int i;
   double x_min = DBL_MAX;
   double x_max = -DBL_MAX;
 
-  gsl_histogram *hist;
+  struct statistic *hist;
   const double bins = 11;
 
   struct hsh_iterator hi;
@@ -1461,15 +1456,15 @@ freq_tab_to_hist(const struct freq_tab *ft, const struct variable *var)
       if ( frq->value[0].f > x_max ) x_max = frq->value[0].f ;
     }
 
-  hist = histogram_create(bins, x_min, x_max);
+  hist = histogram_create (bins, x_min, x_max);
 
   for( i = 0 ; i < ft->n_valid ; ++i )
     {
       frq = &ft->valid[i];
-      gsl_histogram_accumulate(hist, frq->value[0].f, frq->count);
+      histogram_add ((struct histogram *)hist, frq->value[0].f, frq->count);
     }
 
-  return hist;
+  return (struct histogram *)hist;
 }
 
 
@@ -1499,6 +1494,7 @@ freq_tab_to_slice_array(const struct freq_tab *frq_tab,
     {
       const struct freq *frq = &frq_tab->valid[i];
 
+      ds_init_empty (&slices[i].label);
       var_append_value_name (var, frq->value, &slices[i].label);
       slices[i].magnetude = frq->count;
     }
index f16eff76117c4e52da57f75baff887271fd32fc0..d6b4952c289532b0c0974ef0183b5b93585a4af3 100644 (file)
@@ -37,8 +37,9 @@
 #include <language/data-io/file-handle.h>
 #include <language/lexer/lexer.h>
 #include <libpspp/compiler.h>
+#include <libpspp/hash.h>
 #include <libpspp/message.h>
-#include <math/design-matrix.h>
+#include <math/covariance-matrix.h>
 #include <math/coefficient.h>
 #include <math/linreg.h>
 #include <math/moments.h>
@@ -47,8 +48,6 @@
 #include "xalloc.h"
 #include "gettext.h"
 
-#define GLM_LARGE_DATA 1000
-
 /* (headers) */
 
 /* (specification)
@@ -67,6 +66,9 @@ static struct cmd_glm cmd;
 struct moments_var
 {
   struct moments1 *m;
+  double *weight;
+  double *mean;
+  double *variance;
   const struct variable *v;
 };
 
@@ -90,22 +92,18 @@ static int pspp_glm_rc = CMD_SUCCESS;
 int cmd_glm (struct lexer *lexer, struct dataset *ds);
 #endif
 
-static bool run_glm (struct casereader*,
+static bool run_glm (struct casereader *,
                     struct cmd_glm *,
-                    const struct dataset *,
-                    pspp_linreg_cache *);
+                    const struct dataset *);
 
 int
 cmd_glm (struct lexer *lexer, struct dataset *ds)
 {
   struct casegrouper *grouper;
   struct casereader *group;
-  pspp_linreg_cache *model = NULL;
 
   bool ok;
 
-  model = xmalloc (sizeof *model);
-
   if (!parse_glm (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
@@ -113,12 +111,11 @@ cmd_glm (struct lexer *lexer, struct dataset *ds)
   grouper = casegrouper_create_splits (proc_open (ds), dataset_dict (ds));
   while (casegrouper_get_next_group (grouper, &group))
     {
-      run_glm (group, &cmd, ds, model);
+      run_glm (group, &cmd, ds);
     }
   ok = casegrouper_destroy (grouper);
   ok = proc_commit (ds) && ok;
 
-  free (model);
   free (v_dependent);
   return ok ? CMD_SUCCESS : CMD_FAILURE;
 }
@@ -126,8 +123,7 @@ cmd_glm (struct lexer *lexer, struct dataset *ds)
 /* Parser for the dependent sub command */
 static int
 glm_custom_dependent (struct lexer *lexer, struct dataset *ds,
-                     struct cmd_glm *cmd UNUSED,
-                     void *aux UNUSED)
+                     struct cmd_glm *cmd UNUSED, void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
 
@@ -145,110 +141,55 @@ glm_custom_dependent (struct lexer *lexer, struct dataset *ds,
   assert (n_dependent);
   if (n_dependent > 1)
     msg (SE, _("Multivariate GLM not yet supported"));
-  n_dependent = 1; /* Drop this line after adding support for multivariate GLM. */
+  n_dependent = 1;             /* Drop this line after adding support for multivariate GLM. */
 
   return 1;
 }
 
-static void
-coeff_init (pspp_linreg_cache * c, struct design_matrix *dm)
-{
-  c->coeff = xnmalloc (dm->m->size2 + 1, sizeof (*c->coeff));
-  c->coeff[0] = xmalloc (sizeof (*(c->coeff[0])));     /* The first coefficient is the intercept. */
-  c->coeff[0]->v_info = NULL;  /* Intercept has no associated variable. */
-  pspp_coeff_init (c->coeff + 1, dm);
-}
-
 /*
-  Put the moments in the linreg cache.
+  COV is the covariance matrix for variables included in the
+  model. That means the dependent variable is in there, too.
  */
 static void
-compute_moments (pspp_linreg_cache * c, struct moments_var *mom,
-                struct design_matrix *dm, size_t n)
+coeff_init (pspp_linreg_cache * c, const struct design_matrix *cov)
 {
-  size_t i;
-  size_t j;
-  double weight;
-  double mean;
-  double variance;
-  double skewness;
-  double kurtosis;
-  /*
-     Scan the variable names in the columns of the design matrix.
-     When we find the variable we need, insert its mean in the cache.
-   */
-  for (i = 0; i < dm->m->size2; i++)
-    {
-      for (j = 0; j < n; j++)
-       {
-         if (design_matrix_col_to_var (dm, i) == (mom + j)->v)
-           {
-             moments1_calculate ((mom + j)->m, &weight, &mean, &variance,
-                                 &skewness, &kurtosis);
-             gsl_vector_set (c->indep_means, i, mean);
-             gsl_vector_set (c->indep_std, i, sqrt (variance));
-           }
-       }
-    }
+  c->coeff = xnmalloc (cov->m->size2, sizeof (*c->coeff));
+  c->n_coeffs = cov->m->size2 - 1;
+  pspp_coeff_init (c->coeff, cov);
 }
-/* Encode categorical variables.
-   Returns number of valid cases. */
-static int
-prepare_categories (struct casereader *input,
-                    const struct variable **vars, size_t n_vars,
-                    struct moments_var *mom)
-{
-  int n_data;
-  struct ccase c;
-  size_t i;
 
-  for (i = 0; i < n_vars; i++)
-    if (var_is_alpha (vars[i]))
-      cat_stored_values_create (vars[i]);
 
-  n_data = 0;
-  for (; casereader_read (input, &c); case_destroy (&c))
-    {
-      /*
-       The second condition ensures the program will run even if
-       there is only one variable to act as both explanatory and
-       response.
-       */
-      for (i = 0; i < n_vars; i++)
-        {
-          const union value *val = case_data (&c, vars[i]);
-          if (var_is_alpha (vars[i]))
-            cat_value_update (vars[i], val);
-          else
-            moments1_add (mom[i].m, val->f, 1.0);
-        }
-      n_data++;
-   }
-  casereader_destroy (input);
-
-  return n_data;
+static pspp_linreg_cache *
+fit_model (const struct covariance_matrix *cov,
+          const struct variable *dep_var, 
+          const struct variable ** indep_vars, 
+          size_t n_data, size_t n_indep)
+{
+  pspp_linreg_cache *result = NULL;
+  result = pspp_linreg_cache_alloc (dep_var, indep_vars, n_data, n_indep);
+  coeff_init (result, covariance_to_design (cov));
+  pspp_linreg_with_cov (cov, result);  
+  
+  return result;
 }
 
 static bool
 run_glm (struct casereader *input,
         struct cmd_glm *cmd,
-        const struct dataset *ds,
-        pspp_linreg_cache *model)
+        const struct dataset *ds)
 {
-  size_t i;
+  casenumber row;
+  const struct variable **indep_vars;
+  const struct variable **all_vars;
   int n_indep = 0;
+  pspp_linreg_cache *model = NULL; 
+  pspp_linreg_opts lopts;
   struct ccase c;
-  const struct variable **indep_vars;
-  struct design_matrix *X;
-  struct moments_var *mom;
-  gsl_vector *Y;
-  struct casereader *reader;
-  casenumber row;
+  size_t i;
+  size_t n_all_vars;
   size_t n_data;               /* Number of valid cases. */
-
-  pspp_linreg_opts lopts;
-
-  assert (model != NULL);
+  struct casereader *reader;
+  struct covariance_matrix *cov;
 
   if (!casereader_peek (input, 0, &c))
     {
@@ -264,82 +205,56 @@ run_glm (struct casereader *input,
                     1u << DC_SYSTEM);
     }
 
-  for (i = 0; i < n_dependent; i++)
-    {
-      if (!var_is_numeric (v_dependent[i]))
-       {
-         msg (SE, _("Dependent variable must be numeric."));
-         return false;
-       }
-    }
-
-  mom = xnmalloc (n_dependent, sizeof (*mom));
-  mom->m = moments1_create (MOMENT_VARIANCE);
-  mom->v = v_dependent[0];
   lopts.get_depvar_mean_std = 1;
 
   lopts.get_indep_mean_std = xnmalloc (n_dependent, sizeof (int));
   indep_vars = xnmalloc (cmd->n_by, sizeof *indep_vars);
+  n_all_vars = cmd->n_by + n_dependent;
+  all_vars = xnmalloc (n_all_vars, sizeof *all_vars);
 
+  for (i = 0; i < n_dependent; i++)
+    {
+      all_vars[i] = v_dependent[i];
+    }
   for (i = 0; i < cmd->n_by; i++)
     {
       indep_vars[i] = cmd->v_by[i];
+      all_vars[i + n_dependent] = cmd->v_by[i];
     }
   n_indep = cmd->n_by;
-  
+
   reader = casereader_clone (input);
   reader = casereader_create_filter_missing (reader, indep_vars, n_indep,
-                                            MV_ANY, NULL);
+                                            MV_ANY, NULL, NULL);
   reader = casereader_create_filter_missing (reader, v_dependent, 1,
-                                            MV_ANY, NULL);
-  n_data = prepare_categories (casereader_clone (reader),
-                              indep_vars, n_indep, mom);
+                                            MV_ANY, NULL, NULL);
 
-  if ((n_data > 0) && (n_indep > 0))
+  if (n_indep > 0)
     {
-      Y = gsl_vector_alloc (n_data);
-      X =
-       design_matrix_create (n_indep,
-                             (const struct variable **) indep_vars,
-                             n_data);
-      for (i = 0; i < X->m->size2; i++)
-       {
-         lopts.get_indep_mean_std[i] = 1;
-       }
-      model = pspp_linreg_cache_alloc (X->m->size1, X->m->size2);
-      model->indep_means = gsl_vector_alloc (X->m->size2);
-      model->indep_std = gsl_vector_alloc (X->m->size2);
-      model->depvar = v_dependent[0];
+      for (i = 0; i < n_all_vars; i++)
+       if (var_is_alpha (all_vars[i]))
+         cat_stored_values_create (all_vars[i]);
+      
+      cov = covariance_matrix_init (n_all_vars, all_vars, ONE_PASS, PAIRWISE, MV_ANY);
       reader = casereader_create_counter (reader, &row, -1);
       for (; casereader_read (reader, &c); case_destroy (&c))
        {
-         for (i = 0; i < n_indep; ++i)
-           {
-             const struct variable *v = indep_vars[i];
-             const union value *val = case_data (&c, v);
-             if (var_is_alpha (v))
-               design_matrix_set_categorical (X, row, v, val);
-             else
-               design_matrix_set_numeric (X, row, v, val);
-           }
-          gsl_vector_set (Y, row, case_num (&c, model->depvar));
+         /* 
+            Accumulate the covariance matrix.
+         */
+         covariance_matrix_accumulate (cov, &c);
+         n_data++;
        }
+      covariance_matrix_compute (cov);
+
+      for (i = 0; i < n_dependent; i++)
+       {
+         model = fit_model (cov, v_dependent[i], indep_vars, n_data, n_indep);
+         pspp_linreg_cache_free (model);
+       }
+
       casereader_destroy (reader);
-      /*
-       Now that we know the number of coefficients, allocate space
-       and store pointers to the variables that correspond to the
-       coefficients.
-      */
-      coeff_init (model, X);
-      
-      /*
-       Find the least-squares estimates and other statistics.
-      */
-      pspp_linreg ((const gsl_vector *) Y, X->m, &lopts, model);
-      compute_moments (model, mom, X, n_dependent);
-      
-      gsl_vector_free (Y);
-      design_matrix_destroy (X);
+      covariance_matrix_destroy (cov);
     }
   else
     {
index c9c2c9da1a9d1a215b0152612fc46eb1240b34e7..c752d503bbbde6af9eeb0bd3036656e6de2c6019 100644 (file)
@@ -52,7 +52,7 @@ npar_summary_calc_descriptives (struct descriptives *desc,
       pass = casereader_clone (input);
       pass = casereader_create_filter_missing (pass,
                                                &v, 1,
-                                               filter, NULL);
+                                               filter, NULL, NULL);
       pass = casereader_create_filter_weight (pass, dict, NULL, NULL);
       while (casereader_read(pass, &c))
        {
index 37939fe9172b496eaeca10210c7c94fb85969c37..6aed01cf2c3509ff44e25d1a6052f9fc85924de7 100644 (file)
@@ -18,6 +18,7 @@
 #define npar_h 1
 
 #include <stddef.h>
+#include <stdbool.h>
 #include <data/missing-values.h>
 
 #include <stddef.h>
@@ -36,8 +37,9 @@ struct npar_test
   void (*execute) (const struct dataset *,
                   struct casereader *,
                    enum mv_class exclude,
-                  const struct npar_test *
-                  );
+                  const struct npar_test *,
+                  bool,
+                  double);
 
   void (*insert_variables) (const struct npar_test *,
                            struct const_hsh_table *);
index 688ce2379bc103eaed0ce6f1b230a951053f0743..34e03677dc9bc145568a910c05a1ea83a063d4e5 100644 (file)
@@ -1,5 +1,5 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+/* PSPP - a program for statistical analysis. -*-c-*-
+   Copyright (C) 2006, 2008 Free Software Foundation, Inc.
 
    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
@@ -30,6 +30,7 @@
 #include <language/lexer/variable-parser.h>
 #include <language/stats/binomial.h>
 #include <language/stats/chisquare.h>
+#include <language/stats/wilcoxon.h>
 #include <libpspp/hash.h>
 #include <libpspp/pool.h>
 #include <libpspp/taint.h>
@@ -53,7 +54,8 @@
    +friedman=varlist;
    +kendall=varlist;
    missing=miss:!analysis/listwise,
-           incl:include/!exclude;
+   incl:include/!exclude;
+   method=custom;
    +statistics[st_]=descriptives,quartiles,all.
 */
 /* (declarations) */
@@ -70,17 +72,25 @@ struct npar_specs
   size_t n_tests;
 
   const struct variable ** vv; /* Compendium of all variables
-                                      (those mentioned on ANY subcommand */
+                                 (those mentioned on ANY subcommand */
   int n_vars; /* Number of variables in vv */
 
   enum mv_class filter;    /* Missing values to filter. */
 
   bool descriptives;       /* Descriptive statistics should be calculated */
   bool quartiles;          /* Quartiles should be calculated */
+
+  bool exact;  /* Whether exact calculations have been requested */
+  double timer;   /* Maximum time (in minutes) to wait for exact calculations */
 };
 
-void one_sample_insert_variables (const struct npar_test *test,
-                                 struct const_hsh_table *variables);
+static void one_sample_insert_variables (const struct npar_test *test,
+                                        struct const_hsh_table *variables);
+
+static void two_sample_insert_variables (const struct npar_test *test,
+                                        struct const_hsh_table *variables);
+
+
 
 static void
 npar_execute(struct casereader *input,
@@ -98,7 +108,7 @@ npar_execute(struct casereader *input,
          msg (SW, _("NPAR subcommand not currently implemented."));
          continue;
        }
-      test->execute (ds, casereader_clone (input), specs->filter, test);
+      test->execute (ds, casereader_clone (input), specs->filter, test, specs->exact, specs->timer);
     }
 
   if ( specs->descriptives )
@@ -126,7 +136,7 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
   int i;
-  struct npar_specs npar_specs = {0, 0, 0, 0, 0, 0, 0, 0};
+  struct npar_specs npar_specs = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
   struct const_hsh_table *var_hash;
   struct casegrouper *grouper;
   struct casereader *input, *group;
@@ -134,8 +144,8 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
   npar_specs.pool = pool_create ();
 
   var_hash = const_hsh_create_pool (npar_specs.pool, 0,
-                             compare_vars_by_name, hash_var_by_name,
-                             NULL, NULL);
+                                   compare_vars_by_name, hash_var_by_name,
+                                   NULL, NULL);
 
   if ( ! parse_npar_tests (lexer, ds, &cmd, &npar_specs) )
     {
@@ -183,10 +193,14 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
 
   input = proc_open (ds);
   if ( cmd.miss == NPAR_LISTWISE )
-    input = casereader_create_filter_missing (input,
-                                              npar_specs.vv,
-                                              npar_specs.n_vars,
-                                              npar_specs.filter, NULL);
+    {
+      input = casereader_create_filter_missing (input,
+                                               npar_specs.vv,
+                                               npar_specs.n_vars,
+                                               npar_specs.filter,
+                                               NULL, NULL);
+    }
+
 
   grouper = casegrouper_create_splits (input, dataset_dict (ds));
   while (casegrouper_get_next_group (grouper, &group))
@@ -202,7 +216,8 @@ cmd_npar_tests (struct lexer *lexer, struct dataset *ds)
 }
 
 int
-npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests *cmd UNUSED, void *aux )
+npar_custom_chisquare (struct lexer *lexer, struct dataset *ds,
+                      struct cmd_npar_tests *cmd UNUSED, void *aux )
 {
   struct npar_specs *specs = aux;
 
@@ -213,8 +228,8 @@ npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_t
   ((struct npar_test *)tp)->insert_variables = one_sample_insert_variables;
 
   if (!parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds),
-                            &tp->vars, &tp->n_vars,
-                            PV_NO_SCRATCH | PV_NO_DUPLICATE))
+                                  &tp->vars, &tp->n_vars,
+                                  PV_NO_SCRATCH | PV_NO_DUPLICATE))
     {
       return 2;
     }
@@ -307,7 +322,8 @@ npar_custom_chisquare(struct lexer *lexer, struct dataset *ds, struct cmd_npar_t
 
 
 int
-npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests *cmd UNUSED, void *aux)
+npar_custom_binomial (struct lexer *lexer, struct dataset *ds,
+                     struct cmd_npar_tests *cmd UNUSED, void *aux)
 {
   struct npar_specs *specs = aux;
   struct binomial_test *btp = pool_alloc(specs->pool, sizeof(*btp));
@@ -333,8 +349,8 @@ npar_custom_binomial(struct lexer *lexer, struct dataset *ds, struct cmd_npar_te
   if ( lex_match (lexer, '=') )
     {
       if (parse_variables_const_pool (lexer, specs->pool, dataset_dict (ds),
-                               &tp->vars, &tp->n_vars,
-                               PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
+                                     &tp->vars, &tp->n_vars,
+                                     PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
        {
          if ( lex_match (lexer, '('))
            {
@@ -398,18 +414,20 @@ parse_two_sample_related_test (struct lexer *lexer,
   const struct variable **vlist2;
   size_t n_vlist2;
 
+  ((struct npar_test *)test_parameters)->insert_variables = two_sample_insert_variables;
+
   if (!parse_variables_const_pool (lexer, pool,
-                            dict,
-                            &vlist1, &n_vlist1,
-                            PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
+                                  dict,
+                                  &vlist1, &n_vlist1,
+                                  PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
     return false;
 
   if ( lex_match(lexer, T_WITH))
     {
       with = true;
       if ( !parse_variables_const_pool (lexer, pool, dict,
-                                 &vlist2, &n_vlist2,
-                                 PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
+                                       &vlist2, &n_vlist2,
+                                       PV_NUMERIC | PV_NO_SCRATCH | PV_NO_DUPLICATE) )
        return false;
 
       paired = (lex_match (lexer, '(') &&
@@ -449,8 +467,8 @@ parse_two_sample_related_test (struct lexer *lexer,
          assert (n_vlist1 == n_vlist2);
          for ( i = 0 ; i < n_vlist1; ++i )
            {
-             test_parameters->pairs[n][0] = vlist1[i];
-             test_parameters->pairs[n][1] = vlist2[i];
+             test_parameters->pairs[n][1] = vlist1[i];
+             test_parameters->pairs[n][0] = vlist2[i];
              n++;
            }
        }
@@ -461,8 +479,8 @@ parse_two_sample_related_test (struct lexer *lexer,
            {
              for ( j = 0 ; j < n_vlist2; ++j )
                {
-                 test_parameters->pairs[n][0] = vlist1[i];
-                 test_parameters->pairs[n][1] = vlist2[j];
+                 test_parameters->pairs[n][1] = vlist1[i];
+                 test_parameters->pairs[n][0] = vlist2[j];
                  n++;
                }
            }
@@ -476,8 +494,8 @@ parse_two_sample_related_test (struct lexer *lexer,
          for ( j = i + 1 ; j < n_vlist1; ++j )
            {
              assert ( n < test_parameters->n_pairs);
-             test_parameters->pairs[n][0] = vlist1[i];
-             test_parameters->pairs[n][1] = vlist1[j];
+             test_parameters->pairs[n][1] = vlist1[i];
+             test_parameters->pairs[n][0] = vlist1[j];
              n++;
            }
        }
@@ -495,8 +513,8 @@ npar_custom_wilcoxon (struct lexer *lexer,
 {
   struct npar_specs *specs = aux;
 
-  struct two_sample_test *tp = pool_alloc(specs->pool, sizeof(*tp));
-  ((struct npar_test *)tp)->execute = NULL;
+  struct two_sample_test *tp = pool_alloc (specs->pool, sizeof(*tp));
+  ((struct npar_test *)tp)->execute = wilcoxon_execute;
 
   if (!parse_two_sample_related_test (lexer, dataset_dict (ds), cmd,
                                      tp, specs->pool) )
@@ -559,9 +577,9 @@ npar_custom_sign (struct lexer *lexer, struct dataset *ds,
 }
 
 /* Insert the variables for TEST into VAR_HASH */
-void
+static void
 one_sample_insert_variables (const struct npar_test *test,
-                           struct const_hsh_table *var_hash)
+                            struct const_hsh_table *var_hash)
 {
   int i;
   struct one_sample_test *ost = (struct one_sample_test *) test;
@@ -570,3 +588,50 @@ one_sample_insert_variables (const struct npar_test *test,
     const_hsh_insert (var_hash, ost->vars[i]);
 }
 
+static void
+two_sample_insert_variables (const struct npar_test *test,
+                            struct const_hsh_table *var_hash)
+{
+  int i;
+
+  const struct two_sample_test *tst = (const struct two_sample_test *) test;
+
+  for ( i = 0 ; i < tst->n_pairs ; ++i )
+    {
+      variable_pair *pair = &tst->pairs[i];
+
+      const_hsh_insert (var_hash, (*pair)[0]);
+      const_hsh_insert (var_hash, (*pair)[1]);
+    }
+
+}
+
+
+static int
+npar_custom_method (struct lexer *lexer, struct dataset *ds UNUSED,
+                    struct cmd_npar_tests *test UNUSED, void *aux)
+{
+  struct npar_specs *specs = aux;
+
+  if ( lex_match_id (lexer, "EXACT") )
+    {
+      specs->exact = true;
+      specs->timer = 0.0;
+      if (lex_match_id (lexer, "TIMER"))
+       {
+         specs->timer = 5.0;
+
+         if ( lex_match (lexer, '('))
+           {
+             if ( lex_force_num (lexer) )
+               {
+                 specs->timer = lex_number (lexer);
+                 lex_get (lexer);
+               }
+             lex_force_match (lexer, ')');
+           }
+       }
+    }
+
+  return 1;
+}
index 7da992274ea999c8ad488a877264e6dba0aa5327..87a7500465ebd98c8c3aed3bc8db752879caa2b3 100644 (file)
@@ -55,7 +55,7 @@
    "ONEWAY" (oneway_):
    *^variables=custom;
    missing=miss:!analysis/listwise,
-           incl:include/!exclude;
+   incl:include/!exclude;
    +contrast= double list;
    +statistics[st_]=descriptives,homogeneity.
 */
@@ -76,7 +76,7 @@ static const struct variable **vars;
 
 /* A  hash table containing all the distinct values of the independent
    variables */
-static struct hsh_table *global_group_hash ;
+static struct hsh_table *global_group_hash;
 
 /* The number of distinct values of the independent variable, when all
    missing values are disregarded */
@@ -88,19 +88,19 @@ static void run_oneway (struct cmd_oneway *, struct casereader *,
 
 
 /* Routines to show the output tables */
-static void show_anova_table(void);
-static void show_descriptives(void);
-static void show_homogeneity(void);
+static void show_anova_table (void);
+static void show_descriptives (void);
+static void show_homogeneity (void);
 
-static void show_contrast_coeffs(short *);
-static void show_contrast_tests(short *);
+static void show_contrast_coeffs (short *);
+static void show_contrast_tests (short *);
 
 
 enum stat_table_t {STAT_DESC = 1, STAT_HOMO = 2};
 
-static enum stat_table_t stat_tables ;
+static enum stat_table_t stat_tables;
 
-void output_oneway(void);
+void output_oneway (void);
 
 
 int
@@ -111,25 +111,26 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
   int i;
   bool ok;
 
-  if ( !parse_oneway (lexer, ds, &cmd, NULL) )
+  if ( !parse_oneway (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   /* What statistics were requested */
-  if ( cmd.sbc_statistics )
+  if ( cmd.sbc_statistics)
     {
 
-      for (i = 0 ; i < ONEWAY_ST_count ; ++i )
+      for (i = 0; i < ONEWAY_ST_count; ++i)
        {
-         if  ( ! cmd.a_statistics[i]  ) continue;
-
-         switch (i) {
-         case ONEWAY_ST_DESCRIPTIVES:
-           stat_tables |= STAT_DESC;
-           break;
-         case ONEWAY_ST_HOMOGENEITY:
-           stat_tables |= STAT_HOMO;
-           break;
-         }
+         if (! cmd.a_statistics[i]) continue;
+
+         switch (i) 
+           {
+           case ONEWAY_ST_DESCRIPTIVES:
+             stat_tables |= STAT_DESC;
+             break;
+           case ONEWAY_ST_HOMOGENEITY:
+             stat_tables |= STAT_HOMO;
+             break;
+           }
        }
     }
 
@@ -148,91 +149,88 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds)
 
 
 void
-output_oneway(void)
+output_oneway (void)
 {
   size_t i;
-  short *bad_contrast ;
+  short *bad_contrast;
 
   bad_contrast = xnmalloc (cmd.sbc_contrast, sizeof *bad_contrast);
 
   /* Check the sanity of the given contrast values */
-  for (i = 0 ; i < cmd.sbc_contrast ; ++i )
+  for (i = 0; i < cmd.sbc_contrast; ++i)
     {
       int j;
       double sum = 0;
 
       bad_contrast[i] = 0;
-      if ( subc_list_double_count(&cmd.dl_contrast[i]) !=
-          ostensible_number_of_groups )
+      if (subc_list_double_count (&cmd.dl_contrast[i]) !=
+         ostensible_number_of_groups)
        {
-         msg(SW,
-             _("Number of contrast coefficients must equal the number of groups"));
+         msg (SW,
+              _("Number of contrast coefficients must equal the number of groups"));
          bad_contrast[i] = 1;
          continue;
        }
 
-      for (j=0; j < ostensible_number_of_groups ; ++j )
-       sum += subc_list_double_at(&cmd.dl_contrast[i],j);
+      for (j = 0; j < ostensible_number_of_groups; ++j)
+       sum += subc_list_double_at (&cmd.dl_contrast[i], j);
 
       if ( sum != 0.0 )
-       msg(SW,_("Coefficients for contrast %zu do not total zero"), i + 1);
+       msg (SW, _("Coefficients for contrast %zu do not total zero"), i + 1);
     }
 
   if ( stat_tables & STAT_DESC )
-    show_descriptives();
+    show_descriptives ();
 
   if ( stat_tables & STAT_HOMO )
-    show_homogeneity();
+    show_homogeneity ();
 
-  show_anova_table();
+  show_anova_table ();
 
   if (cmd.sbc_contrast )
     {
-      show_contrast_coeffs(bad_contrast);
-      show_contrast_tests(bad_contrast);
+      show_contrast_coeffs (bad_contrast);
+      show_contrast_tests (bad_contrast);
     }
 
-
-  free(bad_contrast);
+  free (bad_contrast);
 
   /* Clean up */
-  for (i = 0 ; i < n_vars ; ++i )
+  for (i = 0; i < n_vars; ++i )
     {
       struct hsh_table *group_hash = group_proc_get (vars[i])->group_hash;
 
-      hsh_destroy(group_hash);
+      hsh_destroy (group_hash);
     }
 
-  hsh_destroy(global_group_hash);
-
+  hsh_destroy (global_group_hash);
 }
 
 
-
-
 /* Parser for the variables sub command */
 static int
 oneway_custom_variables (struct lexer *lexer,
-                       struct dataset *ds, struct cmd_oneway *cmd UNUSED,
-                       void *aux UNUSED)
+                        struct dataset *ds, struct cmd_oneway *cmd UNUSED,
+                        void *aux UNUSED)
 {
   struct dictionary *dict = dataset_dict (ds);
 
   lex_match (lexer, '=');
 
-  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
+  if ((lex_token (lexer) != T_ID ||
+       dict_lookup_var (dict, lex_tokid (lexer)) == NULL)
       && lex_token (lexer) != T_ALL)
     return 2;
 
   if (!parse_variables_const (lexer, dict, &vars, &n_vars,
-                       PV_DUPLICATE
-                       | PV_NUMERIC | PV_NO_SCRATCH) )
+                             PV_DUPLICATE
+                             | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (vars);
       return 0;
     }
 
-  assert(n_vars);
+  assert (n_vars);
 
   if ( ! lex_match (lexer, T_BY))
     return 2;
@@ -241,7 +239,7 @@ oneway_custom_variables (struct lexer *lexer,
 
   if ( !indep_var )
     {
-      msg(SE,_("`%s' is not a variable name"),lex_tokid (lexer));
+      msg (SE, _("`%s' is not a variable name"), lex_tokid (lexer));
       return 0;
     }
 
@@ -251,7 +249,7 @@ oneway_custom_variables (struct lexer *lexer,
 
 /* Show the ANOVA table */
 static void
-show_anova_table(void)
+show_anova_table (void)
 {
   size_t i;
   int n_cols =7;
@@ -260,7 +258,7 @@ show_anova_table(void)
   struct tab_table *t;
 
 
-  t = tab_create (n_cols,n_rows,0);
+  t = tab_create (n_cols, n_rows, 0);
   tab_headers (t, 2, 0, 1, 0);
   tab_dim (t, tab_natural_dimensions);
 
@@ -282,23 +280,23 @@ show_anova_table(void)
   tab_text (t, 6, 0, TAB_CENTER | TAT_TITLE, _("Significance"));
 
 
-  for ( i=0 ; i < n_vars ; ++i )
+  for (i = 0; i < n_vars; ++i)
     {
       struct group_statistics *totals = &group_proc_get (vars[i])->ugs;
       struct hsh_table *group_hash = group_proc_get (vars[i])->group_hash;
       struct hsh_iterator g;
       struct group_statistics *gs;
-      double ssa=0;
-      const char *s = var_to_string(vars[i]);
+      double ssa = 0;
+      const char *s = var_to_string (vars[i]);
 
-      for (gs =  hsh_first (group_hash,&g);
+      for (gs =  hsh_first (group_hash, &g);
           gs != 0;
-          gs = hsh_next(group_hash,&g))
+          gs = hsh_next (group_hash, &g))
        {
-         ssa += (gs->sum * gs->sum)/gs->n;
+         ssa += pow2 (gs->sum) / gs->n;
        }
 
-      ssa -= ( totals->sum * totals->sum ) / totals->n ;
+      ssa -= pow2 (totals->sum) / totals->n;
 
       tab_text (t, 0, i * 3 + 1, TAB_LEFT | TAT_TITLE, s);
       tab_text (t, 1, i * 3 + 1, TAB_LEFT | TAT_TITLE, _("Between Groups"));
@@ -306,13 +304,13 @@ show_anova_table(void)
       tab_text (t, 1, i * 3 + 3, TAB_LEFT | TAT_TITLE, _("Total"));
 
       if (i > 0)
-       tab_hline(t, TAL_1, 0, n_cols - 1 , i * 3 + 1);
+       tab_hline (t, TAL_1, 0, n_cols - 1, i * 3 + 1);
 
       {
         struct group_proc *gp = group_proc_get (vars[i]);
-       const double sst = totals->ssq - ( totals->sum * totals->sum) / totals->n ;
+       const double sst = totals->ssq - pow2 (totals->sum) / totals->n;
        const double df1 = gp->n_groups - 1;
-       const double df2 = totals->n - gp->n_groups ;
+       const double df2 = totals->n - gp->n_groups;
        const double msa = ssa / df1;
 
        gp->mse  = (sst - ssa) / df2;
@@ -333,19 +331,16 @@ show_anova_table(void)
        tab_float (t, 4, i * 3 + 1, TAB_RIGHT, msa, 8, 3);
        tab_float (t, 4, i * 3 + 2, TAB_RIGHT, gp->mse, 8, 3);
 
-
        {
-         const double F = msa/gp->mse ;
+         const double F = msa/gp->mse;
 
          /* The F value */
          tab_float (t, 5, i * 3 + 1, 0,  F, 8, 3);
 
          /* The significance */
-         tab_float (t, 6, i * 3 + 1, 0, gsl_cdf_fdist_Q(F,df1,df2), 8, 3);
+         tab_float (t, 6, i * 3 + 1, 0, gsl_cdf_fdist_Q (F, df1, df2), 8, 3);
        }
-
       }
-
     }
 
 
@@ -356,23 +351,23 @@ show_anova_table(void)
 
 /* Show the descriptives table */
 static void
-show_descriptives(void)
+show_descriptives (void)
 {
   size_t v;
   int n_cols =10;
   struct tab_table *t;
   int row;
 
-  const double confidence=0.95;
+  const double confidence = 0.95;
   const double q = (1.0 - confidence) / 2.0;
 
 
-  int n_rows = 2 ;
+  int n_rows = 2;
 
-  for ( v = 0 ; v < n_vars ; ++v )
+  for ( v = 0; v < n_vars; ++v )
     n_rows += group_proc_get (vars[v])->n_groups + 1;
 
-  t = tab_create (n_cols,n_rows,0);
+  t = tab_create (n_cols, n_rows, 0);
   tab_headers (t, 2, 0, 2, 0);
   tab_dim (t, tab_natural_dimensions);
 
@@ -385,7 +380,7 @@ show_descriptives(void)
           n_cols - 1, n_rows - 1);
 
   /* Underline headers */
-  tab_hline (t, TAL_2, 0, n_cols - 1, 2 );
+  tab_hline (t, TAL_2, 0, n_cols - 1, 2);
   tab_vline (t, TAL_2, 2, 0, n_rows - 1);
 
   tab_text (t, 2, 1, TAB_CENTER | TAT_TITLE, _("N"));
@@ -394,9 +389,10 @@ show_descriptives(void)
   tab_text (t, 5, 1, TAB_CENTER | TAT_TITLE, _("Std. Error"));
 
 
-  tab_vline(t, TAL_0, 7, 0, 0);
-  tab_hline(t, TAL_1, 6, 7, 1);
-  tab_joint_text (t, 6, 0, 7, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF, _("%g%% Confidence Interval for Mean"),confidence*100.0);
+  tab_vline (t, TAL_0, 7, 0, 0);
+  tab_hline (t, TAL_1, 6, 7, 1);
+  tab_joint_text (t, 6, 0, 7, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
+                 _("%g%% Confidence Interval for Mean"), confidence*100.0);
 
   tab_text (t, 6, 1, TAB_CENTER | TAT_TITLE, _("Lower Bound"));
   tab_text (t, 7, 1, TAB_CENTER | TAT_TITLE, _("Upper Bound"));
@@ -409,7 +405,7 @@ show_descriptives(void)
 
 
   row = 2;
-  for ( v=0 ; v < n_vars ; ++v )
+  for (v = 0; v < n_vars; ++v)
     {
       double T;
       double std_error;
@@ -419,17 +415,17 @@ show_descriptives(void)
       struct group_statistics *gs;
       struct group_statistics *totals = &gp->ugs;
 
-      const char *s = var_to_string(vars[v]);
+      const char *s = var_to_string (vars[v]);
 
       struct group_statistics *const *gs_array =
-       (struct group_statistics *const *) hsh_sort(gp->group_hash);
+       (struct group_statistics *const *) hsh_sort (gp->group_hash);
       int count = 0;
 
       tab_text (t, 0, row, TAB_LEFT | TAT_TITLE, s);
       if ( v > 0)
-       tab_hline(t, TAL_1, 0, n_cols - 1 , row);
+       tab_hline (t, TAL_1, 0, n_cols - 1, row);
 
-      for (count = 0 ; count < hsh_count(gp->group_hash) ; ++count)
+      for (count = 0; count < hsh_count (gp->group_hash); ++count)
        {
          struct string vstr;
          ds_init_empty (&vstr);
@@ -445,73 +441,67 @@ show_descriptives(void)
 
          /* Now fill in the numbers ... */
 
-         tab_float (t, 2, row + count, 0, gs->n, 8,0);
+         tab_float (t, 2, row + count, 0, gs->n, 8, 0);
 
-         tab_float (t, 3, row + count, 0, gs->mean,8,2);
+         tab_float (t, 3, row + count, 0, gs->mean, 8, 2);
 
-         tab_float (t, 4, row + count, 0, gs->std_dev,8,2);
+         tab_float (t, 4, row + count, 0, gs->std_dev, 8, 2);
 
-         std_error = gs->std_dev/sqrt(gs->n) ;
+         std_error = gs->std_dev/sqrt (gs->n);
          tab_float (t, 5, row + count, 0,
-                    std_error, 8,2);
+                    std_error, 8, 2);
 
          /* Now the confidence interval */
 
-         T = gsl_cdf_tdist_Qinv(q,gs->n - 1);
+         T = gsl_cdf_tdist_Qinv (q, gs->n - 1);
 
-         tab_float(t, 6, row + count, 0,
-                   gs->mean - T * std_error, 8, 2);
+         tab_float (t, 6, row + count, 0,
+                    gs->mean - T * std_error, 8, 2);
 
-         tab_float(t, 7, row + count, 0,
-                   gs->mean + T * std_error, 8, 2);
+         tab_float (t, 7, row + count, 0,
+                    gs->mean + T * std_error, 8, 2);
 
          /* Min and Max */
-
-         tab_float(t, 8, row + count, 0,  gs->minimum, 8, 2);
-         tab_float(t, 9, row + count, 0,  gs->maximum, 8, 2);
-
+         tab_float (t, 8, row + count, 0,  gs->minimum, 8, 2);
+         tab_float (t, 9, row + count, 0,  gs->maximum, 8, 2);
        }
 
       tab_text (t, 1, row + count,
-               TAB_LEFT | TAT_TITLE ,_("Total"));
+               TAB_LEFT | TAT_TITLE_("Total"));
 
-      tab_float (t, 2, row + count, 0, totals->n, 8,0);
+      tab_float (t, 2, row + count, 0, totals->n, 8, 0);
 
-      tab_float (t, 3, row + count, 0, totals->mean, 8,2);
+      tab_float (t, 3, row + count, 0, totals->mean, 8, 2);
 
-      tab_float (t, 4, row + count, 0, totals->std_dev,8,2);
+      tab_float (t, 4, row + count, 0, totals->std_dev, 8, 2);
 
-      std_error = totals->std_dev/sqrt(totals->n) ;
+      std_error = totals->std_dev/sqrt (totals->n);
 
-      tab_float (t, 5, row + count, 0, std_error, 8,2);
+      tab_float (t, 5, row + count, 0, std_error, 8, 2);
 
       /* Now the confidence interval */
 
-      T = gsl_cdf_tdist_Qinv(q,totals->n - 1);
+      T = gsl_cdf_tdist_Qinv (q, totals->n - 1);
 
-      tab_float(t, 6, row + count, 0,
-               totals->mean - T * std_error, 8, 2);
+      tab_float (t, 6, row + count, 0,
+                totals->mean - T * std_error, 8, 2);
 
-      tab_float(t, 7, row + count, 0,
-               totals->mean + T * std_error, 8, 2);
+      tab_float (t, 7, row + count, 0,
+                totals->mean + T * std_error, 8, 2);
 
       /* Min and Max */
-
-      tab_float(t, 8, row + count, 0,  totals->minimum, 8, 2);
-      tab_float(t, 9, row + count, 0,  totals->maximum, 8, 2);
+      tab_float (t, 8, row + count, 0,  totals->minimum, 8, 2);
+      tab_float (t, 9, row + count, 0,  totals->maximum, 8, 2);
 
       row += gp->n_groups + 1;
     }
 
-
   tab_submit (t);
-
-
 }
 
 /* Show the homogeneity table */
 static void
-show_homogeneity(void)
+show_homogeneity (void)
 {
   size_t v;
   int n_cols = 5;
@@ -520,7 +510,7 @@ show_homogeneity(void)
   struct tab_table *t;
 
 
-  t = tab_create (n_cols,n_rows,0);
+  t = tab_create (n_cols, n_rows, 0);
   tab_headers (t, 1, 0, 1, 0);
   tab_dim (t, tab_natural_dimensions);
 
@@ -532,38 +522,37 @@ show_homogeneity(void)
           n_cols - 1, n_rows - 1);
 
 
-  tab_hline(t, TAL_2, 0, n_cols - 1, 1);
-  tab_vline(t, TAL_2, 1, 0, n_rows - 1);
+  tab_hline (t, TAL_2, 0, n_cols - 1, 1);
+  tab_vline (t, TAL_2, 1, 0, n_rows - 1);
 
 
-  tab_text (t,  1, 0, TAB_CENTER | TAT_TITLE, _("Levene Statistic"));
-  tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("df1"));
-  tab_text (t,  3, 0, TAB_CENTER | TAT_TITLE, _("df2"));
-  tab_text (t,  4, 0, TAB_CENTER | TAT_TITLE, _("Significance"));
-
+  tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Levene Statistic"));
+  tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("df1"));
+  tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("df2"));
+  tab_text (t, 4, 0, TAB_CENTER | TAT_TITLE, _("Significance"));
 
   tab_title (t, _("Test of Homogeneity of Variances"));
 
-  for ( v=0 ; v < n_vars ; ++v )
+  for (v = 0; v < n_vars; ++v)
     {
       double F;
       const struct variable *var = vars[v];
       const struct group_proc *gp = group_proc_get (vars[v]);
-      const char *s = var_to_string(var);
+      const char *s = var_to_string (var);
       const struct group_statistics *totals = &gp->ugs;
 
       const double df1 = gp->n_groups - 1;
-      const double df2 = totals->n - gp->n_groups ;
+      const double df2 = totals->n - gp->n_groups;
 
       tab_text (t, 0, v + 1, TAB_LEFT | TAT_TITLE, s);
 
       F = gp->levene;
-      tab_float (t, 1, v + 1, TAB_RIGHT, F, 8,3);
-      tab_float (t, 2, v + 1, TAB_RIGHT, df1 ,8,0);
-      tab_float (t, 3, v + 1, TAB_RIGHT, df2 ,8,0);
+      tab_float (t, 1, v + 1, TAB_RIGHT, F, 8, 3);
+      tab_float (t, 2, v + 1, TAB_RIGHT, df1, 8, 0);
+      tab_float (t, 3, v + 1, TAB_RIGHT, df2, 8, 0);
 
       /* Now the significance */
-      tab_float (t, 4, v + 1, TAB_RIGHT,gsl_cdf_fdist_Q(F,df1,df2), 8, 3);
+      tab_float (t, 4, v + 1, TAB_RIGHT, gsl_cdf_fdist_Q (F, df1, df2), 8, 3);
     }
 
   tab_submit (t);
@@ -577,12 +566,12 @@ show_contrast_coeffs (short *bad_contrast)
   int n_cols = 2 + ostensible_number_of_groups;
   int n_rows = 2 + cmd.sbc_contrast;
   union value *group_value;
-  int count = 0 ;
-  void *const *group_values ;
+  int count = 0;
+  void *const *group_values;
 
   struct tab_table *t;
 
-  t = tab_create (n_cols,n_rows,0);
+  t = tab_create (n_cols, n_rows, 0);
   tab_headers (t, 2, 0, 2, 0);
   tab_dim (t, tab_natural_dimensions);
 
@@ -594,21 +583,21 @@ show_contrast_coeffs (short *bad_contrast)
           n_cols - 1, n_rows - 1);
 
   tab_box (t,
-          -1,-1,
+          -1, -1,
           TAL_0, TAL_0,
           2, 0,
           n_cols - 1, 0);
 
   tab_box (t,
-          -1,-1,
+          -1, -1,
           TAL_0, TAL_0,
-          0,0,
-          1,1);
+          0, 0,
+          1, 1);
 
-  tab_hline(t, TAL_1, 2, n_cols - 1, 1);
-  tab_hline(t, TAL_2, 0, n_cols - 1, 2);
+  tab_hline (t, TAL_1, 2, n_cols - 1, 1);
+  tab_hline (t, TAL_2, 0, n_cols - 1, 2);
 
-  tab_vline(t, TAL_2, 2, 0, n_rows - 1);
+  tab_vline (t, TAL_2, 2, 0, n_rows - 1);
 
   tab_title (t, _("Contrast Coefficients"));
 
@@ -616,11 +605,11 @@ show_contrast_coeffs (short *bad_contrast)
 
 
   tab_joint_text (t, 2, 0, n_cols - 1, 0, TAB_CENTER | TAT_TITLE,
-                 var_to_string(indep_var));
+                 var_to_string (indep_var));
 
-  group_values = hsh_sort(global_group_hash);
-  for (count = 0 ;
-       count < hsh_count(global_group_hash) ;
+  group_values = hsh_sort (global_group_hash);
+  for (count = 0;
+       count < hsh_count (global_group_hash);
        ++count)
     {
       int i;
@@ -637,16 +626,16 @@ show_contrast_coeffs (short *bad_contrast)
       ds_destroy (&vstr);
 
 
-      for (i = 0 ; i < cmd.sbc_contrast ; ++i )
+      for (i = 0; i < cmd.sbc_contrast; ++i )
        {
-         tab_text(t, 1, i + 2, TAB_CENTER | TAT_PRINTF, "%d", i + 1);
+         tab_text (t, 1, i + 2, TAB_CENTER | TAT_PRINTF, "%d", i + 1);
 
          if ( bad_contrast[i] )
-           tab_text(t, count + 2, i + 2, TAB_RIGHT, "?" );
+           tab_text (t, count + 2, i + 2, TAB_RIGHT, "?" );
          else
-           tab_text(t, count + 2, i + 2, TAB_RIGHT | TAT_PRINTF, "%g",
-                    subc_list_double_at(&cmd.dl_contrast[i], count)
-                    );
+           tab_text (t, count + 2, i + 2, TAB_RIGHT | TAT_PRINTF, "%g",
+                     subc_list_double_at (&cmd.dl_contrast[i], count)
+                     );
        }
     }
 
@@ -656,7 +645,7 @@ show_contrast_coeffs (short *bad_contrast)
 
 /* Show the results of the contrast tests */
 static void
-show_contrast_tests(short *bad_contrast)
+show_contrast_tests (short *bad_contrast)
 {
   size_t v;
   int n_cols = 8;
@@ -664,7 +653,7 @@ show_contrast_tests(short *bad_contrast)
 
   struct tab_table *t;
 
-  t = tab_create (n_cols,n_rows,0);
+  t = tab_create (n_cols, n_rows, 0);
   tab_headers (t, 3, 0, 1, 0);
   tab_dim (t, tab_natural_dimensions);
 
@@ -676,34 +665,34 @@ show_contrast_tests(short *bad_contrast)
           n_cols - 1, n_rows - 1);
 
   tab_box (t,
-          -1,-1,
+          -1, -1,
           TAL_0, TAL_0,
           0, 0,
           2, 0);
 
-  tab_hline(t, TAL_2, 0, n_cols - 1, 1);
-  tab_vline(t, TAL_2, 3, 0, n_rows - 1);
+  tab_hline (t, TAL_2, 0, n_cols - 1, 1);
+  tab_vline (t, TAL_2, 3, 0, n_rows - 1);
 
 
   tab_title (t, _("Contrast Tests"));
 
-  tab_text (t,  2, 0, TAB_CENTER | TAT_TITLE, _("Contrast"));
-  tab_text (t,  3, 0, TAB_CENTER | TAT_TITLE, _("Value of Contrast"));
+  tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Contrast"));
+  tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Value of Contrast"));
   tab_text (t,  4, 0, TAB_CENTER | TAT_TITLE, _("Std. Error"));
   tab_text (t,  5, 0, TAB_CENTER | TAT_TITLE, _("t"));
   tab_text (t,  6, 0, TAB_CENTER | TAT_TITLE, _("df"));
   tab_text (t,  7, 0, TAB_CENTER | TAT_TITLE, _("Sig. (2-tailed)"));
 
-  for ( v = 0 ; v < n_vars ; ++v )
+  for (v = 0; v < n_vars; ++v)
     {
       int i;
       int lines_per_variable = 2 * cmd.sbc_contrast;
 
 
       tab_text (t,  0, (v * lines_per_variable) + 1, TAB_LEFT | TAT_TITLE,
-               var_to_string(vars[v]));
+               var_to_string (vars[v]));
 
-      for ( i = 0 ; i < cmd.sbc_contrast ; ++i )
+      for (i = 0; i < cmd.sbc_contrast; ++i)
        {
          int ci;
          double contrast_value = 0.0;
@@ -714,18 +703,18 @@ show_contrast_tests(short *bad_contrast)
          void *const *group_stat_array;
 
          double T;
-         double std_error_contrast ;
+         double std_error_contrast;
          double df;
-         double sec_vneq=0.0;
+         double sec_vneq = 0.0;
 
 
          /* Note: The calculation of the degrees of freedom in the
             "variances not equal" case is painfull!!
             The following formula may help to understand it:
-            \frac{\left(\sum_{i=1}^k{c_i^2\frac{s_i^2}{n_i}}\right)^2}
+            \frac{\left (\sum_{i=1}^k{c_i^2\frac{s_i^2}{n_i}}\right)^2}
             {
-            \sum_{i=1}^k\left(
-            \frac{\left(c_i^2\frac{s_i^2}{n_i}\right)^2}  {n_i-1}
+            \sum_{i=1}^k\left (
+            \frac{\left (c_i^2\frac{s_i^2}{n_i}\right)^2}  {n_i-1}
             \right)
             }
          */
@@ -744,72 +733,72 @@ show_contrast_tests(short *bad_contrast)
            }
 
          tab_text (t,  2, (v * lines_per_variable) + i + 1,
-                   TAB_CENTER | TAT_TITLE | TAT_PRINTF, "%d",i+1);
+                   TAB_CENTER | TAT_TITLE | TAT_PRINTF, "%d", i + 1);
 
 
          tab_text (t,  2, (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
-                   TAB_CENTER | TAT_TITLE | TAT_PRINTF, "%d",i+1);
+                   TAB_CENTER | TAT_TITLE | TAT_PRINTF, "%d", i + 1);
 
 
          if ( bad_contrast[i])
            continue;
 
-         group_stat_array = hsh_sort(group_hash);
+         group_stat_array = hsh_sort (group_hash);
 
-         for (ci = 0 ; ci < hsh_count(group_hash) ;  ++ci)
+         for (ci = 0; ci < hsh_count (group_hash);  ++ci)
            {
-             const double coef = subc_list_double_at(&cmd.dl_contrast[i], ci);
+             const double coef = subc_list_double_at (&cmd.dl_contrast[i], ci);
              struct group_statistics *gs = group_stat_array[ci];
 
-             const double winv = (gs->std_dev * gs->std_dev) / gs->n;
+             const double winv = pow2 (gs->std_dev) / gs->n;
 
              contrast_value += coef * gs->mean;
 
-             coef_msq += (coef * coef) / gs->n ;
+             coef_msq += (coef * coef) / gs->n;
 
-             sec_vneq += (coef * coef) * (gs->std_dev * gs->std_dev ) /gs->n ;
+             sec_vneq += (coef * coef) * pow2 (gs->std_dev) /gs->n;
 
              df_numerator += (coef * coef) * winv;
              df_denominator += pow2((coef * coef) * winv) / (gs->n - 1);
            }
-         sec_vneq = sqrt(sec_vneq);
+         sec_vneq = sqrt (sec_vneq);
 
          df_numerator = pow2(df_numerator);
 
          tab_float (t,  3, (v * lines_per_variable) + i + 1,
-                    TAB_RIGHT, contrast_value, 8,2);
+                    TAB_RIGHT, contrast_value, 8, 2);
 
          tab_float (t,  3, (v * lines_per_variable) + i + 1 +
                     cmd.sbc_contrast,
-                    TAB_RIGHT, contrast_value, 8,2);
+                    TAB_RIGHT, contrast_value, 8, 2);
 
-         std_error_contrast = sqrt(grp_data->mse * coef_msq);
+         std_error_contrast = sqrt (grp_data->mse * coef_msq);
 
          /* Std. Error */
          tab_float (t,  4, (v * lines_per_variable) + i + 1,
                     TAB_RIGHT, std_error_contrast,
-                    8,3);
+                    8, 3);
 
-         T = fabs(contrast_value / std_error_contrast) ;
+         T = fabs (contrast_value / std_error_contrast);
 
          /* T Statistic */
 
          tab_float (t,  5, (v * lines_per_variable) + i + 1,
                     TAB_RIGHT, T,
-                    8,3);
+                    8, 3);
 
          df = grp_data->ugs.n - grp_data->n_groups;
 
          /* Degrees of Freedom */
          tab_float (t,  6, (v * lines_per_variable) + i + 1,
                     TAB_RIGHT,  df,
-                    8,0);
+                    8, 0);
 
 
          /* Significance TWO TAILED !!*/
          tab_float (t,  7, (v * lines_per_variable) + i + 1,
-                    TAB_RIGHT,  2 * gsl_cdf_tdist_Q(T,df),
-                    8,3);
+                    TAB_RIGHT,  2 * gsl_cdf_tdist_Q (T, df),
+                    8, 3);
 
 
          /* Now for the Variances NOT Equal case */
@@ -818,14 +807,14 @@ show_contrast_tests(short *bad_contrast)
          tab_float (t,  4,
                     (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
                     TAB_RIGHT, sec_vneq,
-                    8,3);
+                    8, 3);
 
 
          T = contrast_value / sec_vneq;
          tab_float (t,  5,
                     (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
                     TAB_RIGHT, T,
-                    8,3);
+                    8, 3);
 
 
          df = df_numerator / df_denominator;
@@ -833,19 +822,19 @@ show_contrast_tests(short *bad_contrast)
          tab_float (t,  6,
                     (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
                     TAB_RIGHT, df,
-                    8,3);
+                    8, 3);
 
          /* The Significance */
 
          tab_float (t, 7, (v * lines_per_variable) + i + 1 + cmd.sbc_contrast,
-                    TAB_RIGHT,  2 * gsl_cdf_tdist_Q(T,df),
-                    8,3);
+                    TAB_RIGHT,  2 * gsl_cdf_tdist_Q (T, df),
+                    8, 3);
 
 
        }
 
       if ( v > 0 )
-       tab_hline(t, TAL_1, 0, n_cols - 1, (v * lines_per_variable) + 1);
+       tab_hline (t, TAL_1, 0, n_cols - 1, (v * lines_per_variable) + 1);
     }
 
   tab_submit (t);
@@ -855,19 +844,19 @@ show_contrast_tests(short *bad_contrast)
 
 /* ONEWAY ANOVA Calculations */
 
-static void  postcalc (  struct cmd_oneway *cmd UNUSED );
+static void  postcalc (struct cmd_oneway *cmd UNUSED);
 
-static void  precalc ( struct cmd_oneway *cmd UNUSED );
+static void  precalc (struct cmd_oneway *cmd UNUSED);
 
 
 
 /* Pre calculations */
 static void
-precalc ( struct cmd_oneway *cmd UNUSED )
+precalc (struct cmd_oneway *cmd UNUSED)
 {
-  size_t i=0;
+  size_t i = 0;
 
-  for(i=0; i< n_vars ; ++i)
+  for (i = 0; i < n_vars; ++i)
     {
       struct group_proc *gp = group_proc_get (vars[i]);
       struct group_statistics *totals = &gp->ugs;
@@ -876,19 +865,15 @@ precalc ( struct cmd_oneway *cmd UNUSED )
         The hash contains a group_statistics structure,
         and is keyed by value of the independent variable */
 
-      gp->group_hash =
-       hsh_create(4,
-                  (hsh_compare_func *) compare_group,
-                  (hsh_hash_func *) hash_group,
-                  (hsh_free_func *) free_group,
-                  (void *) var_get_width (indep_var) );
+      gp->group_hash = hsh_create (4, compare_group, hash_group,
+                                  (hsh_free_func *) free_group,
+                                  indep_var);
 
-
-      totals->sum=0;
-      totals->n=0;
-      totals->ssq=0;
-      totals->sum_diff=0;
-      totals->maximum = - DBL_MAX;
+      totals->sum = 0;
+      totals->n = 0;
+      totals->ssq = 0;
+      totals->sum_diff = 0;
+      totals->maximum = -DBL_MAX;
       totals->minimum = DBL_MAX;
     }
 }
@@ -921,20 +906,20 @@ run_oneway (struct cmd_oneway *cmd,
 
   taint = taint_clone (casereader_get_taint (input));
 
-  global_group_hash = hsh_create(4,
-                                (hsh_compare_func *) compare_values,
-                                (hsh_hash_func *) hash_value,
-                                free_value,
-                                (void *) var_get_width (indep_var) );
+  global_group_hash = hsh_create (4,
+                                 compare_values,
+                                 hash_value,
+                                 free_value,
+                                 indep_var);
 
-  precalc(cmd);
+  precalc (cmd);
 
   exclude = cmd->incl != ONEWAY_INCLUDE ? MV_ANY : MV_SYSTEM;
   input = casereader_create_filter_missing (input, &indep_var, 1,
-                                            exclude, NULL);
+                                            exclude, NULL, NULL);
   if (cmd->miss == ONEWAY_LISTWISE)
     input = casereader_create_filter_missing (input, vars, n_vars,
-                                              exclude, NULL);
+                                              exclude, NULL, NULL);
   input = casereader_create_filter_weight (input, dict, NULL, NULL);
 
   reader = casereader_clone (input);
@@ -949,7 +934,7 @@ run_oneway (struct cmd_oneway *cmd,
       if (*p == NULL)
         *p = value_dup (indep_val, var_get_width (indep_var));
 
-      for ( i = 0 ; i < n_vars ; ++i )
+      for (i = 0; i < n_vars; ++i)
        {
          const struct variable *v = vars[i];
 
@@ -960,29 +945,29 @@ run_oneway (struct cmd_oneway *cmd,
 
          struct group_statistics *gs;
 
-         gs = hsh_find(group_hash, (void *) indep_val );
+         gs = hsh_find (group_hash, indep_val );
 
          if ( ! gs )
            {
              gs = xmalloc (sizeof *gs);
              gs->id = *indep_val;
-             gs->sum=0;
-             gs->n=0;
-             gs->ssq=0;
-             gs->sum_diff=0;
+             gs->sum = 0;
+             gs->n = 0;
+             gs->ssq = 0;
+             gs->sum_diff = 0;
              gs->minimum = DBL_MAX;
              gs->maximum = -DBL_MAX;
 
-             hsh_insert ( group_hash, (void *) gs );
+             hsh_insert ( group_hash, gs );
            }
 
          if (!var_is_value_missing (v, val, exclude))
            {
              struct group_statistics *totals = &gp->ugs;
 
-             totals->n+=weight;
-             totals->sum+=weight * val->f;
-             totals->ssq+=weight * val->f * val->f;
+             totals->n += weight;
+             totals->sum += weight * val->f;
+             totals->ssq += weight * pow2 (val->f);
 
              if ( val->f * weight  < totals->minimum )
                totals->minimum = val->f * weight;
@@ -990,9 +975,9 @@ run_oneway (struct cmd_oneway *cmd,
              if ( val->f * weight  > totals->maximum )
                totals->maximum = val->f * weight;
 
-             gs->n+=weight;
-             gs->sum+=weight * val->f;
-             gs->ssq+=weight * val->f * val->f;
+             gs->n += weight;
+             gs->sum += weight * val->f;
+             gs->ssq += weight * pow2 (val->f);
 
              if ( val->f * weight  < gs->minimum )
                gs->minimum = val->f * weight;
@@ -1007,7 +992,7 @@ run_oneway (struct cmd_oneway *cmd,
     }
   casereader_destroy (reader);
 
-  postcalc(cmd);
+  postcalc (cmd);
 
 
   if ( stat_tables & STAT_HOMO )
@@ -1018,7 +1003,7 @@ run_oneway (struct cmd_oneway *cmd,
   ostensible_number_of_groups = hsh_count (global_group_hash);
 
   if (!taint_has_tainted_successor (taint))
-    output_oneway();
+    output_oneway ();
   taint_destroy (taint);
 }
 
@@ -1027,10 +1012,9 @@ run_oneway (struct cmd_oneway *cmd,
 void
 postcalc (  struct cmd_oneway *cmd UNUSED )
 {
-  size_t i=0;
-
+  size_t i = 0;
 
-  for(i = 0; i < n_vars ; ++i)
+  for (i = 0; i < n_vars; ++i)
     {
       struct group_proc *gp = group_proc_get (vars[i]);
       struct hsh_table *group_hash = gp->group_hash;
@@ -1039,35 +1023,29 @@ postcalc (  struct cmd_oneway *cmd UNUSED )
       struct hsh_iterator g;
       struct group_statistics *gs;
 
-      for (gs =  hsh_first (group_hash,&g);
+      for (gs =  hsh_first (group_hash, &g);
           gs != 0;
-          gs = hsh_next(group_hash,&g))
+          gs = hsh_next (group_hash, &g))
        {
-         gs->mean=gs->sum / gs->n;
-         gs->s_std_dev= sqrt(
-                             ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
-                             ) ;
-
-         gs->std_dev= sqrt(
-                           gs->n/(gs->n-1) *
-                           ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
-                           ) ;
+         gs->mean = gs->sum / gs->n;
+         gs->s_std_dev = sqrt (gs->ssq / gs->n - pow2 (gs->mean));
 
-         gs->se_mean = gs->std_dev / sqrt(gs->n);
-         gs->mean_diff= gs->sum_diff / gs->n;
+         gs->std_dev = sqrt (
+                             gs->n / (gs->n - 1) *
+                             ( gs->ssq / gs->n - pow2 (gs->mean))
+                             );
 
+         gs->se_mean = gs->std_dev / sqrt (gs->n);
+         gs->mean_diff = gs->sum_diff / gs->n;
        }
 
-
-
       totals->mean = totals->sum / totals->n;
-      totals->std_dev= sqrt(
-                           totals->n/(totals->n-1) *
-                           ( (totals->ssq / totals->n ) - totals->mean * totals->mean )
-                           ) ;
-
-      totals->se_mean = totals->std_dev / sqrt(totals->n);
+      totals->std_dev = sqrt (
+                             totals->n / (totals->n - 1) *
+                             (totals->ssq / totals->n - pow2 (totals->mean))
+                             );
 
+      totals->se_mean = totals->std_dev / sqrt (totals->n);
     }
 }
 
index 5bc88c4a97a84fe91aabf77fc897df9e30e4a9bf..13facbdbbf59f85e43bd350578d4633cb07b880e 100644 (file)
@@ -261,7 +261,7 @@ rank_cmd (struct dataset *ds, const struct case_ordering *sc,
 
           /* Sort this split group by the BY variables as primary
              keys and the rank variable as secondary key. */
-          ordering = case_ordering_create (d);
+          ordering = case_ordering_create ();
           for (j = 0; j < n_group_vars; j++)
             case_ordering_add_var (ordering, group_vars[j], SRT_ASCEND);
           case_ordering_add_var (ordering,
@@ -486,7 +486,7 @@ rank_sorted_file (struct casereader *input,
 
 
   input = casereader_create_filter_missing (input, &rank_var, 1,
-                                            exclude_values, output);
+                                            exclude_values, NULL, output);
   input = casereader_create_filter_weight (input, dict, NULL, output);
 
   casereader_split (input, &pass1, &pass2);
@@ -778,7 +778,7 @@ cmd_rank (struct lexer *lexer, struct dataset *ds)
   /* Put the active file back in its original order.  Delete
      our sort key, which we don't need anymore.  */
   {
-    struct case_ordering *ordering = case_ordering_create (dataset_dict (ds));
+    struct case_ordering *ordering = case_ordering_create ();
     struct casereader *sorted;
     case_ordering_add_var (ordering, order, SRT_ASCEND);
     /* FIXME: loses error conditions. */
index 1d31d1845e02e20064610bf3886cd8d11c71f5a0..4f6f0b862196b6a7365466147145714f3969bfa9 100644 (file)
@@ -861,39 +861,6 @@ coeff_init (pspp_linreg_cache * c, struct design_matrix *dm)
   pspp_coeff_init (c->coeff, dm);
 }
 
-/*
-  Put the moments in the linreg cache.
- */
-static void
-compute_moments (pspp_linreg_cache * c, struct moments_var *mom,
-                struct design_matrix *dm, size_t n)
-{
-  size_t i;
-  size_t j;
-  double weight;
-  double mean;
-  double variance;
-  double skewness;
-  double kurtosis;
-  /*
-     Scan the variable names in the columns of the design matrix.
-     When we find the variable we need, insert its mean in the cache.
-   */
-  for (i = 0; i < dm->m->size2; i++)
-    {
-      for (j = 0; j < n; j++)
-       {
-         if (design_matrix_col_to_var (dm, i) == (mom + j)->v)
-           {
-             moments1_calculate ((mom + j)->m, &weight, &mean, &variance,
-                                 &skewness, &kurtosis);
-             pspp_linreg_set_indep_variable_mean (c, (mom + j)->v, mean);
-             pspp_linreg_set_indep_variable_sd (c, (mom + j)->v, sqrt (variance));
-           }
-       }
-    }
-}
-
 static bool
 run_regression (struct casereader *input, struct cmd_regression *cmd,
                struct dataset *ds, pspp_linreg_cache **models)
@@ -956,9 +923,9 @@ run_regression (struct casereader *input, struct cmd_regression *cmd,
       n_indep = identify_indep_vars (indep_vars, dep_var);
       reader = casereader_clone (input);
       reader = casereader_create_filter_missing (reader, indep_vars, n_indep,
-                                                MV_ANY, NULL);
+                                                MV_ANY, NULL, NULL);
       reader = casereader_create_filter_missing (reader, &dep_var, 1,
-                                                MV_ANY, NULL);
+                                                MV_ANY, NULL, NULL);
       n_data = prepare_categories (casereader_clone (reader),
                                   indep_vars, n_indep, mom);
 
@@ -973,7 +940,8 @@ run_regression (struct casereader *input, struct cmd_regression *cmd,
            {
              lopts.get_indep_mean_std[i] = 1;
            }
-         models[k] = pspp_linreg_cache_alloc (X->m->size1, X->m->size2);
+         models[k] = pspp_linreg_cache_alloc (dep_var, (const struct variable **) indep_vars,
+                                              X->m->size1, X->m->size2);
          models[k]->depvar = dep_var;
          /*
             For large data sets, use QR decomposition.
diff --git a/src/language/stats/reliability.q b/src/language/stats/reliability.q
new file mode 100644 (file)
index 0000000..8384bb3
--- /dev/null
@@ -0,0 +1,812 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "xalloc.h"
+#include "xmalloca.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+#include <data/variable.h>
+#include <data/dictionary.h>
+#include <data/procedure.h>
+#include <data/casereader.h>
+#include <data/casegrouper.h>
+#include <math/moments.h>
+#include <data/case.h>
+
+#include <language/command.h>
+
+#include <output/manager.h>
+#include <output/table.h>
+
+/* (headers) */
+
+/* (specification)
+   reliability (rel_):
+     *^variables=varlist("PV_NO_SCRATCH | PV_NUMERIC");
+     scale=custom;
+     missing=miss:!exclude/include;
+     model=custom;
+     method=covariance;
+     +summary[sum_]=total.
+*/
+/* (declarations) */
+/* (functions) */
+
+
+static int rel_custom_scale (struct lexer *lexer, struct dataset *ds,
+                     struct cmd_reliability *p, void *aux);
+
+static int rel_custom_model (struct lexer *, struct dataset *,
+                            struct cmd_reliability *, void *);
+
+int cmd_reliability (struct lexer *lexer, struct dataset *ds);
+
+struct cronbach
+{
+  const struct variable **items;
+  size_t n_items;
+  double alpha;
+  double sum_of_variances;
+  double variance_of_sums;
+  int totals_idx;          /* Casereader index into the totals */
+
+  struct moments1 **m ;    /* Moments of the items */
+  struct moments1 *total ; /* Moments of the totals */
+};
+
+#if 0
+static void
+dump_cronbach (const struct cronbach *s)
+{
+  int i;
+  printf ("N items %d\n", s->n_items);
+  for (i = 0 ; i < s->n_items; ++i)
+    {
+      printf ("%s\n", var_get_name (s->items[i]));
+    }
+
+  printf ("Totals idx %d\n", s->totals_idx);
+
+  printf ("scale variance %g\n", s->variance_of_sums);
+  printf ("alpha %g\n", s->alpha);
+  putchar ('\n');
+}
+#endif
+
+enum model
+  {
+    MODEL_ALPHA,
+    MODEL_SPLIT
+  };
+
+
+struct reliability
+{
+  const struct variable **variables;
+  int n_variables;
+  enum mv_class exclude;
+
+  struct cronbach *sc;
+  int n_sc;
+
+  int total_start;
+
+  struct string scale_name;
+
+  enum model model;
+  int split_point;
+};
+
+
+static double
+alpha (int k, double sum_of_variances, double variance_of_sums)
+{
+  return k / ( k - 1.0) * ( 1 - sum_of_variances / variance_of_sums);
+}
+
+static void reliability_summary_total (const struct reliability *rel);
+
+static void reliability_statistics (const struct reliability *rel);
+
+
+
+static void
+run_reliability (struct casereader *group, struct dataset *ds,
+                struct reliability *rel);
+
+
+int
+cmd_reliability (struct lexer *lexer, struct dataset *ds)
+{
+  int i;
+  bool ok = false;
+  struct casegrouper *grouper;
+  struct casereader *group;
+  struct cmd_reliability cmd;
+
+  struct reliability rel = {
+    NULL, 0, MV_ANY, NULL, 0, -1,
+    DS_EMPTY_INITIALIZER,
+    MODEL_ALPHA, 0};
+
+  cmd.v_variables = NULL;
+
+  if ( ! parse_reliability (lexer, ds, &cmd, &rel) )
+    {
+      goto done;
+    }
+
+  rel.variables = cmd.v_variables;
+  rel.n_variables = cmd.n_variables;
+  rel.exclude = MV_ANY;
+
+
+  if (NULL == rel.sc)
+    {
+      struct cronbach *c;
+      /* Create a default Scale */
+
+      rel.n_sc = 1;
+      rel.sc = xzalloc (sizeof (struct cronbach) * rel.n_sc);
+
+      ds_init_cstr (&rel.scale_name, "ANY");
+
+      c = &rel.sc[0];
+      c->n_items = cmd.n_variables;
+      c->items = xzalloc (sizeof (struct variable*) * c->n_items);
+
+      for (i = 0 ; i < c->n_items ; ++i)
+       c->items[i] = cmd.v_variables[i];
+    }
+
+  if ( cmd.miss == REL_INCLUDE)
+    rel.exclude = MV_SYSTEM;
+
+  if ( rel.model == MODEL_SPLIT)
+    {
+      int i;
+      const struct cronbach *s;
+
+      rel.n_sc += 2 ;
+      rel.sc = xrealloc (rel.sc, sizeof (struct cronbach) * rel.n_sc);
+
+      s = &rel.sc[0];
+
+      rel.sc[1].n_items =
+       (rel.split_point == -1) ? s->n_items / 2 : rel.split_point;
+
+      rel.sc[2].n_items = s->n_items - rel.sc[1].n_items;
+      rel.sc[1].items = xzalloc (sizeof (struct variable *)
+                                * rel.sc[1].n_items);
+
+      rel.sc[2].items = xzalloc (sizeof (struct variable *) *
+                                rel.sc[2].n_items);
+
+      for  (i = 0; i < rel.sc[1].n_items ; ++i)
+       rel.sc[1].items[i] = s->items[i];
+
+      while (i < s->n_items)
+       {
+         rel.sc[2].items[i - rel.sc[1].n_items] = s->items[i];
+         i++;
+       }
+    }
+
+  if (cmd.a_summary[REL_SUM_TOTAL])
+    {
+      int i;
+      const int base_sc = rel.n_sc;
+
+      rel.total_start = base_sc;
+
+      rel.n_sc +=  rel.sc[0].n_items ;
+      rel.sc = xrealloc (rel.sc, sizeof (struct cronbach) * rel.n_sc);
+
+      for (i = 0 ; i < rel.sc[0].n_items; ++i )
+       {
+         int v_src;
+         int v_dest = 0;
+         struct cronbach *s = &rel.sc[i + base_sc];
+
+         s->n_items = rel.sc[0].n_items - 1;
+         s->items = xzalloc (sizeof (struct variable *) * s->n_items);
+         for (v_src = 0 ; v_src < rel.sc[0].n_items ; ++v_src)
+           {
+             if ( v_src != i)
+               s->items[v_dest++] = rel.sc[0].items[v_src];
+           }
+       }
+    }
+
+  /* Data pass. */
+  grouper = casegrouper_create_splits (proc_open (ds), dataset_dict (ds));
+  while (casegrouper_get_next_group (grouper, &group))
+    {
+      run_reliability (group, ds, &rel);
+
+      reliability_statistics (&rel);
+
+      if (cmd.a_summary[REL_SUM_TOTAL])
+       reliability_summary_total (&rel);
+    }
+  ok = casegrouper_destroy (grouper);
+  ok = proc_commit (ds) && ok;
+
+  free_reliability (&cmd);
+
+ done:
+
+  /* Free all the stuff */
+  for (i = 0 ; i < rel.n_sc; ++i)
+    {
+      int x;
+      struct cronbach *c = &rel.sc[i];
+      free (c->items);
+
+      moments1_destroy (c->total);
+
+      if ( c->m)
+       for (x = 0 ; x < c->n_items; ++x)
+         moments1_destroy (c->m[x]);
+
+      free (c->m);
+    }
+
+  ds_destroy (&rel.scale_name);
+  free (rel.sc);
+
+  if (ok)
+    return CMD_SUCCESS;
+
+  return CMD_FAILURE;
+}
+
+/* Return the sum of all the item variables in S */
+static  double
+append_sum (const struct ccase *c, casenumber n UNUSED, void *aux)
+{
+  double sum = 0;
+  const struct cronbach *s = aux;
+
+  int v;
+  for (v = 0 ; v < s->n_items; ++v)
+    {
+      sum += case_data (c, s->items[v])->f;
+    }
+
+  return sum;
+};
+
+
+static void case_processing_summary (casenumber n_valid, casenumber n_missing);
+
+static void
+run_reliability (struct casereader *input, struct dataset *ds UNUSED,
+                struct reliability *rel)
+{
+  int i;
+  int si;
+  struct ccase c;
+  casenumber n_missing ;
+  casenumber n_valid = 0;
+
+
+  for (si = 0 ; si < rel->n_sc; ++si)
+    {
+      struct cronbach *s = &rel->sc[si];
+
+      s->m = xzalloc (sizeof (s->m) * s->n_items);
+      s->total = moments1_create (MOMENT_VARIANCE);
+
+      for (i = 0 ; i < s->n_items ; ++i )
+       s->m[i] = moments1_create (MOMENT_VARIANCE);
+    }
+
+  input = casereader_create_filter_missing (input,
+                                           rel->variables,
+                                           rel->n_variables,
+                                           rel->exclude,
+                                           &n_missing,
+                                           NULL);
+
+  for (si = 0 ; si < rel->n_sc; ++si)
+    {
+      struct cronbach *s = &rel->sc[si];
+
+
+      s->totals_idx = casereader_get_value_cnt (input);
+      input =
+       casereader_create_append_numeric (input, append_sum,
+                                         s, NULL);
+    }
+
+  for (; casereader_read (input, &c); case_destroy (&c))
+    {
+      double weight = 1.0;
+      n_valid ++;
+
+      for (si = 0; si < rel->n_sc; ++si)
+       {
+         struct cronbach *s = &rel->sc[si];
+
+         for (i = 0 ; i < s->n_items ; ++i )
+           moments1_add (s->m[i], case_data (&c, s->items[i])->f, weight);
+
+         moments1_add (s->total, case_data_idx (&c, s->totals_idx)->f, weight);
+       }
+    }
+  casereader_destroy (input);
+
+  for (si = 0; si < rel->n_sc; ++si)
+    {
+      struct cronbach *s = &rel->sc[si];
+
+      s->sum_of_variances = 0;
+      for (i = 0 ; i < s->n_items ; ++i )
+       {
+         double weight, mean, variance;
+         moments1_calculate (s->m[i], &weight, &mean, &variance, NULL, NULL);
+
+         s->sum_of_variances += variance;
+       }
+
+      moments1_calculate (s->total, NULL, NULL, &s->variance_of_sums,
+                         NULL, NULL);
+
+      s->alpha =
+       alpha (s->n_items, s->sum_of_variances, s->variance_of_sums);
+    }
+
+
+  {
+    struct tab_table *tab = tab_create(1, 1, 0);
+
+    tab_dim (tab, tab_natural_dimensions);
+    tab_flags (tab, SOMF_NO_TITLE );
+
+    tab_text(tab, 0, 0, TAT_PRINTF, "Scale: %s", ds_cstr (&rel->scale_name));
+
+    tab_submit(tab);
+  }
+
+
+  case_processing_summary (n_valid, n_missing);
+}
+
+
+static void reliability_statistics_model_alpha (struct tab_table *tbl,
+                                               const struct reliability *rel);
+
+static void reliability_statistics_model_split (struct tab_table *tbl,
+                                               const struct reliability *rel);
+
+struct reliability_output_table
+{
+  int n_cols;
+  int n_rows;
+  int heading_cols;
+  int heading_rows;
+  void (*populate)(struct tab_table *, const struct reliability *);
+};
+
+static struct reliability_output_table rol[2] =
+  {
+    { 2, 2, 1, 1, reliability_statistics_model_alpha},
+    { 4, 9, 3, 0, reliability_statistics_model_split}
+  };
+
+static void
+reliability_statistics (const struct reliability *rel)
+{
+  int n_cols = rol[rel->model].n_cols;
+  int n_rows = rol[rel->model].n_rows;
+  int heading_columns = rol[rel->model].heading_cols;
+  int heading_rows = rol[rel->model].heading_rows;
+
+  struct tab_table *tbl = tab_create (n_cols, n_rows, 0);
+  tab_headers (tbl, heading_columns, 0, heading_rows, 0);
+
+  tab_dim (tbl, tab_natural_dimensions);
+
+  tab_title (tbl, _("Reliability Statistics"));
+
+  /* Vertical lines for the data only */
+  tab_box (tbl,
+          -1, -1,
+          -1, TAL_1,
+          heading_columns, 0,
+          n_cols - 1, n_rows - 1);
+
+  /* Box around table */
+  tab_box (tbl,
+          TAL_2, TAL_2,
+          -1, -1,
+          0, 0,
+          n_cols - 1, n_rows - 1);
+
+
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows);
+
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
+
+  if ( rel->model == MODEL_ALPHA )
+    reliability_statistics_model_alpha (tbl, rel);
+  else if (rel->model == MODEL_SPLIT )
+    reliability_statistics_model_split (tbl, rel);
+
+  tab_submit (tbl);
+}
+
+static void
+reliability_summary_total (const struct reliability *rel)
+{
+  int i;
+  const int n_cols = 5;
+  const int heading_columns = 1;
+  const int heading_rows = 1;
+  const int n_rows = rel->sc[0].n_items + heading_rows ;
+
+  struct tab_table *tbl = tab_create (n_cols, n_rows, 0);
+  tab_headers (tbl, heading_columns, 0, heading_rows, 0);
+
+  tab_dim (tbl, tab_natural_dimensions);
+
+  tab_title (tbl, _("Item-Total Statistics"));
+
+  /* Vertical lines for the data only */
+  tab_box (tbl,
+          -1, -1,
+          -1, TAL_1,
+          heading_columns, 0,
+          n_cols - 1, n_rows - 1);
+
+  /* Box around table */
+  tab_box (tbl,
+          TAL_2, TAL_2,
+          -1, -1,
+          0, 0,
+          n_cols - 1, n_rows - 1);
+
+
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows);
+
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
+
+  tab_text (tbl, 1, 0, TAB_CENTER | TAT_TITLE,
+           _("Scale Mean if Item Deleted"));
+
+  tab_text (tbl, 2, 0, TAB_CENTER | TAT_TITLE,
+           _("Scale Variance if Item Deleted"));
+
+  tab_text (tbl, 3, 0, TAB_CENTER | TAT_TITLE,
+           _("Corrected Item-Total Correlation"));
+
+  tab_text (tbl, 4, 0, TAB_CENTER | TAT_TITLE,
+           _("Cronbach's Alpha if Item Deleted"));
+
+
+  for (i = 0 ; i < rel->sc[0].n_items; ++i)
+    {
+      double cov, item_to_total_r;
+      double mean, weight, var;
+
+      const struct cronbach *s = &rel->sc[rel->total_start + i];
+      tab_text (tbl, 0, heading_rows + i, TAB_LEFT| TAT_TITLE,
+               var_to_string (rel->sc[0].items[i]));
+
+      moments1_calculate (s->total, &weight, &mean, &var, 0, 0);
+
+      tab_float (tbl, 1, heading_rows + i, TAB_RIGHT,
+                mean, 8, 3);
+
+      tab_float (tbl, 2, heading_rows + i, TAB_RIGHT,
+                s->variance_of_sums, 8, 3);
+
+      tab_float (tbl, 4, heading_rows + i, TAB_RIGHT,
+                s->alpha, 8, 3);
+
+
+      moments1_calculate (rel->sc[0].m[i], &weight, &mean, &var, 0,0);
+      cov = rel->sc[0].variance_of_sums + var - s->variance_of_sums;
+      cov /= 2.0;
+
+      item_to_total_r = (cov - var) / (sqrt(var) * sqrt (s->variance_of_sums));
+
+
+      tab_float (tbl, 3, heading_rows + i, TAB_RIGHT,
+                item_to_total_r, 8, 3);
+    }
+
+
+  tab_submit (tbl);
+}
+
+
+static void
+reliability_statistics_model_alpha (struct tab_table *tbl,
+                                   const struct reliability *rel)
+{
+  const struct cronbach *s = &rel->sc[0];
+
+  tab_text (tbl, 0, 0, TAB_CENTER | TAT_TITLE,
+               _("Cronbach's Alpha"));
+
+  tab_text (tbl, 1, 0, TAB_CENTER | TAT_TITLE,
+               _("N of items"));
+
+  tab_float (tbl, 0, 1, TAB_RIGHT, s->alpha, 8, 3);
+
+  tab_float (tbl, 1, 1, TAB_RIGHT, s->n_items, 8, 0);
+}
+
+
+static void
+reliability_statistics_model_split (struct tab_table *tbl,
+                                   const struct reliability *rel)
+{
+  tab_text (tbl, 0, 0, TAB_LEFT,
+           _("Cronbach's Alpha"));
+
+  tab_text (tbl, 1, 0, TAB_LEFT,
+           _("Part 1"));
+
+  tab_text (tbl, 2, 0, TAB_LEFT,
+           _("Value"));
+
+  tab_text (tbl, 2, 1, TAB_LEFT,
+           _("N of Items"));
+
+
+
+  tab_text (tbl, 1, 2, TAB_LEFT,
+           _("Part 2"));
+
+  tab_text (tbl, 2, 2, TAB_LEFT,
+           _("Value"));
+
+  tab_text (tbl, 2, 3, TAB_LEFT,
+           _("N of Items"));
+
+
+
+  tab_text (tbl, 1, 4, TAB_LEFT,
+           _("Total N of Items"));
+
+  tab_text (tbl, 0, 5, TAB_LEFT,
+           _("Correlation Between Forms"));
+
+
+  tab_text (tbl, 0, 6, TAB_LEFT,
+           _("Spearman-Brown Coefficient"));
+
+  tab_text (tbl, 1, 6, TAB_LEFT,
+           _("Equal Length"));
+
+  tab_text (tbl, 1, 7, TAB_LEFT,
+           _("Unequal Length"));
+
+
+  tab_text (tbl, 0, 8, TAB_LEFT,
+           _("Guttman Split-Half Coefficient"));
+
+
+
+  tab_float (tbl, 3, 0, TAB_RIGHT, rel->sc[1].alpha, 8, 3);
+  tab_float (tbl, 3, 2, TAB_RIGHT, rel->sc[2].alpha, 8, 3);
+
+  tab_float (tbl, 3, 1, TAB_RIGHT, rel->sc[1].n_items, 8, 0);
+  tab_float (tbl, 3, 3, TAB_RIGHT, rel->sc[2].n_items, 8, 0);
+
+  tab_float (tbl, 3, 4, TAB_RIGHT,
+            rel->sc[1].n_items + rel->sc[2].n_items, 8, 0);
+
+  {
+    /* R is the correlation between the two parts */
+    double r = rel->sc[0].variance_of_sums -
+      rel->sc[1].variance_of_sums -
+      rel->sc[2].variance_of_sums ;
+
+    /* Guttman Split Half Coefficient */
+    double g = 2 * r / rel->sc[0].variance_of_sums;
+
+    /* Unequal Length Spearman Brown Coefficient, and
+     intermediate value used in the computation thereof */
+    double uly, tmp;
+
+    r /= sqrt (rel->sc[1].variance_of_sums);
+    r /= sqrt (rel->sc[2].variance_of_sums);
+    r /= 2.0;
+
+    tab_float (tbl, 3, 5, TAB_RIGHT, r, 8, 3);
+
+    /* Equal length Spearman-Brown Coefficient */
+    tab_float (tbl, 3, 6, TAB_RIGHT, 2 * r / (1.0 + r), 8, 3);
+
+    tab_float (tbl, 3, 8, TAB_RIGHT, g, 8, 3);
+
+    tmp = (1.0 - r*r) * rel->sc[1].n_items * rel->sc[2].n_items /
+      pow2 (rel->sc[0].n_items);
+
+    uly = sqrt( pow4 (r) + 4 * pow2 (r) * tmp);
+    uly -= pow2 (r);
+    uly /= 2 * tmp;
+
+    tab_float (tbl, 3, 7, TAB_RIGHT, uly, 8, 3);
+
+  }
+}
+
+
+
+static void
+case_processing_summary (casenumber n_valid, casenumber n_missing)
+{
+  casenumber total;
+  int n_cols = 4;
+  int n_rows = 4;
+  int heading_columns = 2;
+  int heading_rows = 1;
+  struct tab_table *tbl;
+  tbl = tab_create (n_cols, n_rows, 0);
+  tab_headers (tbl, heading_columns, 0, heading_rows, 0);
+
+  tab_dim (tbl, tab_natural_dimensions);
+
+  tab_title (tbl, _("Case Processing Summary"));
+
+  /* Vertical lines for the data only */
+  tab_box (tbl,
+          -1, -1,
+          -1, TAL_1,
+          heading_columns, 0,
+          n_cols - 1, n_rows - 1);
+
+  /* Box around table */
+  tab_box (tbl,
+          TAL_2, TAL_2,
+          -1, -1,
+          0, 0,
+          n_cols - 1, n_rows - 1);
+
+
+  tab_hline (tbl, TAL_2, 0, n_cols - 1, heading_rows);
+
+  tab_vline (tbl, TAL_2, heading_columns, 0, n_rows - 1);
+
+
+  tab_text (tbl, 0, heading_rows, TAB_LEFT | TAT_TITLE,
+               _("Cases"));
+
+  tab_text (tbl, 1, heading_rows, TAB_LEFT | TAT_TITLE,
+               _("Valid"));
+
+  tab_text (tbl, 1, heading_rows + 1, TAB_LEFT | TAT_TITLE,
+               _("Excluded"));
+
+  tab_text (tbl, 1, heading_rows + 2, TAB_LEFT | TAT_TITLE,
+               _("Total"));
+
+  tab_text (tbl, heading_columns, 0, TAB_CENTER | TAT_TITLE,
+               _("N"));
+
+  tab_text (tbl, heading_columns + 1, 0, TAB_CENTER | TAT_TITLE | TAT_PRINTF,
+               _("%%"));
+
+  total = n_missing + n_valid;
+
+  tab_float (tbl, 2, heading_rows, TAB_RIGHT,
+            n_valid, 8, 0);
+
+
+  tab_float (tbl, 2, heading_rows + 1, TAB_RIGHT,
+            n_missing, 8, 0);
+
+
+  tab_float (tbl, 2, heading_rows + 2, TAB_RIGHT,
+            total, 8, 0);
+
+
+  tab_float (tbl, 3, heading_rows, TAB_RIGHT,
+            100 * n_valid / (double) total, 8, 1);
+
+
+  tab_float (tbl, 3, heading_rows + 1, TAB_RIGHT,
+            100 * n_missing / (double) total, 8, 1);
+
+
+  tab_float (tbl, 3, heading_rows + 2, TAB_RIGHT,
+            100 * total / (double) total, 8, 1);
+
+
+  tab_submit (tbl);
+}
+
+static int
+rel_custom_model (struct lexer *lexer, struct dataset *ds UNUSED,
+                 struct cmd_reliability *cmd UNUSED, void *aux)
+{
+  struct reliability *rel = aux;
+
+  if (lex_match_id (lexer, "ALPHA"))
+    {
+      rel->model = MODEL_ALPHA;
+    }
+  else if (lex_match_id (lexer, "SPLIT"))
+    {
+      rel->model = MODEL_SPLIT;
+      rel->split_point = -1;
+      if ( lex_match (lexer, '('))
+       {
+         lex_force_num (lexer);
+         rel->split_point = lex_number (lexer);
+         lex_get (lexer);
+         lex_force_match (lexer, ')');
+       }
+    }
+  else
+    return 0;
+
+  return 1;
+}
+
+
+
+static int
+rel_custom_scale (struct lexer *lexer, struct dataset *ds UNUSED,
+                 struct cmd_reliability *p, void *aux)
+{
+  struct const_var_set *vs;
+  struct reliability *rel = aux;
+  struct cronbach *scale;
+
+  rel->n_sc = 1;
+  rel->sc = xzalloc (sizeof (struct cronbach) * rel->n_sc);
+  scale = &rel->sc[0];
+
+  if ( ! lex_force_match (lexer, '(')) return 0;
+
+  if ( ! lex_force_string (lexer) ) return 0;
+
+  ds_init_string (&rel->scale_name, lex_tokstr (lexer));
+
+  lex_get (lexer);
+
+  if ( ! lex_force_match (lexer, ')')) return 0;
+
+  lex_match (lexer, '=');
+
+  vs = const_var_set_create_from_array (p->v_variables, p->n_variables);
+
+  if (!parse_const_var_set_vars (lexer, vs, &scale->items, &scale->n_items, 0))
+    {
+      const_var_set_destroy (vs);
+      return 2;
+    }
+
+  const_var_set_destroy (vs);
+  return 1;
+}
+
+/*
+   Local Variables:
+   mode: c
+   End:
+*/
index c84f71d54cee3dc69bd8fa20bc4950bda0f7ef1c..fd8c7c535f9e630b88acbfdbafeaa8367374fdcc 100644 (file)
@@ -39,7 +39,7 @@ struct case_ordering *
 parse_case_ordering (struct lexer *lexer, const struct dictionary *dict,
                      bool *saw_direction)
 {
-  struct case_ordering *ordering = case_ordering_create (dict);
+  struct case_ordering *ordering = case_ordering_create ();
   const struct variable **vars = NULL;
   size_t var_cnt = 0;
 
index 5bb02e1767af92edd5267f4c2c9e42bbfcf9440a..3d27874362050247f3ab55f534312d4bdfc217ee 100644 (file)
@@ -80,8 +80,8 @@ struct group_properties
   /* The comparison criterion */
   enum comparison criterion;
 
-  /* The width of the independent variable */
-  int indep_width ;
+  /* The independent variable */
+  struct variable *indep_var;
 
   union {
     /* The value of the independent variable at which groups are determined to
@@ -1459,7 +1459,7 @@ common_calc (const struct dictionary *dict,
 
          gs->n += weight;
          gs->sum += weight * val->f;
-         gs->ssq += weight * val->f * val->f;
+         gs->ssq += weight * pow2 (val->f);
        }
     }
   return 0;
@@ -1496,12 +1496,12 @@ common_postcalc (struct cmd_t_test *cmd)
 
       gs->mean=gs->sum / gs->n;
       gs->s_std_dev= sqrt (
-                        ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+                        ( (gs->ssq / gs->n ) - pow2 (gs->mean))
                         ) ;
 
       gs->std_dev= sqrt (
                         gs->n/ (gs->n-1) *
-                        ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+                        ( (gs->ssq / gs->n ) - pow2 (gs->mean))
                         ) ;
 
       gs->se_mean = gs->std_dev / sqrt (gs->n);
@@ -1676,7 +1676,7 @@ group_precalc (struct cmd_t_test *cmd )
       /* There's always 2 groups for a T - TEST */
       ttpr->n_groups = 2;
 
-      gp.indep_width = var_get_width (indep_var);
+      gp.indep_var = indep_var;
 
       ttpr->group_hash = hsh_create (2,
                                    (hsh_compare_func *) compare_group_binary,
@@ -1772,12 +1772,12 @@ group_postcalc ( struct cmd_t_test *cmd )
          gs->mean = gs->sum / gs->n;
 
          gs->s_std_dev= sqrt (
-                             ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+                             ( (gs->ssq / gs->n ) - pow2 (gs->mean))
                              ) ;
 
          gs->std_dev= sqrt (
                            gs->n/ (gs->n-1) *
-                           ( (gs->ssq / gs->n ) - gs->mean * gs->mean )
+                           ( (gs->ssq / gs->n ) - pow2 (gs->mean))
                            ) ;
 
          gs->se_mean = gs->std_dev / sqrt (gs->n);
@@ -1815,7 +1815,7 @@ calculate (struct cmd_t_test *cmd,
     input = casereader_create_filter_missing (input,
                                               cmd->v_variables,
                                               cmd->n_variables,
-                                              exclude, NULL);
+                                              exclude, NULL, NULL);
 
   input = casereader_create_filter_weight (input, dict, NULL, NULL);
 
@@ -1888,10 +1888,6 @@ compare_group_binary (const struct group_statistics *a,
 
   if ( p->criterion == CMP_LE )
     {
-      /* less-than comparision is not meaningfull for
-        alpha variables, so we shouldn't ever arrive here */
-      assert (p->indep_width == 0 ) ;
-
       flag_a = ( a->id.f < p->v.critical_value ) ;
       flag_b = ( b->id.f < p->v.critical_value ) ;
     }
@@ -1918,8 +1914,6 @@ hash_group_binary (const struct group_statistics *g,
 
   if ( p->criterion == CMP_LE )
     {
-      /* Not meaningfull to do a less than compare for alpha values ? */
-      assert (p->indep_width == 0 ) ;
       flag = ( g->id.f < p->v.critical_value ) ;
     }
   else if ( p->criterion == CMP_EQ)
@@ -1939,10 +1933,10 @@ short
 which_group (const struct group_statistics *g,
            const struct group_properties *p)
 {
-  if ( 0 == compare_values (&g->id, &p->v.g_value[0], p->indep_width))
+  if ( 0 == compare_values (&g->id, &p->v.g_value[0], p->indep_var))
     return 0;
 
-  if ( 0 == compare_values (&g->id, &p->v.g_value[1], p->indep_width))
+  if ( 0 == compare_values (&g->id, &p->v.g_value[1], p->indep_var))
     return 1;
 
   return 2;
diff --git a/src/language/stats/wilcoxon.c b/src/language/stats/wilcoxon.c
new file mode 100644 (file)
index 0000000..7552d7e
--- /dev/null
@@ -0,0 +1,418 @@
+/* Pspp - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+
+#include <config.h>
+#include "wilcoxon.h"
+#include <data/variable.h>
+#include <data/casereader.h>
+#include <data/casewriter.h>
+#include <data/case-ordering.h>
+#include <math/sort.h>
+#include <libpspp/message.h>
+#include <xalloc.h>
+#include <output/table.h>
+#include <data/procedure.h>
+#include <data/dictionary.h>
+#include <misc/wx-mp-sr.h>
+#include <gsl/gsl_cdf.h>
+#include <unistd.h>
+#include <signal.h>
+#include <libpspp/assertion.h>
+
+static double timed_wilcoxon_significance (double w, long int n, double timer);
+
+
+static double
+append_difference (const struct ccase *c, casenumber n UNUSED, void *aux)
+{
+  const variable_pair *vp = aux;
+
+  return case_data (c, (*vp)[0])->f - case_data (c, (*vp)[1])->f;
+}
+
+static void show_ranks_box (const struct wilcoxon_state *,
+                           const struct two_sample_test *);
+
+static void show_tests_box (const struct wilcoxon_state *,
+                           const struct two_sample_test *,
+                           bool exact, double timer);
+
+
+
+static void
+distinct_callback (double v UNUSED, casenumber n, double w UNUSED, void *aux)
+{
+  struct wilcoxon_state *ws = aux;
+
+  ws->tiebreaker += pow3 (n) - n;
+}
+
+#define WEIGHT_IDX 2
+
+void
+wilcoxon_execute (const struct dataset *ds,
+                 struct casereader *input,
+                 enum mv_class exclude,
+                 const struct npar_test *test,
+                 bool exact,
+                 double timer)
+{
+  int i;
+  bool warn = true;
+  const struct dictionary *dict = dataset_dict (ds);
+  const struct two_sample_test *t2s = (struct two_sample_test *) test;
+
+  struct wilcoxon_state *ws = xcalloc (sizeof (*ws), t2s->n_pairs);
+  const struct variable *weight = dict_get_weight (dict);
+  struct variable *weightx = var_create_internal (WEIGHT_IDX);
+
+  input =
+    casereader_create_filter_weight (input, dict, &warn, NULL);
+
+  for (i = 0 ; i < t2s->n_pairs; ++i )
+    {
+      struct casereader *r = casereader_clone (input);
+      struct casewriter *writer;
+      struct ccase c;
+      struct case_ordering *ordering = case_ordering_create ();
+      variable_pair *vp = &t2s->pairs[i];
+
+      const int reader_width = weight ? 3 : 2;
+
+      ws[i].sign = var_create_internal (0);
+      ws[i].absdiff = var_create_internal (1);
+
+      case_ordering_add_var (ordering, ws[i].absdiff, SRT_ASCEND);
+
+
+      r = casereader_create_filter_missing (r, *vp, 2,
+                                           exclude,
+                                           NULL, NULL);
+
+      writer = sort_create_writer (ordering, reader_width);
+      while (casereader_read (r, &c))
+       {
+         struct ccase output;
+         double d = append_difference (&c, 0, vp);
+
+         case_create (&output, reader_width);
+
+         if (d > 0)
+           {
+             case_data_rw (&output, ws[i].sign)->f = 1.0;
+
+           }
+         else if (d < 0)
+           {
+             case_data_rw (&output, ws[i].sign)->f = -1.0;
+           }
+         else
+           {
+             double w = 1.0;
+             if (weight)
+               w = case_data (&c, weight)->f;
+
+             /* Central point values should be dropped */
+             ws[i].n_zeros += w;
+             case_destroy (&c);
+             continue;
+           }
+
+         case_data_rw (&output, ws[i].absdiff)->f = fabs (d);
+
+         if (weight)
+          case_data_rw (&output, weightx)->f = case_data (&c, weight)->f;
+
+         casewriter_write (writer, &output);
+         case_destroy (&c);
+       }
+      casereader_destroy (r);
+      ws[i].reader = casewriter_make_reader (writer);
+    }
+
+  for (i = 0 ; i < t2s->n_pairs; ++i )
+    {
+      struct casereader *rr ;
+      struct ccase c;
+      enum rank_error err = 0;
+
+      rr = casereader_create_append_rank (ws[i].reader, ws[i].absdiff,
+                                         weight ? weightx : NULL, &err,
+                                         distinct_callback, &ws[i]
+                                         );
+
+      while (casereader_read (rr, &c))
+       {
+         double sign = case_data (&c, ws[i].sign)->f;
+         double rank = case_data_idx (&c, weight ? 3 : 2)->f;
+         double w = 1.0;
+         if (weight)
+           w = case_data (&c, weightx)->f;
+
+         if ( sign > 0 )
+           {
+             ws[i].positives.sum += rank * w;
+             ws[i].positives.n += w;
+           }
+         else if (sign < 0)
+           {
+             ws[i].negatives.sum += rank * w;
+             ws[i].negatives.n += w;
+           }
+         else
+           NOT_REACHED ();
+
+         case_destroy (&c);
+       }
+
+      casereader_destroy (rr);
+    }
+
+  casereader_destroy (input);
+
+  var_destroy (weightx);
+
+  show_ranks_box (ws, t2s);
+  show_tests_box (ws, t2s, exact, timer);
+
+  for (i = 0 ; i < t2s->n_pairs; ++i )
+    {
+      var_destroy (ws[i].sign);
+      var_destroy (ws[i].absdiff);
+    }
+
+  free (ws);
+}
+
+
+\f
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+static void
+show_ranks_box (const struct wilcoxon_state *ws, const struct two_sample_test *t2s)
+{
+  size_t i;
+  struct tab_table *table = tab_create (5, 1 + 4 * t2s->n_pairs, 0);
+
+  tab_dim (table, tab_natural_dimensions);
+
+  tab_title (table, _("Ranks"));
+
+  tab_headers (table, 2, 0, 1, 0);
+
+  /* Vertical lines inside the box */
+  tab_box (table, 0, 0, -1, TAL_1,
+          1, 0, table->nc - 1, tab_nr (table) - 1 );
+
+  /* Box around entire table */
+  tab_box (table, TAL_2, TAL_2, -1, -1,
+          0, 0, table->nc - 1, tab_nr (table) - 1 );
+
+
+  tab_text (table,  2, 0,  TAB_CENTER, _("N"));
+  tab_text (table,  3, 0,  TAB_CENTER, _("Mean Rank"));
+  tab_text (table,  4, 0,  TAB_CENTER, _("Sum of Ranks"));
+
+
+  for (i = 0 ; i < t2s->n_pairs; ++i)
+    {
+      variable_pair *vp = &t2s->pairs[i];
+
+      struct string pair_name;
+      ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
+      ds_put_cstr (&pair_name, " - ");
+      ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
+
+      tab_text (table, 1, 1 + i * 4, TAB_LEFT, _("Negative Ranks"));
+      tab_text (table, 1, 2 + i * 4, TAB_LEFT, _("Positive Ranks"));
+      tab_text (table, 1, 3 + i * 4, TAB_LEFT, _("Ties"));
+      tab_text (table, 1, 4 + i * 4, TAB_LEFT, _("Total"));
+
+      tab_hline (table, TAL_1, 0, table->nc - 1, 1 + i * 4);
+
+
+      tab_text (table, 0, 1 + i * 4, TAB_LEFT, ds_cstr (&pair_name));
+      ds_destroy (&pair_name);
+
+
+      /* N */
+      tab_float (table, 2, 1 + i * 4, TAB_RIGHT, ws[i].negatives.n, 8, 0);
+      tab_float (table, 2, 2 + i * 4, TAB_RIGHT, ws[i].positives.n, 8, 0);
+      tab_float (table, 2, 3 + i * 4, TAB_RIGHT, ws[i].n_zeros, 8, 0);
+
+      tab_float (table, 2, 4 + i * 4, TAB_RIGHT,
+                ws[i].n_zeros + ws[i].positives.n + ws[i].negatives.n, 8, 0);
+
+      /* Sums */
+      tab_float (table, 4, 1 + i * 4, TAB_RIGHT, ws[i].negatives.sum, 8, 2);
+      tab_float (table, 4, 2 + i * 4, TAB_RIGHT, ws[i].positives.sum, 8, 2);
+
+
+      /* Means */
+      tab_float (table, 3, 1 + i * 4, TAB_RIGHT,
+                ws[i].negatives.sum / (double) ws[i].negatives.n, 8, 2);
+
+      tab_float (table, 3, 2 + i * 4, TAB_RIGHT,
+                ws[i].positives.sum / (double) ws[i].positives.n, 8, 2);
+
+    }
+
+  tab_hline (table, TAL_2, 0, table->nc - 1, 1);
+  tab_vline (table, TAL_2, 2, 0, table->nr - 1);
+
+
+  tab_submit (table);
+}
+
+
+static void
+show_tests_box (const struct wilcoxon_state *ws,
+               const struct two_sample_test *t2s,
+               bool exact,
+               double timer
+               )
+{
+  size_t i;
+  struct tab_table *table = tab_create (1 + t2s->n_pairs, exact ? 5 : 3, 0);
+
+  tab_dim (table, tab_natural_dimensions);
+
+  tab_title (table, _("Test Statistics"));
+
+  tab_headers (table, 1, 0, 1, 0);
+
+  /* Vertical lines inside the box */
+  tab_box (table, 0, 0, -1, TAL_1,
+          0, 0, table->nc - 1, tab_nr (table) - 1 );
+
+  /* Box around entire table */
+  tab_box (table, TAL_2, TAL_2, -1, -1,
+          0, 0, table->nc - 1, tab_nr (table) - 1 );
+
+
+  tab_text (table,  0, 1,  TAB_LEFT, _("Z"));
+  tab_text (table,  0, 2,  TAB_LEFT, _("Asymp. Sig (2-tailed)"));
+
+  if ( exact )
+    {
+      tab_text (table,  0, 3,  TAB_LEFT, _("Exact Sig (2-tailed)"));
+      tab_text (table,  0, 4,  TAB_LEFT, _("Exact Sig (1-tailed)"));
+
+#if 0
+      tab_text (table,  0, 5,  TAB_LEFT, _("Point Probability"));
+#endif
+    }
+
+  for (i = 0 ; i < t2s->n_pairs; ++i)
+    {
+      double z;
+      double n = ws[i].positives.n + ws[i].negatives.n;
+      variable_pair *vp = &t2s->pairs[i];
+
+      struct string pair_name;
+      ds_init_cstr (&pair_name, var_to_string ((*vp)[0]));
+      ds_put_cstr (&pair_name, " - ");
+      ds_put_cstr (&pair_name, var_to_string ((*vp)[1]));
+
+
+      tab_text (table, 1 + i, 0, TAB_CENTER, ds_cstr (&pair_name));
+      ds_destroy (&pair_name);
+
+      z = MIN (ws[i].positives.sum, ws[i].negatives.sum);
+      z -= n * (n + 1)/ 4.0;
+
+      z /= sqrt (n * (n + 1) * (2*n + 1)/24.0 - ws[i].tiebreaker / 48.0);
+
+      tab_float (table, 1 + i, 1, TAB_RIGHT, z, 8, 3);
+
+      tab_float (table, 1 + i, 2, TAB_RIGHT,
+                2.0 * gsl_cdf_ugaussian_P (z),
+                8, 3);
+
+      if (exact)
+       {
+         double p =
+           timed_wilcoxon_significance (ws[i].positives.sum,
+                                        n,
+                                        timer );
+
+         if ( p == SYSMIS)
+           {
+             msg (MW, _("Exact significance was not calculated after %.2f minutes. Skipping test."), timer);
+           }
+         else
+           {
+             tab_float (table, 1 + i, 3, TAB_RIGHT, p, 8, 3);
+             tab_float (table, 1 + i, 4, TAB_RIGHT, p / 2.0, 8, 3);
+           }
+       }
+    }
+
+  tab_hline (table, TAL_2, 0, table->nc - 1, 1);
+  tab_vline (table, TAL_2, 1, 0, table->nr - 1);
+
+
+  tab_submit (table);
+}
+
+\f
+
+#include <setjmp.h>
+
+static sigjmp_buf env;
+
+static void
+give_up_callback (int signal UNUSED)
+{
+  siglongjmp (env, 1);
+}
+
+static double
+timed_wilcoxon_significance (double w, long int n, double timer)
+{
+  double p = SYSMIS;
+
+  sigset_t set;
+
+  struct sigaction timeout_action;
+  struct sigaction old_action;
+
+  if (timer <= 0 )
+    return LevelOfSignificanceWXMPSR (w, n);
+
+  sigemptyset (&set);
+
+  timeout_action.sa_mask = set;
+  timeout_action.sa_flags = 0;
+
+  timeout_action.sa_handler = give_up_callback;
+
+  if ( 0 == sigsetjmp (env, 1))
+    {
+      sigaction (SIGALRM, &timeout_action, &old_action);
+      alarm (timer * 60.0);
+
+      p = LevelOfSignificanceWXMPSR (w, n);
+    }
+
+  sigaction (SIGALRM, &old_action, NULL);
+
+  return p;
+}
diff --git a/src/language/stats/wilcoxon.h b/src/language/stats/wilcoxon.h
new file mode 100644 (file)
index 0000000..b0f86a2
--- /dev/null
@@ -0,0 +1,65 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#if !wilcoxon_h
+#define wilcoxon_h 1
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <language/stats/npar.h>
+#include <data/case.h>
+
+
+struct rank_sum
+{
+  double n;
+  double sum;
+};
+
+struct wilcoxon_state
+{
+  struct casereader *reader;
+  struct variable *sign;
+  struct variable *absdiff;
+
+  struct rank_sum positives;
+  struct rank_sum negatives;
+  double n_zeros;
+
+  double tiebreaker;
+};
+
+
+struct wilcoxon_test
+{
+  struct two_sample_test parent;
+};
+
+struct casereader;
+struct dataset;
+
+
+void wilcoxon_execute (const struct dataset *ds,
+                      struct casereader *input,
+                      enum mv_class exclude,
+                      const struct npar_test *test,
+                      bool exact,
+                      double timer
+                      );
+
+
+
+#endif
diff --git a/src/language/tests/.gitignore b/src/language/tests/.gitignore
new file mode 100644 (file)
index 0000000..61e8b4e
--- /dev/null
@@ -0,0 +1 @@
+check-model.c
diff --git a/src/language/tests/ChangeLog b/src/language/tests/ChangeLog
deleted file mode 100644 (file)
index d76583f..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6441.  Reviewed by John Darrington.
-
-       * automake.mk: Add new file.
-
-       * format-guesser-test.c: New file.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * automake.mk: Add new file.
-
-       * paper-size.c: New file.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new file.
-
-       * datasheet-test.c: New file.
-
-2007-04-22  Ben Pfaff  <blp@gnu.org>
-
-       Implement model checker for testing purposes.
-       
-       Patch #5873.
-       
-       * automake.mk: Add check-model.[ch].
-
-       * check-model.h: New file.
-
-       * check-model.q: New file.
-
-Thu Oct 26 20:19:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add float-format.c.
-
-       * float-format.c: New file.
-
-Sat Oct 14 16:21:45 2006  Ben Pfaff  <blp@gnu.org>
-
-       * casefile-test.c: (test_casereader_clone) Free cases that we
-       read, to avoid memory leak.
-
-Tue Jun  6 18:48:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * casefile-test.c: (test_casefile) Test the new casereader_seek()
-       function.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/tests/OChangeLog b/src/language/tests/OChangeLog
new file mode 100644 (file)
index 0000000..d76583f
--- /dev/null
@@ -0,0 +1,53 @@
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6441.  Reviewed by John Darrington.
+
+       * automake.mk: Add new file.
+
+       * format-guesser-test.c: New file.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * automake.mk: Add new file.
+
+       * paper-size.c: New file.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new file.
+
+       * datasheet-test.c: New file.
+
+2007-04-22  Ben Pfaff  <blp@gnu.org>
+
+       Implement model checker for testing purposes.
+       
+       Patch #5873.
+       
+       * automake.mk: Add check-model.[ch].
+
+       * check-model.h: New file.
+
+       * check-model.q: New file.
+
+Thu Oct 26 20:19:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add float-format.c.
+
+       * float-format.c: New file.
+
+Sat Oct 14 16:21:45 2006  Ben Pfaff  <blp@gnu.org>
+
+       * casefile-test.c: (test_casereader_clone) Free cases that we
+       read, to avoid memory leak.
+
+Tue Jun  6 18:48:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * casefile-test.c: (test_casefile) Test the new casereader_seek()
+       function.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 5a5423930858afc288105dd3e2d92661a45b492b..54d95107d94794011bb9f184550f8b10ae55c87b 100644 (file)
@@ -6,12 +6,18 @@ language_tests_built_sources = \
 language_tests_sources = \
        src/language/tests/check-model.h \
        src/language/tests/datasheet-test.c \
+       src/language/tests/datasheet-check.c \
+       src/language/tests/datasheet-check.h \
        src/language/tests/format-guesser-test.c \
        src/language/tests/float-format.c \
        src/language/tests/moments-test.c \
+       src/language/tests/model-checker.c \
+       src/language/tests/model-checker.h \
        src/language/tests/paper-size.c \
        src/language/tests/pool-test.c 
 
 all_q_sources += $(language_tests_built_sources:.c=.q)
 EXTRA_DIST += $(language_tests_built_sources:.c=.q)
 CLEANFILES += $(language_tests_built_sources)
+
+EXTRA_DIST += src/language/tests/OChangeLog
index a2654717888d5232f679eacb57190b2284587b50..b1f44ffa6bef06ad0a3e6c927281e6762c6f02c0 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <errno.h>
 
-#include <libpspp/model-checker.h>
+#include <language/tests/model-checker.h>
 #include <language/lexer/lexer.h>
 
 #include "error.h"
diff --git a/src/language/tests/datasheet-check.c b/src/language/tests/datasheet-check.c
new file mode 100644 (file)
index 0000000..b3b2856
--- /dev/null
@@ -0,0 +1,472 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <data/datasheet.h>
+#include "datasheet-check.h"
+#include "model-checker.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <data/casereader-provider.h>
+#include <data/casereader.h>
+#include <data/casewriter.h>
+#include <data/lazy-casereader.h>
+#include <data/sparse-cases.h>
+#include <libpspp/array.h>
+#include <libpspp/assertion.h>
+#include <libpspp/range-map.h>
+#include <libpspp/range-set.h>
+#include <libpspp/taint.h>
+#include <libpspp/tower.h>
+
+#include "minmax.h"
+#include "md4.h"
+#include "xalloc.h"
+
+
+/* lazy_casereader callback function to instantiate a casereader
+   from the datasheet. */
+static struct casereader *
+lazy_callback (void *ds_)
+{
+  struct datasheet *ds = ds_;
+  return datasheet_make_reader (ds);
+}
+
+
+/* Maximum size of datasheet supported for model checking
+   purposes. */
+#define MAX_ROWS 5
+#define MAX_COLS 5
+
+
+/* Checks that READER contains the ROW_CNT rows and COLUMN_CNT
+   columns of data in ARRAY, reporting any errors via MC. */
+static void
+check_datasheet_casereader (struct mc *mc, struct casereader *reader,
+                            double array[MAX_ROWS][MAX_COLS],
+                            size_t row_cnt, size_t column_cnt)
+{
+  if (casereader_get_case_cnt (reader) != row_cnt)
+    {
+      if (casereader_get_case_cnt (reader) == CASENUMBER_MAX
+          && casereader_count_cases (reader) == row_cnt)
+        mc_error (mc, "datasheet casereader has unknown case count");
+      else
+        mc_error (mc, "casereader row count (%lu) does not match "
+                  "expected (%zu)",
+                  (unsigned long int) casereader_get_case_cnt (reader),
+                  row_cnt);
+    }
+  else if (casereader_get_value_cnt (reader) != column_cnt)
+    mc_error (mc, "casereader column count (%zu) does not match "
+              "expected (%zu)",
+              casereader_get_value_cnt (reader), column_cnt);
+  else
+    {
+      struct ccase c;
+      size_t row;
+
+      for (row = 0; row < row_cnt; row++)
+        {
+          size_t col;
+
+          if (!casereader_read (reader, &c))
+            {
+              mc_error (mc, "casereader_read failed reading row %zu of %zu "
+                        "(%zu columns)", row, row_cnt, column_cnt);
+              return;
+            }
+
+          for (col = 0; col < column_cnt; col++)
+            if (case_num_idx (&c, col) != array[row][col])
+              mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: "
+                        "%g != %g",
+                        row, col, row_cnt, column_cnt,
+                        case_num_idx (&c, col), array[row][col]);
+
+         case_destroy (&c);
+        }
+
+      if (casereader_read (reader, &c))
+        mc_error (mc, "casereader has extra cases (expected %zu)", row_cnt);
+    }
+}
+
+/* Checks that datasheet DS contains has ROW_CNT rows, COLUMN_CNT
+   columns, and the same contents as ARRAY, reporting any
+   mismatches via mc_error.  Then, adds DS to MC as a new state. */
+static void
+check_datasheet (struct mc *mc, struct datasheet *ds,
+                 double array[MAX_ROWS][MAX_COLS],
+                 size_t row_cnt, size_t column_cnt)
+{
+  struct datasheet *ds2;
+  struct casereader *reader;
+  unsigned long int serial = 0;
+
+  assert (row_cnt < MAX_ROWS);
+  assert (column_cnt < MAX_COLS);
+
+  /* If it is a duplicate hash, discard the state before checking
+     its consistency, to save time. */
+  if (mc_discard_dup_state (mc, hash_datasheet (ds)))
+    {
+      datasheet_destroy (ds);
+      return;
+    }
+
+  /* Check contents of datasheet via datasheet functions. */
+  if (row_cnt != datasheet_get_row_cnt (ds))
+    mc_error (mc, "row count (%lu) does not match expected (%zu)",
+              (unsigned long int) datasheet_get_row_cnt (ds), row_cnt);
+  else if (column_cnt != datasheet_get_column_cnt (ds))
+    mc_error (mc, "column count (%zu) does not match expected (%zu)",
+              datasheet_get_column_cnt (ds), column_cnt);
+  else
+    {
+      size_t row, col;
+
+      for (row = 0; row < row_cnt; row++)
+        for (col = 0; col < column_cnt; col++)
+          {
+            union value v;
+            if (!datasheet_get_value (ds, row, col, &v, 1))
+              NOT_REACHED ();
+            if (v.f != array[row][col])
+              mc_error (mc, "element %zu,%zu (of %zu,%zu) differs: %g != %g",
+                        row, col, row_cnt, column_cnt, v.f, array[row][col]);
+          }
+    }
+
+  /* Check that datasheet contents are correct when read through
+     casereader. */
+  ds2 = clone_datasheet (ds);
+  reader = datasheet_make_reader (ds2);
+  check_datasheet_casereader (mc, reader, array, row_cnt, column_cnt);
+  casereader_destroy (reader);
+
+  /* Check that datasheet contents are correct when read through
+     casereader with lazy_casereader wrapped around it.  This is
+     valuable because otherwise there is no non-GUI code that
+     uses the lazy_casereader. */
+  ds2 = clone_datasheet (ds);
+  reader = lazy_casereader_create (column_cnt, row_cnt,
+                                   lazy_callback, ds2, &serial);
+  check_datasheet_casereader (mc, reader, array, row_cnt, column_cnt);
+  if (lazy_casereader_destroy (reader, serial))
+    {
+      /* Lazy casereader was never instantiated.  This will
+         only happen if there are no rows (because in that case
+         casereader_read never gets called). */
+      datasheet_destroy (ds2);
+      if (row_cnt != 0)
+        mc_error (mc, "lazy casereader not instantiated, but should "
+                  "have been (size %zu,%zu)", row_cnt, column_cnt);
+    }
+  else
+    {
+      /* Lazy casereader was instantiated.  This is the common
+         case, in which some casereader operation
+         (casereader_read in this case) was performed on the
+         lazy casereader. */
+      casereader_destroy (reader);
+      if (row_cnt == 0)
+        mc_error (mc, "lazy casereader instantiated, but should not "
+                  "have been (size %zu,%zu)", row_cnt, column_cnt);
+    }
+
+  mc_add_state (mc, ds);
+}
+
+/* Extracts the contents of DS into DATA. */
+static void
+extract_data (const struct datasheet *ds, double data[MAX_ROWS][MAX_COLS])
+{
+  size_t column_cnt = datasheet_get_column_cnt (ds);
+  size_t row_cnt = datasheet_get_row_cnt (ds);
+  size_t row, col;
+
+  assert (row_cnt < MAX_ROWS);
+  assert (column_cnt < MAX_COLS);
+  for (row = 0; row < row_cnt; row++)
+    for (col = 0; col < column_cnt; col++)
+      {
+        union value v;
+        if (!datasheet_get_value (ds, row, col, &v, 1))
+          NOT_REACHED ();
+        data[row][col] = v.f;
+      }
+}
+
+/* Clones the structure and contents of ODS into *DS,
+   and the contents of ODATA into DATA. */
+static void
+clone_model (const struct datasheet *ods, double odata[MAX_ROWS][MAX_COLS],
+             struct datasheet **ds, double data[MAX_ROWS][MAX_COLS])
+{
+  *ds = clone_datasheet (ods);
+  memcpy (data, odata, MAX_ROWS * MAX_COLS * sizeof **data);
+}
+
+/* "init" function for struct mc_class. */
+static void
+datasheet_mc_init (struct mc *mc)
+{
+  struct datasheet_test_params *params = mc_get_aux (mc);
+  struct datasheet *ds;
+
+  if (params->backing_rows == 0 && params->backing_cols == 0)
+    {
+      /* Create unbacked datasheet. */
+      ds = datasheet_create (NULL);
+      mc_name_operation (mc, "empty datasheet");
+      check_datasheet (mc, ds, NULL, 0, 0);
+    }
+  else
+    {
+      /* Create datasheet with backing. */
+      struct casewriter *writer;
+      struct casereader *reader;
+      double data[MAX_ROWS][MAX_COLS];
+      int row;
+
+      assert (params->backing_rows > 0 && params->backing_rows <= MAX_ROWS);
+      assert (params->backing_cols > 0 && params->backing_cols <= MAX_COLS);
+
+      writer = mem_writer_create (params->backing_cols);
+      for (row = 0; row < params->backing_rows; row++)
+        {
+          struct ccase c;
+          int col;
+
+          case_create (&c, params->backing_cols);
+          for (col = 0; col < params->backing_cols; col++)
+            {
+              double value = params->next_value++;
+              data[row][col] = value;
+              case_data_rw_idx (&c, col)->f = value;
+            }
+          casewriter_write (writer, &c);
+        }
+      reader = casewriter_make_reader (writer);
+      assert (reader != NULL);
+
+      ds = datasheet_create (reader);
+      mc_name_operation (mc, "datasheet with (%d,%d) backing",
+                         params->backing_rows, params->backing_cols);
+      check_datasheet (mc, ds, data,
+                       params->backing_rows, params->backing_cols);
+    }
+}
+
+/* "mutate" function for struct mc_class. */
+static void
+datasheet_mc_mutate (struct mc *mc, const void *ods_)
+{
+  struct datasheet_test_params *params = mc_get_aux (mc);
+
+  const struct datasheet *ods = ods_;
+  double odata[MAX_ROWS][MAX_COLS];
+  double data[MAX_ROWS][MAX_COLS];
+  size_t column_cnt = datasheet_get_column_cnt (ods);
+  size_t row_cnt = datasheet_get_row_cnt (ods);
+  size_t pos, new_pos, cnt;
+
+  extract_data (ods, odata);
+
+  /* Insert all possible numbers of columns in all possible
+     positions. */
+  for (pos = 0; pos <= column_cnt; pos++)
+    for (cnt = 0; cnt <= params->max_cols - column_cnt; cnt++)
+      if (mc_include_state (mc))
+        {
+          struct datasheet *ds;
+          union value new[MAX_COLS];
+          size_t i, j;
+
+          mc_name_operation (mc, "insert %zu columns at %zu", cnt, pos);
+          clone_model (ods, odata, &ds, data);
+
+          for (i = 0; i < cnt; i++)
+            new[i].f = params->next_value++;
+
+          if (!datasheet_insert_columns (ds, new, cnt, pos))
+            mc_error (mc, "datasheet_insert_columns failed");
+
+          for (i = 0; i < row_cnt; i++)
+            {
+              insert_range (&data[i][0], column_cnt, sizeof data[i][0],
+                            pos, cnt);
+              for (j = 0; j < cnt; j++)
+                data[i][pos + j] = new[j].f;
+            }
+
+          check_datasheet (mc, ds, data, row_cnt, column_cnt + cnt);
+        }
+
+  /* Delete all possible numbers of columns from all possible
+     positions. */
+  for (pos = 0; pos < column_cnt; pos++)
+    for (cnt = 0; cnt < column_cnt - pos; cnt++)
+      if (mc_include_state (mc))
+        {
+          struct datasheet *ds;
+          size_t i;
+
+          mc_name_operation (mc, "delete %zu columns at %zu", cnt, pos);
+          clone_model (ods, odata, &ds, data);
+
+          datasheet_delete_columns (ds, pos, cnt);
+
+          for (i = 0; i < row_cnt; i++)
+            remove_range (&data[i], column_cnt, sizeof *data[i], pos, cnt);
+
+          check_datasheet (mc, ds, data, row_cnt, column_cnt - cnt);
+        }
+
+  /* Move all possible numbers of columns from all possible
+     existing positions to all possible new positions. */
+  for (pos = 0; pos < column_cnt; pos++)
+    for (cnt = 0; cnt < column_cnt - pos; cnt++)
+      for (new_pos = 0; new_pos < column_cnt - cnt; new_pos++)
+        if (mc_include_state (mc))
+          {
+            struct datasheet *ds;
+            size_t i;
+
+            clone_model (ods, odata, &ds, data);
+            mc_name_operation (mc, "move %zu columns from %zu to %zu",
+                               cnt, pos, new_pos);
+
+            datasheet_move_columns (ds, pos, new_pos, cnt);
+
+            for (i = 0; i < row_cnt; i++)
+              move_range (&data[i], column_cnt, sizeof data[i][0],
+                          pos, new_pos, cnt);
+
+            check_datasheet (mc, ds, data, row_cnt, column_cnt);
+          }
+
+  /* Insert all possible numbers of rows in all possible
+     positions. */
+  for (pos = 0; pos <= row_cnt; pos++)
+    for (cnt = 0; cnt <= params->max_rows - row_cnt; cnt++)
+      if (mc_include_state (mc))
+        {
+          struct datasheet *ds;
+          struct ccase c[MAX_ROWS];
+          size_t i, j;
+
+          clone_model (ods, odata, &ds, data);
+          mc_name_operation (mc, "insert %zu rows at %zu", cnt, pos);
+
+          for (i = 0; i < cnt; i++)
+            {
+              case_create (&c[i], column_cnt);
+              for (j = 0; j < column_cnt; j++)
+                case_data_rw_idx (&c[i], j)->f = params->next_value++;
+            }
+
+          insert_range (data, row_cnt, sizeof data[pos], pos, cnt);
+          for (i = 0; i < cnt; i++)
+            for (j = 0; j < column_cnt; j++)
+              data[i + pos][j] = case_num_idx (&c[i], j);
+
+          if (!datasheet_insert_rows (ds, pos, c, cnt))
+            mc_error (mc, "datasheet_insert_rows failed");
+
+          check_datasheet (mc, ds, data, row_cnt + cnt, column_cnt);
+        }
+
+  /* Delete all possible numbers of rows from all possible
+     positions. */
+  for (pos = 0; pos < row_cnt; pos++)
+    for (cnt = 0; cnt < row_cnt - pos; cnt++)
+      if (mc_include_state (mc))
+        {
+          struct datasheet *ds;
+
+          clone_model (ods, odata, &ds, data);
+          mc_name_operation (mc, "delete %zu rows at %zu", cnt, pos);
+
+          datasheet_delete_rows (ds, pos, cnt);
+
+          remove_range (&data[0], row_cnt, sizeof data[0], pos, cnt);
+
+          check_datasheet (mc, ds, data, row_cnt - cnt, column_cnt);
+        }
+
+  /* Move all possible numbers of rows from all possible existing
+     positions to all possible new positions. */
+  for (pos = 0; pos < row_cnt; pos++)
+    for (cnt = 0; cnt < row_cnt - pos; cnt++)
+      for (new_pos = 0; new_pos < row_cnt - cnt; new_pos++)
+        if (mc_include_state (mc))
+          {
+            struct datasheet *ds;
+
+            clone_model (ods, odata, &ds, data);
+            mc_name_operation (mc, "move %zu rows from %zu to %zu",
+                               cnt, pos, new_pos);
+
+            datasheet_move_rows (ds, pos, new_pos, cnt);
+
+            move_range (&data[0], row_cnt, sizeof data[0],
+                        pos, new_pos, cnt);
+
+            check_datasheet (mc, ds, data, row_cnt, column_cnt);
+          }
+}
+
+/* "destroy" function for struct mc_class. */
+static void
+datasheet_mc_destroy (const struct mc *mc UNUSED, void *ds_)
+{
+  struct datasheet *ds = ds_;
+  datasheet_destroy (ds);
+}
+
+/* Executes the model checker on the datasheet test driver with
+   the given OPTIONS and passing in the given PARAMS, which must
+   point to a modifiable "struct datasheet_test_params".  If any
+   value in PARAMS is out of range, it will be adjusted into the
+   valid range before running the test.
+
+   Returns the results of the model checking run. */
+struct mc_results *
+datasheet_test (struct mc_options *options, void *params_)
+{
+  struct datasheet_test_params *params = params_;
+  static const struct mc_class datasheet_mc_class =
+    {
+      datasheet_mc_init,
+      datasheet_mc_mutate,
+      datasheet_mc_destroy,
+    };
+
+  params->next_value = 1;
+  params->max_rows = MIN (params->max_rows, MAX_ROWS);
+  params->max_cols = MIN (params->max_cols, MAX_COLS);
+  params->backing_rows = MIN (params->backing_rows, params->max_rows);
+  params->backing_cols = MIN (params->backing_cols, params->max_cols);
+
+  mc_options_set_aux (options, params);
+  return mc_run (&datasheet_mc_class, options);
+}
diff --git a/src/language/tests/datasheet-check.h b/src/language/tests/datasheet-check.h
new file mode 100644 (file)
index 0000000..bd0e492
--- /dev/null
@@ -0,0 +1,89 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef DATA_DATASHEET_TEST_H
+#define DATA_DATASHEET_TEST_H 1
+
+#if 0
+#include <data/case.h>
+#include <data/value.h>
+
+struct casereader;
+
+/* A datasheet is a 2-d array of data that may be stored in
+   memory or on disk.  It efficiently supports data storage and
+   retrieval, as well as adding, removing, and rearranging both
+   rows and columns.  */
+
+struct datasheet *datasheet_create (struct casereader *);
+void datasheet_destroy (struct datasheet *);
+struct datasheet *datasheet_rename (struct datasheet *);
+
+bool datasheet_error (const struct datasheet *);
+void datasheet_force_error (struct datasheet *);
+const struct taint *datasheet_get_taint (const struct datasheet *);
+
+struct casereader *datasheet_make_reader (struct datasheet *);
+
+/* Columns. */
+size_t datasheet_get_column_cnt (const struct datasheet *);
+bool datasheet_insert_columns (struct datasheet *,
+                               const union value[], size_t cnt,
+                               size_t before);
+void datasheet_delete_columns (struct datasheet *, size_t start, size_t cnt);
+void datasheet_move_columns (struct datasheet *,
+                             size_t old_start, size_t new_start,
+                             size_t cnt);
+
+/* Rows. */
+casenumber datasheet_get_row_cnt (const struct datasheet *);
+bool datasheet_insert_rows (struct datasheet *,
+                            casenumber before, struct ccase[],
+                            casenumber cnt);
+void datasheet_delete_rows (struct datasheet *,
+                            casenumber first, casenumber cnt);
+void datasheet_move_rows (struct datasheet *,
+                          size_t old_start, size_t new_start,
+                          size_t cnt);
+
+/* Data. */
+bool datasheet_get_row (const struct datasheet *, casenumber, struct ccase *);
+bool datasheet_put_row (struct datasheet *, casenumber, struct ccase *);
+bool datasheet_get_value (const struct datasheet *, casenumber, size_t column,
+                          union value *, int width);
+bool datasheet_put_value (struct datasheet *, casenumber, size_t column,
+                          const union value *, int width);
+
+#endif
+
+/* Testing. */
+struct mc_options;
+
+struct datasheet_test_params
+  {
+    /* Parameters. */
+    int max_rows;
+    int max_cols;
+    int backing_rows;
+    int backing_cols;
+
+    /* State. */
+    int next_value;
+  };
+
+struct mc_results *datasheet_test (struct mc_options *options, void *params);
+
+#endif /* data/datasheet.h */
index 67f68377e14ed987fc42671ba55989ef4510aee5..dfe8b6b2f0a4b1a341412522a5f6f579d0f8fa33 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <config.h>
 
-#include <data/datasheet.h>
+#include "datasheet-check.h"
 
 #include <language/command.h>
 #include <language/lexer/lexer.h>
@@ -49,6 +49,7 @@ cmd_debug_datasheet (struct lexer *lexer, struct dataset *dataset UNUSED)
   params.backing_rows = 0;
   params.backing_cols = 0;
 
+
   for (;;)
     {
       if (lex_match_id (lexer, "MAX"))
diff --git a/src/language/tests/model-checker.c b/src/language/tests/model-checker.c
new file mode 100644 (file)
index 0000000..a040750
--- /dev/null
@@ -0,0 +1,1466 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include "model-checker.h"
+
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <data/val-type.h>
+#include <libpspp/bit-vector.h>
+#include <libpspp/compiler.h>
+#include <libpspp/deque.h>
+#include <libpspp/str.h>
+#include <math/moments.h>
+
+#include "error.h"
+#include "minmax.h"
+#include "xalloc.h"
+\f
+/* Initializes PATH as an empty path. */
+void
+mc_path_init (struct mc_path *path)
+{
+  path->ops = NULL;
+  path->length = 0;
+  path->capacity = 0;
+}
+
+/* Copies the contents of OLD into NEW. */
+void
+mc_path_copy (struct mc_path *new, const struct mc_path *old)
+{
+  if (old->length > new->capacity)
+    {
+      new->capacity = old->length;
+      free (new->ops);
+      new->ops = xnmalloc (new->capacity, sizeof *new->ops);
+    }
+  new->length = old->length;
+  memcpy (new->ops, old->ops, old->length * sizeof *new->ops);
+}
+
+/* Adds OP to the end of PATH. */
+void
+mc_path_push (struct mc_path *path, int op)
+{
+  if (path->length >= path->capacity)
+    path->ops = xnrealloc (path->ops, ++path->capacity, sizeof *path->ops);
+  path->ops[path->length++] = op;
+}
+
+/* Removes and returns the operation at the end of PATH. */
+int
+mc_path_pop (struct mc_path *path)
+{
+  int back = mc_path_back (path);
+  path->length--;
+  return back;
+}
+
+/* Returns the operation at the end of PATH. */
+int
+mc_path_back (const struct mc_path *path)
+{
+  assert (path->length > 0);
+  return path->ops[path->length - 1];
+}
+
+/* Destroys PATH. */
+void
+mc_path_destroy (struct mc_path *path)
+{
+  free (path->ops);
+  path->ops = NULL;
+}
+
+/* Returns the operation in position INDEX in PATH.
+   INDEX must be less than the length of PATH. */
+int
+mc_path_get_operation (const struct mc_path *path, size_t index)
+{
+  assert (index < path->length);
+  return path->ops[index];
+}
+
+/* Returns the number of operations in PATH. */
+size_t
+mc_path_get_length (const struct mc_path *path)
+{
+  return path->length;
+}
+
+/* Appends the operations in PATH to STRING, separating each one
+   with a single space. */
+void
+mc_path_to_string (const struct mc_path *path, struct string *string)
+{
+  size_t i;
+
+  for (i = 0; i < mc_path_get_length (path); i++)
+    {
+      if (i > 0)
+        ds_put_char (string, ' ');
+      ds_put_format (string, "%d", mc_path_get_operation (path, i));
+    }
+}
+\f
+/* Search options. */
+struct mc_options
+  {
+    /* Search strategy. */
+    enum mc_strategy strategy;          /* Type of strategy. */
+    int max_depth;                      /* Limit on depth (or INT_MAX). */
+    int hash_bits;                      /* Number of bits to hash (or 0). */
+    unsigned int seed;                  /* Random seed for MC_RANDOM
+                                           or MC_DROP_RANDOM. */
+    struct mc_path follow_path;         /* Path for MC_PATH. */
+
+    /* Queue configuration. */
+    int queue_limit;                    /* Maximum length of queue. */
+    enum mc_queue_limit_strategy queue_limit_strategy;
+                                        /* How to choose state to drop
+                                           from queue. */
+
+    /* Stop conditions. */
+    int max_unique_states;              /* Maximum unique states to process. */
+    int max_errors;                     /* Maximum errors to detect. */
+    double time_limit;                  /* Maximum time in seconds. */
+
+    /* Output configuration. */
+    int verbosity;                      /* 0=low, 1=normal, 2+=high. */
+    int failure_verbosity;              /* If greater than verbosity,
+                                           verbosity of error replays. */
+    FILE *output_file;                  /* File to receive output. */
+
+    /* How to report intermediate progress. */
+    int progress_usec;                  /* Microseconds between reports. */
+    mc_progress_func *progress_func;    /* Function to call on each report. */
+
+    /* Client data. */
+    void *aux;
+  };
+
+/* Default progress function. */
+static bool
+default_progress (struct mc *mc)
+{
+  if (mc_results_get_stop_reason (mc_get_results (mc)) == MC_CONTINUING)
+    putc ('.', stderr);
+  else
+    putc ('\n', stderr);
+  return true;
+}
+
+/* Do-nothing progress function. */
+static bool
+null_progress (struct mc *mc UNUSED)
+{
+  return true;
+}
+
+/* Creates and returns a set of options initialized to the
+   defaults. */
+struct mc_options *
+mc_options_create (void)
+{
+  struct mc_options *options = xmalloc (sizeof *options);
+
+  options->strategy = MC_BROAD;
+  options->max_depth = INT_MAX;
+  options->hash_bits = 20;
+  options->seed = 0;
+  mc_path_init (&options->follow_path);
+
+  options->queue_limit = 10000;
+  options->queue_limit_strategy = MC_DROP_RANDOM;
+
+  options->max_unique_states = INT_MAX;
+  options->max_errors = 1;
+  options->time_limit = 0.0;
+
+  options->verbosity = 1;
+  options->failure_verbosity = 2;
+  options->output_file = stdout;
+  options->progress_usec = 250000;
+  options->progress_func = default_progress;
+
+  options->aux = NULL;
+
+  return options;
+}
+
+/* Returns a copy of the given OPTIONS. */
+struct mc_options *
+mc_options_clone (const struct mc_options *options)
+{
+  return xmemdup (options, sizeof *options);
+}
+
+/* Destroys OPTIONS. */
+void
+mc_options_destroy (struct mc_options *options)
+{
+  mc_path_destroy (&options->follow_path);
+  free (options);
+}
+
+/* Returns the search strategy used for OPTIONS.  The choices
+   are:
+
+   - MC_BROAD (the default): Breadth-first search.  First tries
+     all the operations with depth 1, then those with depth 2,
+     then those with depth 3, and so on.
+
+     This search algorithm finds the least number of operations
+     needed to trigger a given bug.
+
+   - MC_DEEP: Depth-first search.  Searches downward in the tree
+     of states as fast as possible.  Good for finding bugs that
+     require long sequences of operations to trigger.
+
+   - MC_RANDOM: Random-first search.  Searches through the tree
+     of states in random order.  The standard C library's rand
+     function selects the search path; you can control the seed
+     passed to srand using mc_options_set_seed.
+
+   - MC_PATH: Explicit path.  Applies an explicitly specified
+     sequence of operations. */
+enum mc_strategy
+mc_options_get_strategy (const struct mc_options *options)
+{
+  return options->strategy;
+}
+
+/* Sets the search strategy used for OPTIONS to STRATEGY.
+
+   This function cannot be used to set MC_PATH as the search
+   strategy.  Use mc_options_set_follow_path instead. */
+void
+mc_options_set_strategy (struct mc_options *options, enum mc_strategy strategy)
+{
+  assert (strategy == MC_BROAD
+          || strategy == MC_DEEP
+          || strategy == MC_RANDOM);
+  options->strategy = strategy;
+}
+
+/* Returns OPTION's random seed used by MC_RANDOM and
+   MC_DROP_RANDOM. */
+unsigned int
+mc_options_get_seed (const struct mc_options *options)
+{
+  return options->seed;
+}
+
+/* Set OPTION's random seed used by MC_RANDOM and MC_DROP_RANDOM
+   to SEED. */
+void
+mc_options_set_seed (struct mc_options *options, unsigned int seed)
+{
+  options->seed = seed;
+}
+
+/* Returns the maximum depth to which OPTIONS's search will
+   descend.  The initial states are at depth 1, states produced
+   as their mutations are at depth 2, and so on. */
+int
+mc_options_get_max_depth (const struct mc_options *options)
+{
+  return options->max_depth;
+}
+
+/* Sets the maximum depth to which OPTIONS's search will descend
+   to MAX_DEPTH.  The initial states are at depth 1, states
+   produced as their mutations are at depth 2, and so on. */
+void
+mc_options_set_max_depth (struct mc_options *options, int max_depth)
+{
+  options->max_depth = max_depth;
+}
+
+/* Returns the base-2 log of the number of bits in OPTIONS's hash
+   table.  The hash table is used for dropping states that are
+   probably duplicates: any state with a given hash value, as
+   will only be processed once.  A return value of 0 indicates
+   that the model checker will not discard duplicate states based
+   on their hashes.
+
+   The hash table is a power of 2 bits long, by default 2**20
+   bits (128 kB).  Depending on how many states you expect the
+   model checker to check, how much memory you're willing to let
+   the hash table take up, and how worried you are about missing
+   states due to hash collisions, you could make it larger or
+   smaller.
+
+   The "birthday paradox" points to a reasonable way to size your
+   hash table.  If you expect the model checker to check about
+   2**N states, then, assuming a perfect hash, you need a hash
+   table of 2**(N+1) bits to have a 50% chance of seeing a hash
+   collision, 2**(N+2) bits to have a 25% chance, and so on. */
+int
+mc_options_get_hash_bits (const struct mc_options *options)
+{
+  return options->hash_bits;
+}
+
+/* Sets the base-2 log of the number of bits in OPTIONS's hash
+   table to HASH_BITS.  A HASH_BITS value of 0 requests that the
+   model checker not discard duplicate states based on their
+   hashes.  (This causes the model checker to never terminate in
+   many cases.) */
+void
+mc_options_set_hash_bits (struct mc_options *options, int hash_bits)
+{
+  assert (hash_bits >= 0);
+  options->hash_bits = MIN (hash_bits, CHAR_BIT * sizeof (unsigned int) - 1);
+}
+
+/* Returns the path set in OPTIONS by mc_options_set_follow_path.
+   May be used only if the search strategy is MC_PATH. */
+const struct mc_path *
+mc_options_get_follow_path (const struct mc_options *options)
+{
+  assert (options->strategy == MC_PATH);
+  return &options->follow_path;
+}
+
+/* Sets, in OPTIONS, the search algorithm to MC_PATH and the path
+   to be the explicit path specified in FOLLOW_PATH. */
+void
+mc_options_set_follow_path (struct mc_options *options,
+                            const struct mc_path *follow_path)
+{
+  assert (mc_path_get_length (follow_path) > 0);
+  options->strategy = MC_PATH;
+  mc_path_copy (&options->follow_path, follow_path);
+}
+
+/* Returns the maximum number of queued states in OPTIONS.  The
+   default value is 10,000.  The primary reason to limit the
+   number of queued states is to conserve memory, so if you can
+   afford the memory and your model needs more room in the queue,
+   you can raise the limit.  Conversely, if your models are large
+   or memory is constrained, you can reduce the limit.
+
+   Following the execution of the model checker, you can find out
+   the maximum queue length during the run by calling
+   mc_results_get_max_queue_length. */
+int
+mc_options_get_queue_limit (const struct mc_options *options)
+{
+  return options->queue_limit;
+}
+
+/* Sets the maximum number of queued states in OPTIONS to
+   QUEUE_LIMIT.  */
+void
+mc_options_set_queue_limit (struct mc_options *options, int queue_limit)
+{
+  assert (queue_limit > 0);
+  options->queue_limit = queue_limit;
+}
+
+/* Returns the queue limit strategy used by OPTIONS, that is,
+   when a new state must be inserted into a full state queue is
+   full, how the state to be dropped is chosen.  The choices are:
+
+   - MC_DROP_NEWEST: Drop the newest state; that is, do not
+     insert the new state into the queue at all.
+
+   - MC_DROP_OLDEST: Drop the state that has been enqueued for
+     the longest.
+
+   - MC_DROP_RANDOM (the default): Drop a randomly selected state
+     from the queue.  The standard C library's rand function
+     selects the state to drop; you can control the seed passed
+     to srand using mc_options_set_seed. */
+enum mc_queue_limit_strategy
+mc_options_get_queue_limit_strategy (const struct mc_options *options)
+{
+  return options->queue_limit_strategy;
+}
+
+/* Sets the queue limit strategy used by OPTIONS to STRATEGY.
+
+   This setting has no effect unless the model being checked
+   causes the state queue to overflow (see
+   mc_options_get_queue_limit). */
+void
+mc_options_set_queue_limit_strategy (struct mc_options *options,
+                                     enum mc_queue_limit_strategy strategy)
+{
+  assert (strategy == MC_DROP_NEWEST
+          || strategy == MC_DROP_OLDEST
+          || strategy == MC_DROP_RANDOM);
+  options->queue_limit_strategy = strategy;
+}
+
+/* Returns OPTIONS's maximum number of unique states that the
+   model checker will examine before terminating.  The default is
+   INT_MAX. */
+int
+mc_options_get_max_unique_states (const struct mc_options *options)
+{
+  return options->max_unique_states;
+}
+
+/* Sets OPTIONS's maximum number of unique states that the model
+   checker will examine before terminating to
+   MAX_UNIQUE_STATE. */
+void
+mc_options_set_max_unique_states (struct mc_options *options,
+                                  int max_unique_states)
+{
+  options->max_unique_states = max_unique_states;
+}
+
+/* Returns the maximum number of errors that OPTIONS will allow
+   the model checker to encounter before terminating.  The
+   default is 1. */
+int
+mc_options_get_max_errors (const struct mc_options *options)
+{
+  return options->max_errors;
+}
+
+/* Sets the maximum number of errors that OPTIONS will allow the
+   model checker to encounter before terminating to
+   MAX_ERRORS. */
+void
+mc_options_set_max_errors (struct mc_options *options, int max_errors)
+{
+  options->max_errors = max_errors;
+}
+
+/* Returns the maximum amount of time, in seconds, that OPTIONS will allow the
+   model checker to consume before terminating.  The
+   default of 0.0 means that time consumption is unlimited. */
+double
+mc_options_get_time_limit (const struct mc_options *options)
+{
+  return options->time_limit;
+}
+
+/* Sets the maximum amount of time, in seconds, that OPTIONS will
+   allow the model checker to consume before terminating to
+   TIME_LIMIT.  A value of 0.0 means that time consumption is
+   unlimited; otherwise, the return value will be positive. */
+void
+mc_options_set_time_limit (struct mc_options *options, double time_limit)
+{
+  assert (time_limit >= 0.0);
+  options->time_limit = time_limit;
+}
+
+/* Returns the level of verbosity for output messages specified
+   by OPTIONS.  The default verbosity level is 1.
+
+   A verbosity level of 0 inhibits all messages except for
+   errors; a verbosity level of 1 also allows warnings; a
+   verbosity level of 2 also causes a description of each state
+   added to be output; a verbosity level of 3 also causes a
+   description of each duplicate state to be output.  Verbosity
+   levels less than 0 or greater than 3 are allowed but currently
+   have no additional effect. */
+int
+mc_options_get_verbosity (const struct mc_options *options)
+{
+  return options->verbosity;
+}
+
+/* Sets the level of verbosity for output messages specified
+   by OPTIONS to VERBOSITY. */
+void
+mc_options_set_verbosity (struct mc_options *options, int verbosity)
+{
+  options->verbosity = verbosity;
+}
+
+/* Returns the level of verbosity for failures specified by
+   OPTIONS.  The default failure verbosity level is 2.
+
+   The failure verbosity level has an effect only when an error
+   is reported, and only when the failure verbosity level is
+   higher than the regular verbosity level.  When this is the
+   case, the model checker replays the error path at the higher
+   verbosity level specified.  This has the effect of outputting
+   an explicit, human-readable description of the sequence of
+   operations that caused the error. */
+int
+mc_options_get_failure_verbosity (const struct mc_options *options)
+{
+  return options->failure_verbosity;
+}
+
+/* Sets the level of verbosity for failures specified by OPTIONS
+   to FAILURE_VERBOSITY. */
+void
+mc_options_set_failure_verbosity (struct mc_options *options,
+                                  int failure_verbosity)
+{
+  options->failure_verbosity = failure_verbosity;
+}
+
+/* Returns the output file used for messages printed by the model
+   checker specified by OPTIONS.  The default is stdout. */
+FILE *
+mc_options_get_output_file (const struct mc_options *options)
+{
+  return options->output_file;
+}
+
+/* Sets the output file used for messages printed by the model
+   checker specified by OPTIONS to OUTPUT_FILE.
+
+   The model checker does not automatically close the specified
+   output file.  If this is desired, the model checker's client
+   must do so. */
+void
+mc_options_set_output_file (struct mc_options *options,
+                            FILE *output_file)
+{
+  options->output_file = output_file;
+}
+
+/* Returns the number of microseconds between calls to the
+   progress function specified by OPTIONS.   The default is
+   250,000 (1/4 second).  A value of 0 disables progress
+   reporting. */
+int
+mc_options_get_progress_usec (const struct mc_options *options)
+{
+  return options->progress_usec;
+}
+
+/* Sets the number of microseconds between calls to the progress
+   function specified by OPTIONS to PROGRESS_USEC.  A value of 0
+   disables progress reporting. */
+void
+mc_options_set_progress_usec (struct mc_options *options, int progress_usec)
+{
+  assert (progress_usec >= 0);
+  options->progress_usec = progress_usec;
+}
+
+/* Returns the function called to report progress specified by
+   OPTIONS.  The function used by default prints '.' to
+   stderr. */
+mc_progress_func *
+mc_options_get_progress_func (const struct mc_options *options)
+{
+  return options->progress_func;
+}
+
+/* Sets the function called to report progress specified by
+   OPTIONS to PROGRESS_FUNC.  A non-null function must be
+   specified; to disable progress reporting, set the progress
+   reporting interval to 0.
+
+   PROGRESS_FUNC will be called zero or more times while the
+   model checker's run is ongoing.  For these calls to the
+   progress function, mc_results_get_stop_reason will return
+   MC_CONTINUING.  It will also be called exactly once soon
+   before mc_run returns, in which case
+   mc_results_get_stop_reason will return a different value. */
+void
+mc_options_set_progress_func (struct mc_options *options,
+                              mc_progress_func *progress_func)
+{
+  assert (options->progress_func != NULL);
+  options->progress_func = progress_func;
+}
+
+/* Returns the auxiliary data set in OPTIONS by the client.  The
+   default is a null pointer.
+
+   This auxiliary data value can be retrieved by the
+   client-specified functions in struct mc_class during a model
+   checking run using mc_get_aux. */
+void *
+mc_options_get_aux (const struct mc_options *options)
+{
+  return options->aux;
+}
+
+/* Sets the auxiliary data in OPTIONS to AUX. */
+void
+mc_options_set_aux (struct mc_options *options, void *aux)
+{
+  options->aux = aux;
+}
+\f
+/* Results of a model checking run. */
+struct mc_results
+  {
+    /* Overall results. */
+    enum mc_stop_reason stop_reason;    /* Why the run ended. */
+    int unique_state_count;             /* Number of unique states checked. */
+    int error_count;                    /* Number of errors found. */
+
+    /* Depth statistics. */
+    int max_depth_reached;              /* Max depth state examined. */
+    struct moments1 *depth_moments;     /* Enables reporting mean depth. */
+
+    /* If error_count > 0, path to the last error reported. */
+    struct mc_path error_path;
+
+    /* States dropped... */
+    int duplicate_dropped_states;       /* ...as duplicates. */
+    int off_path_dropped_states;        /* ...as off-path (MC_PATH only). */
+    int depth_dropped_states;           /* ...due to excessive depth. */
+    int queue_dropped_states;           /* ...due to queue overflow. */
+
+    /* Queue statistics. */
+    int queued_unprocessed_states;      /* Enqueued but never dequeued. */
+    int max_queue_length;               /* Maximum queue length observed. */
+
+    /* Timing. */
+    struct timeval start;               /* Start of model checking run. */
+    struct timeval end;                 /* End of model checking run. */
+  };
+
+/* Creates, initializes, and returns a new set of results. */
+static struct mc_results *
+mc_results_create (void)
+{
+  struct mc_results *results = xcalloc (1, sizeof (struct mc_results));
+  results->stop_reason = MC_CONTINUING;
+  results->depth_moments = moments1_create (MOMENT_MEAN);
+  gettimeofday (&results->start, NULL);
+  return results;
+}
+
+/* Destroys RESULTS. */
+void
+mc_results_destroy (struct mc_results *results)
+{
+  if (results != NULL)
+    {
+      moments1_destroy (results->depth_moments);
+      mc_path_destroy (&results->error_path);
+      free (results);
+    }
+}
+
+/* Returns RESULTS's reason that the model checking run
+   terminated.  The possible reasons are:
+
+   - MC_CONTINUING: The run is not actually yet complete.  This
+     can only be returned before mc_run has returned, e.g. when
+     the progress function set by mc_options_set_progress_func
+     examines the run's results.
+
+   - MC_SUCCESS: The run completed because the queue emptied.
+     The entire state space might not have been explored due to a
+     requested limit on maximum depth, hash collisions, etc.
+
+   - MC_MAX_UNIQUE_STATES: The run completed because as many
+     unique states have been checked as were requested (using
+     mc_options_set_max_unique_states).
+
+   - MC_MAX_ERROR_COUNT: The run completed because the maximum
+     requested number of errors (by default, 1 error) was
+     reached.
+
+   - MC_END_OF_PATH: The run completed because the path specified
+     with mc_options_set_follow_path was fully traversed.
+
+   - MC_TIMEOUT: The run completed because the time limit set
+     with mc_options_set_time_limit was exceeded.
+
+   - MC_INTERRUPTED: The run completed because SIGINT was caught
+     (typically, due to the user typing Ctrl+C). */
+enum mc_stop_reason
+mc_results_get_stop_reason (const struct mc_results *results)
+{
+  return results->stop_reason;
+}
+
+/* Returns the number of unique states checked specified by
+   RESULTS. */
+int
+mc_results_get_unique_state_count (const struct mc_results *results)
+{
+  return results->unique_state_count;
+}
+
+/* Returns the number of errors found specified by RESULTS. */
+int
+mc_results_get_error_count (const struct mc_results *results)
+{
+  return results->error_count;
+}
+
+/* Returns the maximum depth reached during the model checker run
+   represented by RESULTS.  The initial states are at depth 1,
+   their child states at depth 2, and so on. */
+int
+mc_results_get_max_depth_reached (const struct mc_results *results)
+{
+  return results->max_depth_reached;
+}
+
+/* Returns the mean depth reached during the model checker run
+   represented by RESULTS. */
+double
+mc_results_get_mean_depth_reached (const struct mc_results *results)
+{
+  double mean;
+  moments1_calculate (results->depth_moments, NULL, &mean, NULL, NULL, NULL);
+  return mean != SYSMIS ? mean : 0.0;
+}
+
+/* Returns the path traversed to obtain the last error
+   encountered during the model checker run represented by
+   RESULTS.  Returns a null pointer if the run did not report any
+   errors. */
+const struct mc_path *
+mc_results_get_error_path (const struct mc_results *results)
+{
+  return results->error_count > 0 ? &results->error_path : NULL;
+}
+
+/* Returns the number of states dropped as duplicates (based on
+   hash value) during the model checker run represented by
+   RESULTS. */
+int
+mc_results_get_duplicate_dropped_states (const struct mc_results *results)
+{
+  return results->duplicate_dropped_states;
+}
+
+/* Returns the number of states dropped because they were off the
+   path specified by mc_options_set_follow_path during the model
+   checker run represented by RESULTS.  A nonzero value here
+   indicates a missing call to mc_include_state in the
+   client-supplied mutation function. */
+int
+mc_results_get_off_path_dropped_states (const struct mc_results *results)
+{
+  return results->off_path_dropped_states;
+}
+
+/* Returns the number of states dropped because their depth
+   exceeded the maximum specified with mc_options_set_max_depth
+   during the model checker run represented by RESULTS. */
+int
+mc_results_get_depth_dropped_states (const struct mc_results *results)
+{
+  return results->depth_dropped_states;
+}
+
+/* Returns the number of states dropped from the queue due to
+   queue overflow during the model checker run represented by
+   RESULTS. */
+int
+mc_results_get_queue_dropped_states (const struct mc_results *results)
+{
+  return results->queue_dropped_states;
+}
+
+/* Returns the number of states that were checked and enqueued
+   but never dequeued and processed during the model checker run
+   represented by RESULTS.  This is zero if the stop reason is
+   MC_CONTINUING or MC_SUCCESS; otherwise, it is the number of
+   states in the queue at the time that the checking run
+   stopped. */
+int
+mc_results_get_queued_unprocessed_states (const struct mc_results *results)
+{
+  return results->queued_unprocessed_states;
+}
+
+/* Returns the maximum length of the queue during the model
+   checker run represented by RESULTS.  If this is equal to the
+   maximum queue length, then the queue (probably) overflowed
+   during the run; otherwise, it did not overflow. */
+int
+mc_results_get_max_queue_length (const struct mc_results *results)
+{
+  return results->max_queue_length;
+}
+
+/* Returns the time at which the model checker run represented by
+   RESULTS started. */
+struct timeval
+mc_results_get_start (const struct mc_results *results)
+{
+  return results->start;
+}
+
+/* Returns the time at which the model checker run represented by
+   RESULTS ended.  (This function may not be called while the run
+   is still ongoing.) */
+struct timeval
+mc_results_get_end (const struct mc_results *results)
+{
+  assert (results->stop_reason != MC_CONTINUING);
+  return results->end;
+}
+
+/* Returns the number of seconds obtained by subtracting time Y
+   from time X. */
+static double
+timeval_subtract (struct timeval x, struct timeval y)
+{
+  /* From libc.info. */
+  double difference;
+
+  /* Perform the carry for the later subtraction by updating Y. */
+  if (x.tv_usec < y.tv_usec) {
+    int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
+    y.tv_usec -= 1000000 * nsec;
+    y.tv_sec += nsec;
+  }
+  if (x.tv_usec - y.tv_usec > 1000000) {
+    int nsec = (x.tv_usec - y.tv_usec) / 1000000;
+    y.tv_usec += 1000000 * nsec;
+    y.tv_sec -= nsec;
+  }
+
+  /* Compute the time remaining to wait.
+     `tv_usec' is certainly positive. */
+  difference = (x.tv_sec - y.tv_sec) + (x.tv_usec - y.tv_usec) / 1000000.0;
+  if (x.tv_sec < y.tv_sec)
+    difference = -difference;
+  return difference;
+}
+
+
+/* Returns the duration, in seconds, of the model checker run
+   represented by RESULTS.  (This function may not be called
+   while the run is still ongoing.) */
+double
+mc_results_get_duration (const struct mc_results *results)
+{
+  assert (results->stop_reason != MC_CONTINUING);
+  return timeval_subtract (results->end, results->start);
+}
+\f
+/* An active model checking run. */
+struct mc
+  {
+    /* Related data structures. */
+    const struct mc_class *class;
+    struct mc_options *options;
+    struct mc_results *results;
+
+    /* Array of 2**(options->hash_bits) bits representing states
+       already visited. */
+    unsigned char *hash;
+
+    /* State queue. */
+    struct mc_state **queue;            /* Array of pointers to states. */
+    struct deque queue_deque;           /* Deque. */
+
+    /* State currently being built by "init" or "mutate". */
+    struct mc_path path;                /* Path to current state. */
+    struct string path_string;          /* Buffer for path_string function. */
+    bool state_named;                   /* mc_name_operation called? */
+    bool state_error;                   /* mc_error called? */
+
+    /* Statistics for calling the progress function. */
+    unsigned int progress;              /* Current progress value. */
+    unsigned int next_progress;         /* Next value to call progress func. */
+    unsigned int prev_progress;         /* Last value progress func called. */
+    struct timeval prev_progress_time;  /* Last time progress func called. */
+
+    /* Information for handling and restoring SIGINT. */
+    bool interrupted;                   /* SIGINT received? */
+    bool *saved_interrupted_ptr;        /* Saved value of interrupted_ptr. */
+    void (*saved_sigint) (int);         /* Saved SIGINT handler. */
+  };
+
+/* A state in the queue. */
+struct mc_state
+  {
+    struct mc_path path;                /* Path to this state. */
+    void *data;                         /* Client-supplied data. */
+  };
+
+/* Points to the current struct mc's "interrupted" member. */
+static bool *interrupted_ptr = NULL;
+
+static const char *path_string (struct mc *);
+static void free_state (const struct mc *, struct mc_state *);
+static void stop (struct mc *, enum mc_stop_reason);
+static struct mc_state *make_state (const struct mc *, void *);
+static size_t random_queue_index (struct mc *);
+static void enqueue_state (struct mc *, struct mc_state *);
+static void do_error_state (struct mc *);
+static void next_operation (struct mc *);
+static bool is_off_path (const struct mc *);
+static void sigint_handler (int signum);
+static void init_mc (struct mc *,
+                     const struct mc_class *, struct mc_options *);
+static void finish_mc (struct mc *);
+
+/* Runs the model checker on the client-specified CLASS with the
+   client-specified OPTIONS.  OPTIONS may be a null pointer if
+   the defaults are acceptable.  Destroys OPTIONS; use
+   mc_options_clone if a copy is needed.
+
+   Returns the results of the model checking run, which must be
+   destroyed by the client with mc_results_destroy.
+
+   To pass auxiliary data to the functions in CLASS, use
+   mc_options_set_aux on OPTIONS, which may be retrieved from the
+   CLASS functions using mc_get_aux. */
+struct mc_results *
+mc_run (const struct mc_class *class, struct mc_options *options)
+{
+  struct mc mc;
+
+  init_mc (&mc, class, options);
+  while (!deque_is_empty (&mc.queue_deque)
+         && mc.results->stop_reason == MC_CONTINUING)
+    {
+      struct mc_state *state = mc.queue[deque_pop_front (&mc.queue_deque)];
+      mc_path_copy (&mc.path, &state->path);
+      mc_path_push (&mc.path, 0);
+      class->mutate (&mc, state->data);
+      free_state (&mc, state);
+      if (mc.interrupted)
+        stop (&mc, MC_INTERRUPTED);
+    }
+  finish_mc (&mc);
+
+  return mc.results;
+}
+
+/* Tests whether the current operation is one that should be
+   performed, checked, and enqueued.  If so, returns true.
+   Otherwise, returns false and, unless checking is stopped,
+   advances to the next state.  The caller should then advance
+   to the next operation.
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+bool
+mc_include_state (struct mc *mc)
+{
+  if (mc->results->stop_reason != MC_CONTINUING)
+    return false;
+  else if (is_off_path (mc))
+    {
+      next_operation (mc);
+      return false;
+    }
+  else
+    return true;
+}
+
+/* Tests whether HASH represents a state that has (probably)
+   already been enqueued.  If not, returns false and marks HASH
+   so that it will be treated as a duplicate in the future.  If
+   so, returns true and advances to the next state.  The
+   caller should then advance to the next operation.
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+bool
+mc_discard_dup_state (struct mc *mc, unsigned int hash)
+{
+  if (mc->options->hash_bits > 0)
+    {
+      hash &= (1u << mc->options->hash_bits) - 1;
+      if (TEST_BIT (mc->hash, hash))
+        {
+          if (mc->options->verbosity > 2)
+            fprintf (mc->options->output_file,
+                     "    [%s] discard duplicate state\n", path_string (mc));
+          mc->results->duplicate_dropped_states++;
+          next_operation (mc);
+          return true;
+        }
+      SET_BIT (mc->hash, hash);
+    }
+  return false;
+}
+
+/* Names the current state NAME, which may contain
+   printf-style format specifications.  NAME should be a
+   human-readable name for the current operation.
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+void
+mc_name_operation (struct mc *mc, const char *name, ...)
+{
+  va_list args;
+
+  va_start (args, name);
+  mc_vname_operation (mc, name, args);
+  va_end (args);
+}
+
+/* Names the current state NAME, which may contain
+   printf-style format specifications, for which the
+   corresponding arguments must be given in ARGS.  NAME should be
+   a human-readable name for the current operation.
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+void
+mc_vname_operation (struct mc *mc, const char *name, va_list args)
+{
+  if (mc->state_named && mc->options->verbosity > 0)
+    fprintf (mc->options->output_file, "  [%s] warning: duplicate call "
+             "to mc_name_operation (missing call to mc_add_state?)\n",
+             path_string (mc));
+  mc->state_named = true;
+
+  if (mc->options->verbosity > 1)
+    {
+      fprintf (mc->options->output_file, "  [%s] ", path_string (mc));
+      vfprintf (mc->options->output_file, name, args);
+      putc ('\n', mc->options->output_file);
+    }
+}
+
+/* Reports the given error MESSAGE for the current operation.
+   The resulting state should still be passed to mc_add_state
+   when all relevant error messages have been issued.  The state
+   will not, however, be enqueued for later mutation of its own.
+
+   By default, model checking stops after the first error
+   encountered.
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+void
+mc_error (struct mc *mc, const char *message, ...)
+{
+  va_list args;
+
+  if (mc->results->stop_reason != MC_CONTINUING)
+    return;
+
+  if (mc->options->verbosity > 1)
+    fputs ("    ", mc->options->output_file);
+  fprintf (mc->options->output_file, "[%s] error: ",
+           path_string (mc));
+  va_start (args, message);
+  vfprintf (mc->options->output_file, message, args);
+  va_end (args);
+  putc ('\n', mc->options->output_file);
+
+  mc->state_error = true;
+}
+
+/* Enqueues DATA as the state corresponding to the current
+   operation.  The operation should have been named with a call
+   to mc_name_operation, and it should have been checked by the
+   caller (who should have reported any errors with mc_error).
+
+   This function should be called from the client-provided
+   "mutate" function, according to the pattern explained in the
+   big comment at the top of model-checker.h. */
+void
+mc_add_state (struct mc *mc, void *data)
+{
+  if (!mc->state_named && mc->options->verbosity > 0)
+    fprintf (mc->options->output_file, "  [%s] warning: unnamed state\n",
+             path_string (mc));
+
+  if (mc->results->stop_reason != MC_CONTINUING)
+    {
+      /* Nothing to do. */
+    }
+  else if (mc->state_error)
+    do_error_state (mc);
+  else if (is_off_path (mc))
+    mc->results->off_path_dropped_states++;
+  else if (mc->path.length + 1 > mc->options->max_depth)
+    mc->results->depth_dropped_states++;
+  else
+    {
+      /* This is the common case. */
+      mc->results->unique_state_count++;
+      if (mc->results->unique_state_count >= mc->options->max_unique_states)
+        stop (mc, MC_MAX_UNIQUE_STATES);
+      enqueue_state (mc, make_state (mc, data));
+      next_operation (mc);
+      return;
+    }
+
+  mc->class->destroy (mc, data);
+  next_operation (mc);
+}
+
+/* Returns the options that were passed to mc_run for model
+   checker MC. */
+const struct mc_options *
+mc_get_options (const struct mc *mc)
+{
+  return mc->options;
+}
+
+/* Returns the current state of the results for model checker
+   MC.  This function is appropriate for use from the progress
+   function set by mc_options_set_progress_func.
+
+   Not all of the results are meaningful before model checking
+   completes. */
+const struct mc_results *
+mc_get_results (const struct mc *mc)
+{
+  return mc->results;
+}
+
+/* Returns the auxiliary data set on the options passed to mc_run
+   with mc_options_set_aux. */
+void *
+mc_get_aux (const struct mc *mc)
+{
+  return mc_options_get_aux (mc_get_options (mc));
+}
+\f
+/* Expresses MC->path as a string and returns the string. */
+static const char *
+path_string (struct mc *mc)
+{
+  ds_clear (&mc->path_string);
+  mc_path_to_string (&mc->path, &mc->path_string);
+  return ds_cstr (&mc->path_string);
+}
+
+/* Frees STATE, including client data. */
+static void
+free_state (const struct mc *mc, struct mc_state *state)
+{
+  mc->class->destroy (mc, state->data);
+  mc_path_destroy (&state->path);
+  free (state);
+}
+
+/* Sets STOP_REASON as the reason that MC's processing stopped,
+   unless MC is already stopped. */
+static void
+stop (struct mc *mc, enum mc_stop_reason stop_reason)
+{
+  if (mc->results->stop_reason == MC_CONTINUING)
+    mc->results->stop_reason = stop_reason;
+}
+
+/* Creates and returns a new state whose path is copied from
+   MC->path and whose data is specified by DATA. */
+static struct mc_state *
+make_state (const struct mc *mc, void *data)
+{
+  struct mc_state *new = xmalloc (sizeof *new);
+  mc_path_init (&new->path);
+  mc_path_copy (&new->path, &mc->path);
+  new->data = data;
+  return new;
+}
+
+/* Returns the index in MC->queue of a random element in the
+   queue. */
+static size_t
+random_queue_index (struct mc *mc)
+{
+  assert (!deque_is_empty (&mc->queue_deque));
+  return deque_front (&mc->queue_deque,
+                      rand () % deque_count (&mc->queue_deque));
+}
+
+/* Adds NEW to MC's state queue, dropping a state if necessary
+   due to overflow. */
+static void
+enqueue_state (struct mc *mc, struct mc_state *new)
+{
+  size_t idx;
+
+  if (new->path.length > mc->results->max_depth_reached)
+    mc->results->max_depth_reached = new->path.length;
+  moments1_add (mc->results->depth_moments, new->path.length, 1.0);
+
+  if (deque_count (&mc->queue_deque) < mc->options->queue_limit)
+    {
+      /* Add new state to queue. */
+      if (deque_is_full (&mc->queue_deque))
+        mc->queue = deque_expand (&mc->queue_deque,
+                                   mc->queue, sizeof *mc->queue);
+      switch (mc->options->strategy)
+        {
+        case MC_BROAD:
+          idx = deque_push_back (&mc->queue_deque);
+          break;
+        case MC_DEEP:
+          idx = deque_push_front (&mc->queue_deque);
+          break;
+        case MC_RANDOM:
+          if (!deque_is_empty (&mc->queue_deque))
+            {
+              idx = random_queue_index (mc);
+              mc->queue[deque_push_front (&mc->queue_deque)]
+                = mc->queue[idx];
+            }
+          else
+            idx = deque_push_front (&mc->queue_deque);
+          break;
+        case MC_PATH:
+          assert (deque_is_empty (&mc->queue_deque));
+          assert (!is_off_path (mc));
+          idx = deque_push_back (&mc->queue_deque);
+          if (mc->path.length
+              >= mc_path_get_length (&mc->options->follow_path))
+            stop (mc, MC_END_OF_PATH);
+          break;
+        default:
+          NOT_REACHED ();
+        }
+      if (deque_count (&mc->queue_deque) > mc->results->max_queue_length)
+        mc->results->max_queue_length = deque_count (&mc->queue_deque);
+    }
+  else
+    {
+      /* Queue has reached limit, so replace an existing
+         state. */
+      assert (mc->options->strategy != MC_PATH);
+      assert (!deque_is_empty (&mc->queue_deque));
+      mc->results->queue_dropped_states++;
+      switch (mc->options->queue_limit_strategy)
+        {
+        case MC_DROP_NEWEST:
+          free_state (mc, new);
+          return;
+        case MC_DROP_OLDEST:
+          switch (mc->options->strategy)
+            {
+            case MC_BROAD:
+              idx = deque_front (&mc->queue_deque, 0);
+              break;
+            case MC_DEEP:
+              idx = deque_back (&mc->queue_deque, 0);
+              break;
+            case MC_RANDOM:
+            case MC_PATH:
+            default:
+              NOT_REACHED ();
+            }
+          break;
+        case MC_DROP_RANDOM:
+          idx = random_queue_index (mc);
+          break;
+        default:
+          NOT_REACHED ();
+        }
+      free_state (mc, mc->queue[idx]);
+    }
+  mc->queue[idx] = new;
+}
+
+/* Process an error state being added to MC. */
+static void
+do_error_state (struct mc *mc)
+{
+  mc->results->error_count++;
+  if (mc->results->error_count >= mc->options->max_errors)
+    stop (mc, MC_MAX_ERROR_COUNT);
+
+  mc_path_copy (&mc->results->error_path, &mc->path);
+
+  if (mc->options->failure_verbosity > mc->options->verbosity)
+    {
+      struct mc_options *path_options;
+
+      fprintf (mc->options->output_file, "[%s] retracing error path:\n",
+               path_string (mc));
+      path_options = mc_options_clone (mc->options);
+      mc_options_set_verbosity (path_options, mc->options->failure_verbosity);
+      mc_options_set_failure_verbosity (path_options, 0);
+      mc_options_set_follow_path (path_options, &mc->path);
+
+      mc_results_destroy (mc_run (mc->class, path_options));
+
+      putc ('\n', mc->options->output_file);
+    }
+}
+
+/* Advances MC to start processing the operation following the
+   current one. */
+static void
+next_operation (struct mc *mc)
+{
+  mc_path_push (&mc->path, mc_path_pop (&mc->path) + 1);
+  mc->state_error = false;
+  mc->state_named = false;
+
+  if (++mc->progress >= mc->next_progress)
+    {
+      struct timeval now;
+      double elapsed, delta;
+
+      if (mc->results->stop_reason == MC_CONTINUING
+          && !mc->options->progress_func (mc))
+        stop (mc, MC_INTERRUPTED);
+
+      gettimeofday (&now, NULL);
+
+      if (mc->options->time_limit > 0.0
+          && (timeval_subtract (now, mc->results->start)
+              > mc->options->time_limit))
+        stop (mc, MC_TIMEOUT);
+
+      elapsed = timeval_subtract (now, mc->prev_progress_time);
+      if (elapsed > 0.0)
+        {
+          /* Re-estimate the amount of progress to take
+             progress_usec microseconds. */
+          unsigned int progress = mc->progress - mc->prev_progress;
+          double progress_sec = mc->options->progress_usec / 1000000.0;
+          delta = progress / elapsed * progress_sec;
+        }
+      else
+        {
+          /* No measurable time at all elapsed during that amount
+             of progress.  Try doubling the amount of progress
+             required. */
+          delta = (mc->progress - mc->prev_progress) * 2;
+        }
+
+      if (delta > 0.0 && delta + mc->progress + 1.0 < UINT_MAX)
+        mc->next_progress = mc->progress + delta + 1.0;
+      else
+        mc->next_progress = mc->progress + (mc->progress - mc->prev_progress);
+
+      mc->prev_progress = mc->progress;
+      mc->prev_progress_time = now;
+    }
+}
+
+/* Returns true if we're tracing an explicit path but the current
+   operation produces a state off that path, false otherwise. */
+static bool
+is_off_path (const struct mc *mc)
+{
+  return (mc->options->strategy == MC_PATH
+          && (mc_path_back (&mc->path)
+              != mc_path_get_operation (&mc->options->follow_path,
+                                        mc->path.length - 1)));
+}
+
+/* Handler for SIGINT. */
+static void
+sigint_handler (int signum UNUSED)
+{
+  /* Just mark the model checker as interrupted. */
+  *interrupted_ptr = true;
+}
+
+/* Initializes MC as a model checker with the given CLASS and
+   OPTIONS.  OPTIONS may be null to use the default options. */
+static void
+init_mc (struct mc *mc, const struct mc_class *class,
+         struct mc_options *options)
+{
+  /* Validate and adjust OPTIONS. */
+  if (options == NULL)
+    options = mc_options_create ();
+  assert (options->queue_limit_strategy != MC_DROP_OLDEST
+          || options->strategy != MC_RANDOM);
+  if (options->strategy == MC_PATH)
+    {
+      options->max_depth = INT_MAX;
+      options->hash_bits = 0;
+    }
+  if (options->progress_usec == 0)
+    {
+      options->progress_func = null_progress;
+      if (options->time_limit > 0.0)
+        options->progress_usec = 250000;
+    }
+
+  /* Initialize MC. */
+  mc->class = class;
+  mc->options = options;
+  mc->results = mc_results_create ();
+
+  mc->hash = (mc->options->hash_bits > 0
+              ? xcalloc (1, DIV_RND_UP (1 << mc->options->hash_bits, CHAR_BIT))
+              : NULL);
+
+  mc->queue = NULL;
+  deque_init_null (&mc->queue_deque);
+
+  mc_path_init (&mc->path);
+  mc_path_push (&mc->path, 0);
+  ds_init_empty (&mc->path_string);
+  mc->state_named = false;
+  mc->state_error = false;
+
+  mc->progress = 0;
+  mc->next_progress = mc->options->progress_usec != 0 ? 100 : UINT_MAX;
+  mc->prev_progress = 0;
+  mc->prev_progress_time = mc->results->start;
+
+  if (mc->options->strategy == MC_RANDOM
+      || options->queue_limit_strategy == MC_DROP_RANDOM)
+    srand (mc->options->seed);
+
+  mc->interrupted = false;
+  mc->saved_interrupted_ptr = interrupted_ptr;
+  interrupted_ptr = &mc->interrupted;
+  mc->saved_sigint = signal (SIGINT, sigint_handler);
+
+  class->init (mc);
+}
+
+/* Complete the model checker run for MC. */
+static void
+finish_mc (struct mc *mc)
+{
+  /* Restore signal handlers. */
+  signal (SIGINT, mc->saved_sigint);
+  interrupted_ptr = mc->saved_interrupted_ptr;
+
+  /* Mark the run complete. */
+  stop (mc, MC_SUCCESS);
+  gettimeofday (&mc->results->end, NULL);
+
+  /* Empty the queue. */
+  mc->results->queued_unprocessed_states = deque_count (&mc->queue_deque);
+  while (!deque_is_empty (&mc->queue_deque))
+    {
+      struct mc_state *state = mc->queue[deque_pop_front (&mc->queue_deque)];
+      free_state (mc, state);
+    }
+
+  /* Notify the progress function of completion. */
+  mc->options->progress_func (mc);
+
+  /* Free memory. */
+  mc_path_destroy (&mc->path);
+  ds_destroy (&mc->path_string);
+  free (mc->options);
+  free (mc->queue);
+  free (mc->hash);
+}
diff --git a/src/language/tests/model-checker.h b/src/language/tests/model-checker.h
new file mode 100644 (file)
index 0000000..8c86fae
--- /dev/null
@@ -0,0 +1,463 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/* Implementation-level model checker.
+
+   A model checker is a tool for software testing and
+   verification that works by exploring all the possible states
+   in a system and verifying their internal consistency.  A
+   conventional model checker requires that the code in a system
+   be translated into a specification language.  The model
+   checker then verifies the specification, rather than the code.
+
+   This is instead an implementation-level model checker, which
+   does not require a separate specification.  Instead, the model
+   checker requires writing a second implementation of the system
+   being checked.  The second implementation can usually be made
+   almost trivial in comparison to the one being checked, because
+   it's usually acceptable for its performance to be
+   comparatively poor, e.g. O(N^2) instead of O(lg N), and thus
+   to use much simpler algorithms.
+
+   For introduction to the implementation-level model checking
+   approach used here, please refer to the following papers:
+
+     Musuvathi, Park, Chou, Engler, Dill, "CMC: A Pragmatic
+     Approach to Model Checking Real Code", Proceedings of the
+     Fifth Symposium on Operating Systems Design and
+     Implementation (OSDI), Dec 2002.
+     http://sprout.stanford.edu/PAPERS/CMC-OSDI-2002/CMC-OSDI-2002.pdf
+
+     Yang, Twohey, Engler, Musuvathi, "Using Model Checking to
+     Find Serious File System Errors", Proceedings of the Sixth
+     Symposium on Operating System Design and Implementation
+     (OSDI), Dec 2004.
+     http://www.stanford.edu/~engler/osdi04-fisc.pdf
+
+     Yang, Twohey, Pfaff, Sar, Engler, "EXPLODE: A Lightweight,
+     General Approach to Finding Serious Errors in Storage
+     Systems", First Workshop on the Evaluation of Software
+     Defect Detection Tools (BUGS), June 2005.
+     http://benpfaff.org/papers/explode.pdf
+
+   Use of a model checker is appropriate when the system being
+   checked is difficult to test using handwritten tests.  This
+   can be the case, for example, when the system has a
+   complicated internal state that is difficult to reason about
+   over a long series of operations.
+
+   The implementation model checker works by putting a set of one
+   of more initial states in a queue (and checking them for
+   consistency).  Then the model checker removes a state from the
+   queue and applies all possible operations of interest to it
+   ("mutates" it), obtaining a set of zero or more child states
+   (and checking each of them for consistency).  Each of these
+   states is itself added to the queue.  The model checker
+   continues dequeuing states and mutating and checking them
+   until the queue is empty.
+
+   In pseudo-code, the process looks like this:
+
+     Q = { initial states }
+     while Q is not empty:
+       S = dequeue(Q)
+       for each operation applicable to S do:
+         T = operation(S)
+         check(T)
+         enqueue(Q, T)
+
+   In many cases this process will never terminate, because every
+   state has one or more child states.  For some systems this is
+   unavoidable, but in others we can make the process finite by
+   pursuing a few stratagems:
+
+     1. Limit the maximum size of the system; for example, limit
+        the number of rows and columns in the implementation of a
+        table being checked.  The client of the model checker is
+        responsible for implementing such limits.
+
+     2. Avoid checking a single state more than one time.  This
+        model checker provides assistance for this function by
+        allowing the client to provide a hash of the system state.
+        States with identical hashes will only be checked once
+        during a single run.
+
+   When a system cannot be made finite, or when a finite system
+   is too large to check in a practical amount of time, the model
+   checker provides multiple ways to limit the checking run:
+   based on maximum depth, maximum unique states checked, maximum
+   errors found (by default, 1), or maximum time used for
+   checking.
+
+   The client of the model checker must provide three functions
+   via function pointers embedded into a "struct mc_class":
+
+     1. void init (struct mc *mc);
+
+        This function is called once at the beginning of a
+        checking run.  It checks one or more initial states and
+        adds them to the model checker's queue.  (If it does not
+        add any states to the queue, then there is nothing to
+        check.)
+
+        Here's an outline for writing the init function:
+
+          void
+          init_foo (struct mc *mc)
+          {
+            struct foo *foo;
+
+            mc_name_operation (mc, "initial state");
+            foo = generate_initial_foo ();
+            if (!state_is_consistent (foo))
+              mc_error (mc, "inconsistent state");
+            mc_add_state (mc, foo);
+          }
+
+     2. void mutate (struct mc *mc, const void *data);
+
+        This function is called when a dequeued state is ready to
+        be mutated.  For each operation that can be applied to
+        the client-specified DATA, it applies that operation to a
+        clone of the DATA, checks that the clone is consistent,
+        and adds the clone to the model checker's queue.
+
+        Here's an outline for writing the mutate function:
+
+          void
+          mutate_foo (struct mc *mc, void *state_)
+          {
+            struct foo *state = state_;
+
+            for (...each operation...)
+              if (mc_include_state (mc))
+                {
+                  struct foo *clone;
+
+                  mc_name_operation (mc, "do operation %s", ...);
+                  clone = clone_foo (state);
+                  do_operation (clone);
+                  if (!mc_discard_dup_state (mc, hash_foo (clone)))
+                    {
+                      if (!state_is_consistent (clone))
+                        mc_error (mc, "inconsistent state");
+                      mc_add_state (mc, clone);
+                    }
+                  else
+                    destroy_foo (clone);
+                }
+          }
+
+        Notes on the above outline:
+
+          - The call to mc_include_state allows currently
+            uninteresting operations to be skipped.  It is not
+            essential.
+
+          - The call to mc_name_operation should give the current
+            operation a human-readable name.  The name may
+            include printf-style format specifications.
+
+            When an error occurs, the model checker (by default)
+            replays the sequence of operations performed to reach
+            the error, printing the name of the operation at each
+            step, which is often sufficient information in itself
+            to debug the error.
+
+            At higher levels of verbosity, the name is printed
+            for each operation.
+
+          - Operations should be performed on a copy of the data
+            provided.  The data provided should not be destroyed
+            or modified.
+
+          - The call to mc_discard_dup_state is needed to discard
+            (probably) duplicate states.  It is otherwise
+            optional.
+
+            To reduce the probability of collisions, use a
+            high-quality hash function.  MD4 is a reasonable
+            choice: it is fast but high-quality.  In one test,
+            switching to MD4 from MD5 increased overall speed of
+            model checking by 8% and actually reduced (!) the
+            number of collisions.
+
+            The hash value needs to include enough of the state
+            to ensure that interesting states are not excluded,
+            but it need not include the entire state.  For
+            example, in many cases, the structure of complex data
+            (metadata) is often much more important than the
+            contents (data), so it may be reasonable to hash only
+            the metadata.
+
+            mc_discard_dup_state may be called before or after
+            checking for consistency, but calling it first avoids
+            wasting time checking duplicate states for
+            consistency, which again can be a significant
+            performance boost.
+
+          - The mc_error function reports errors.  It may be
+            called as many times as desired to report each kind
+            of inconsistency in a state.
+
+          - The mc_add_state function adds the new state to the
+            queue.  It should be called regardless of whether an
+            error was reported, to indicate to the model checker
+            that state processing has finished.
+
+          - The mutation function should be deterministic, to
+            make it possible to reliably reproduce errors.
+
+     3. void destroy (struct mc *mc, void *data);
+
+        This function is called to discard the client-specified
+        DATA associated with a state.
+
+   Numerous options are available for configuring the model
+   checker.  The most important of these are:
+
+     - Search algorithm:
+
+       * Breadth-first search (the default): First try all the
+         operations with depth 1, then those with depth 2, then
+         those with depth 3, and so on.
+
+         This search algorithm finds the least number of
+         operations needed to trigger a given bug.
+
+       * Depth-first search: Searches downward in the tree of
+         states as fast as possible.  Good for finding bugs that
+         require long sequences of operations to trigger.
+
+       * Random-first search: Searches through the tree of
+         states in random order.
+
+       * Explicit path: Applies an explicitly specified sequence
+         of operations.
+
+     - Verbosity: By default, messages are printed only when an
+       error is encountered, but you can cause the checker to
+       print a message on every state transition.  This is most
+       useful when the errors in your code cause segfaults or
+       some other kind of sudden termination.
+
+     - Treatment of errors: By default, when an error is
+       encountered, the model checker recursively invokes itself
+       with an increased verbosity level and configured to follow
+       only the error path.  As long as the mutation function is
+       deterministic, this quickly and concisely replays the
+       error and describes the path followed to reach it in an
+       easily human-readable manner.
+
+     - Limits:
+
+       * Maximum depth: You can limit the depth of the operations
+         performed.  Most often useful with depth-first search.
+         By default, depth is unlimited.
+
+       * Maximum queue length: You can limit the number of states
+         kept in the queue at any given time.  The main reason to
+         do so is to limit memory consumption.  The default
+         limit is 10,000 states.  Several strategies are
+         available for choosing which state to drop when the
+         queue overflows.
+
+     - Stop conditions: based on maximum unique states checked,
+       maximum errors found (by default, 1), or maximum time used
+       for checking.
+
+     - Progress: by default, the checker prints a '.' on stderr
+       every .25 seconds, but you can substitute another progress
+       function or disable progress printing.
+
+   This model checker does not (yet) include two features
+   described in the papers cited above: utility scoring
+   heuristics to guide the search strategy and "choice points" to
+   explore alternative cases.  The former feature is less
+   interesting for this model checker, because the data
+   structures we are thus far using it to model are much smaller
+   than those discussed in the paper.  The latter feature we
+   should implement at some point. */
+
+#ifndef LIBPSPP_MODEL_CHECKER_H
+#define LIBPSPP_MODEL_CHECKER_H 1
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#include <libpspp/compiler.h>
+
+/* An active model checking run. */
+struct mc;
+
+/* Provided by each client of the model checker. */
+struct mc_class
+  {
+    void (*init) (struct mc *);
+    void (*mutate) (struct mc *, const void *);
+    void (*destroy) (const struct mc *, void *);
+  };
+
+/* Results of a model checking run. */
+struct mc_results;
+
+/* Configuration for running the model checker. */
+struct mc_options;
+
+/* Primary external interface to model checker. */
+struct mc_results *mc_run (const struct mc_class *, struct mc_options *);
+
+/* Functions for use from client-supplied "init" and "mutate"
+   functions. */
+bool mc_include_state (struct mc *);
+bool mc_discard_dup_state (struct mc *, unsigned int hash);
+void mc_name_operation (struct mc *, const char *, ...) PRINTF_FORMAT (2, 3);
+void mc_vname_operation (struct mc *, const char *, va_list)
+     PRINTF_FORMAT (2, 0);
+void mc_error (struct mc *, const char *, ...) PRINTF_FORMAT (2, 3);
+void mc_add_state (struct mc *, void *data);
+
+/* Functions for use from client-supplied "init", "mutate", and
+   "destroy" functions. */
+const struct mc_options *mc_get_options (const struct mc *);
+const struct mc_results *mc_get_results (const struct mc *);
+void *mc_get_aux (const struct mc *);
+\f
+/* A path of operations through a model to arrive at some
+   particular state. */
+struct mc_path
+  {
+    int *ops;           /* Sequence of operations. */
+    size_t length;      /* Number of operations. */
+    size_t capacity;    /* Number of operations for which room is allocated. */
+  };
+
+void mc_path_init (struct mc_path *);
+void mc_path_copy (struct mc_path *, const struct mc_path *);
+void mc_path_push (struct mc_path *, int new_state);
+int mc_path_pop (struct mc_path *);
+int mc_path_back (const struct mc_path *);
+void mc_path_destroy (struct mc_path *);
+
+int mc_path_get_operation (const struct mc_path *, size_t index);
+size_t mc_path_get_length (const struct mc_path *);
+
+struct string;
+void mc_path_to_string (const struct mc_path *, struct string *);
+\f
+struct mc_options *mc_options_create (void);
+struct mc_options *mc_options_clone (const struct mc_options *);
+void mc_options_destroy (struct mc_options *);
+
+/* Search strategy. */
+enum mc_strategy
+  {
+    MC_BROAD,           /* Breadth-first search. */
+    MC_DEEP,            /* Depth-first search. */
+    MC_RANDOM,          /* Randomly ordered search. */
+    MC_PATH             /* Follow one explicit path. */
+  };
+
+enum mc_strategy mc_options_get_strategy (const struct mc_options *);
+void mc_options_set_strategy (struct mc_options *, enum mc_strategy);
+unsigned int mc_options_get_seed (const struct mc_options *);
+void mc_options_set_seed (struct mc_options *, unsigned int seed);
+int mc_options_get_max_depth (const struct mc_options *);
+void mc_options_set_max_depth (struct mc_options *, int max_depth);
+int mc_options_get_hash_bits (const struct mc_options *);
+void mc_options_set_hash_bits (struct mc_options *, int hash_bits);
+
+const struct mc_path *mc_options_get_follow_path (const struct mc_options *);
+void mc_options_set_follow_path (struct mc_options *, const struct mc_path *);
+
+/* Strategy for dropped states from the queue when it
+   overflows. */
+enum mc_queue_limit_strategy
+  {
+    MC_DROP_NEWEST,     /* Don't enqueue the new state at all. */
+    MC_DROP_OLDEST,     /* Drop the oldest state in the queue. */
+    MC_DROP_RANDOM      /* Drop a random state from the queue. */
+  };
+
+int mc_options_get_queue_limit (const struct mc_options *);
+void mc_options_set_queue_limit (struct mc_options *, int queue_limit);
+enum mc_queue_limit_strategy mc_options_get_queue_limit_strategy (
+  const struct mc_options *);
+void mc_options_set_queue_limit_strategy (struct mc_options *,
+                                          enum mc_queue_limit_strategy);
+
+int mc_options_get_max_unique_states (const struct mc_options *);
+void mc_options_set_max_unique_states (struct mc_options *,
+                                       int max_unique_states);
+int mc_options_get_max_errors (const struct mc_options *);
+void mc_options_set_max_errors (struct mc_options *, int max_errors);
+double mc_options_get_time_limit (const struct mc_options *);
+void mc_options_set_time_limit (struct mc_options *, double time_limit);
+
+int mc_options_get_verbosity (const struct mc_options *);
+void mc_options_set_verbosity (struct mc_options *, int verbosity);
+int mc_options_get_failure_verbosity (const struct mc_options *);
+void mc_options_set_failure_verbosity (struct mc_options *,
+                                       int failure_verbosity);
+FILE *mc_options_get_output_file (const struct mc_options *);
+void mc_options_set_output_file (struct mc_options *, FILE *);
+
+typedef bool mc_progress_func (struct mc *);
+int mc_options_get_progress_usec (const struct mc_options *);
+void mc_options_set_progress_usec (struct mc_options *, int progress_usec);
+mc_progress_func *mc_options_get_progress_func (const struct mc_options *);
+void mc_options_set_progress_func (struct mc_options *, mc_progress_func *);
+
+void *mc_options_get_aux (const struct mc_options *);
+void mc_options_set_aux (struct mc_options *, void *aux);
+\f
+/* Reason that a model checking run terminated. */
+enum mc_stop_reason
+  {
+    MC_CONTINUING,              /* Run has not yet terminated. */
+    MC_SUCCESS,                 /* Queue emptied (ran out of states). */
+    MC_MAX_UNIQUE_STATES,       /* Did requested number of unique states. */
+    MC_MAX_ERROR_COUNT,         /* Too many errors. */
+    MC_END_OF_PATH,             /* Processed requested path (MC_PATH only). */
+    MC_TIMEOUT,                 /* Timeout. */
+    MC_INTERRUPTED              /* Received SIGINT (Ctrl+C). */
+  };
+
+void mc_results_destroy (struct mc_results *);
+
+enum mc_stop_reason mc_results_get_stop_reason (const struct mc_results *);
+int mc_results_get_unique_state_count (const struct mc_results *);
+int mc_results_get_error_count (const struct mc_results *);
+
+int mc_results_get_max_depth_reached (const struct mc_results *);
+double mc_results_get_mean_depth_reached (const struct mc_results *);
+
+const struct mc_path *mc_results_get_error_path (const struct mc_results *);
+
+int mc_results_get_duplicate_dropped_states (const struct mc_results *);
+int mc_results_get_off_path_dropped_states (const struct mc_results *);
+int mc_results_get_depth_dropped_states (const struct mc_results *);
+int mc_results_get_queue_dropped_states (const struct mc_results *);
+int mc_results_get_queued_unprocessed_states (const struct mc_results *);
+int mc_results_get_max_queue_length (const struct mc_results *);
+
+struct timeval mc_results_get_start (const struct mc_results *);
+struct timeval mc_results_get_end (const struct mc_results *);
+double mc_results_get_duration (const struct mc_results *);
+
+#endif /* libpspp/model-checker.h */
diff --git a/src/language/utilities/ChangeLog b/src/language/utilities/ChangeLog
deleted file mode 100644 (file)
index 5701c38..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-2007-09-16  Ben Pfaff  <blp@gnu.org>
-
-       * set.q (show_warranty): Use fputs to print lack-of-warranty
-       statement, instead of msg.  This is because msg now outputs the
-       message to output devices, and the output subsystem is not
-       prepared to deal with table cells that exceed one page in length.
-       Thanks to John Darrington for bug report and review.  Bug #21093.
-       (show_copying) Ditto.
-
-2007-08-16  Ben Pfaff  <blp@gnu.org>
-
-       Implement journaling.  Bug #17240.
-       
-       * set.q: Add LOG subcommand as synonym for JOURNAL.
-       (stc_custom_journal): Implement.
-       (stc_custom_log): New function.
-
-2007-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Abstract the documents within a dictionary a little better.
-       Thanks to John Darrington for suggestion, initial version, and
-       review.  Patch #5917.
-
-       * title.c (add_document_line): Removed.
-       (add_document_trailer): New function.
-       (cmd_document): Rewrite to yield SPSS-like output and to use the
-       updated document API.
-       (cmd_add_documents): Ditto.
-
-2007-05-03 John Darrington <john@darrington.wattle.id.au>
-
-       * title.c: Implemented ADD DOCUMENT command.
-
-Sun Nov 19 09:21:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       * set.q: Add RIB, RRB settings to control binary formats used by
-       data_out.
-       (cmd_set) Implement SET RIB, RRB.
-       (show_rib) New function.
-       (show_rrb) New function.
-       (static var show_table[]) Add SHOW RIB, RRB.
-
-Sat Nov  4 16:05:47 2006  Ben Pfaff  <blp@gnu.org>
-
-       * set.q: Add WIB, WRB settings to control binary formats used by
-       data_out.
-       (cmd_set) Implement SET WIB, WRB.
-       (stc_to_integer_format) New function.
-       (stc_to_float_format) New function.
-       (show_integer_format) New function.
-       (show_float_format) New function.
-       (show_wib) New function.
-       (show_wrb) New function.
-       (static var show_table[]) Add SHOW WIB, WRB.
-
-Sat Nov  4 11:48:23 2006  Ben Pfaff  <blp@gnu.org>
-
-       * set.q: Update ERRORS, MESSAGES, RESULTS command syntax.
-       (cmd_set) Handle ERRORS command.
-       (show_errors) New function.
-       (var show_table[]) Add ERRORS to the table.
-
-Tue Oct 31 20:10:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * set.q (cmd_set): Drop the `ok' variable, which didn't do
-       anything useful.
-       (extract_cc_token) Adapt to new fmt_number_style.
-       (do_cc) Ditto.
-       (format_cc) Ditto.
-       (show_cc) Change parameter to be an enum fmt_type.  Adjust all
-       callers.
-
-Wed Apr 26 15:06:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       * set.q: Use SN instead of MN for most output from SHOW, because
-       the output is tied to the SHOW command that caused it.
-
-Tue Apr 25 13:21:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       * permissions.c (change_permissions): Use SE instead of ME for
-       errors associated with a syntax file command.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/utilities/OChangeLog b/src/language/utilities/OChangeLog
new file mode 100644 (file)
index 0000000..5701c38
--- /dev/null
@@ -0,0 +1,85 @@
+2007-09-16  Ben Pfaff  <blp@gnu.org>
+
+       * set.q (show_warranty): Use fputs to print lack-of-warranty
+       statement, instead of msg.  This is because msg now outputs the
+       message to output devices, and the output subsystem is not
+       prepared to deal with table cells that exceed one page in length.
+       Thanks to John Darrington for bug report and review.  Bug #21093.
+       (show_copying) Ditto.
+
+2007-08-16  Ben Pfaff  <blp@gnu.org>
+
+       Implement journaling.  Bug #17240.
+       
+       * set.q: Add LOG subcommand as synonym for JOURNAL.
+       (stc_custom_journal): Implement.
+       (stc_custom_log): New function.
+
+2007-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Abstract the documents within a dictionary a little better.
+       Thanks to John Darrington for suggestion, initial version, and
+       review.  Patch #5917.
+
+       * title.c (add_document_line): Removed.
+       (add_document_trailer): New function.
+       (cmd_document): Rewrite to yield SPSS-like output and to use the
+       updated document API.
+       (cmd_add_documents): Ditto.
+
+2007-05-03 John Darrington <john@darrington.wattle.id.au>
+
+       * title.c: Implemented ADD DOCUMENT command.
+
+Sun Nov 19 09:21:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       * set.q: Add RIB, RRB settings to control binary formats used by
+       data_out.
+       (cmd_set) Implement SET RIB, RRB.
+       (show_rib) New function.
+       (show_rrb) New function.
+       (static var show_table[]) Add SHOW RIB, RRB.
+
+Sat Nov  4 16:05:47 2006  Ben Pfaff  <blp@gnu.org>
+
+       * set.q: Add WIB, WRB settings to control binary formats used by
+       data_out.
+       (cmd_set) Implement SET WIB, WRB.
+       (stc_to_integer_format) New function.
+       (stc_to_float_format) New function.
+       (show_integer_format) New function.
+       (show_float_format) New function.
+       (show_wib) New function.
+       (show_wrb) New function.
+       (static var show_table[]) Add SHOW WIB, WRB.
+
+Sat Nov  4 11:48:23 2006  Ben Pfaff  <blp@gnu.org>
+
+       * set.q: Update ERRORS, MESSAGES, RESULTS command syntax.
+       (cmd_set) Handle ERRORS command.
+       (show_errors) New function.
+       (var show_table[]) Add ERRORS to the table.
+
+Tue Oct 31 20:10:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * set.q (cmd_set): Drop the `ok' variable, which didn't do
+       anything useful.
+       (extract_cc_token) Adapt to new fmt_number_style.
+       (do_cc) Ditto.
+       (format_cc) Ditto.
+       (show_cc) Change parameter to be an enum fmt_type.  Adjust all
+       callers.
+
+Wed Apr 26 15:06:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       * set.q: Use SN instead of MN for most output from SHOW, because
+       the output is tied to the SHOW command that caused it.
+
+Tue Apr 25 13:21:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       * permissions.c (change_permissions): Use SE instead of ME for
+       errors associated with a syntax file command.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 5f66102cbc909e742ffe676895149d95aee3b75c..c4ca92b0bc54bcbb4a1eb8b69e67a49624bff13f 100644 (file)
@@ -16,3 +16,5 @@ all_q_sources += $(src_language_utilities_built_sources:.c=.q)
 EXTRA_DIST += $(src_language_utilities_built_sources:.c=.q)
 CLEANFILES += $(src_language_utilities_built_sources)
 
+
+EXTRA_DIST += src/language/utilities/OChangeLog
index d7b102836e460cf0f05650d201d718b546bb0db5..8e69dab50c6260f63795d569c910ab48cd743c47 100644 (file)
@@ -26,7 +26,6 @@
 #include <data/file-name.h>
 
 #include "dirname.h"
-#include "canonicalize.h"
 #include "xalloc.h"
 
 #include "gettext.h"
@@ -191,8 +190,7 @@ parse_insert (struct lexer *lexer, char **filename)
       return CMD_FAILURE;
     }
 
-  *filename = canonicalize_file_name (relative_filename);
-  free (relative_filename);
+  *filename = relative_filename;
 
   return CMD_SUCCESS;
 }
index e058aa5958330e4924f415dd60713882b8767305..37388f9264162e2c346c4f7b7a3edc637aa8bcce 100644 (file)
@@ -115,7 +115,7 @@ int tgetnum (const char *);
      wib=wib:msbfirst/lsbfirst/vax/native;
      wrb=wrb:native/isl/isb/idl/idb/vf/vd/vg/zs/zl;
      width=custom;
-     workspace=integer "x>=1024" "%s must be at least 1 MB";
+     workspace=integer "x>0" "%s must be positive";
      xsort=xsort:yes/no.
 */
 
@@ -195,7 +195,12 @@ cmd_set (struct lexer *lexer, struct dataset *ds)
   if (cmd.sbc_wrb)
     settings_set_output_float_format (stc_to_float_format (cmd.wrb));
   if (cmd.sbc_workspace)
-    settings_set_workspace (cmd.n_workspace[0] * 1024L);
+    {
+      if ( cmd.n_workspace[0] < 1024 && ! settings_get_testing_mode ())
+       msg (SE, _("WORKSPACE must be at least 1MB"));
+      else
+       settings_set_workspace (cmd.n_workspace[0] * 1024L);
+    }
 
   if (cmd.sbc_block)
     msg (SW, _("%s is obsolete."), "BLOCK");
diff --git a/src/language/xforms/ChangeLog b/src/language/xforms/ChangeLog
deleted file mode 100644 (file)
index 4e15b1e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-2007-04-16  Ben Pfaff  <blp@gnu.org>
-
-       * recode.c (parse_map_in): Improve error message when user
-       attempts to use THRU with string variables.
-       Suggested by seth@swoolley.homeip.net.
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * recode.c (parse_mappings): Initialize "out" member of mapping
-       for CONVERT, fixing an uninitialized data bug.
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * recode.c (enlarge_dst_widths): Source isn't null-terminated, so
-       don't pretend it is.
-       (var_is_num_missing): MISSING should include system-missing values
-       too.
-
-Thu Feb  1 16:51:16 2007  Ben Pfaff  <blp@gnu.org>
-
-       * recode.c (find_src_numeric): Handle MAP_SYSMIS case, which was
-       carelessly overlooked until now.  Fixes bug #18917.  Thanks to
-       John Darrington for bug report and review.
-
-Sat Dec  9 18:48:20 2006  Ben Pfaff  <blp@gnu.org>
-
-       * compute.c (struct compute_trns): Remove `fv' member, which was
-       redundant with `variable'.
-
-Thu Nov 30 22:46:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * compute.c: Fix bug #17422, which reports that a variable created
-       by assignment in a COMPUTE command could not be used in the
-       computation expression.
-       (struct lvalue) Drop `var_name' member in favor of `variable'
-       pointer.  Add `is_new_variable' member to allow us to know whether
-       to delete the variable at destruction time, in case of an error.
-       (lvalue_parse) Create variable whose name is specified, if it does
-       not already exist, as a numeric variable.
-       (lvalue_get_type) Rewrite to work with revised lvalue structure.
-       New `dict' parameter, which propagates back up its call chain.
-       (lvalue_finalize) No need to create variable here since we did so
-       at parse time.
-       (lvalue_destroy) Destroy variable if `is_new_variable' set.
-
-Sat Oct  7 11:04:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk fail.c: Added a debug transformation which always fails.
-
-Sat May  6 16:02:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       Get rid of `char *c' member in union value, for cleanliness.
-
-       * recode.c: (union recode_value) New union.
-       (struct map_in) Change x, y types to union recode_value.
-       (struct map_out) Change value type to union recode_value.
-       (find_src_string) Wrap data_in() call so it uses a real `union
-       value'.
-
-Sat May  6 14:08:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * select-if.c (cmd_filter): Make FILTER without any further
-       keywords turn off filtering, with a warning, for compatibility.
-       Change errors from cascading failures to ordinary failures.  Check
-       for command terminator.
-
-Sat May  6 13:25:57 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, remove
-       PROCESS IF, which was deprecated anyway and can be easily
-       simulated with TEMPORARY followed by SELECT IF.
-
-       * select-if.c (cmd_process_if): Removed.
-       (global var process_if_expr) Removed, along with all references
-       globally.
-
-Tue Apr 25 13:23:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * select-if.c (cmd_process_if): Use SW instead of MW for warning
-       associated with a syntax file command.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/language/xforms/OChangeLog b/src/language/xforms/OChangeLog
new file mode 100644 (file)
index 0000000..4e15b1e
--- /dev/null
@@ -0,0 +1,84 @@
+2007-04-16  Ben Pfaff  <blp@gnu.org>
+
+       * recode.c (parse_map_in): Improve error message when user
+       attempts to use THRU with string variables.
+       Suggested by seth@swoolley.homeip.net.
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * recode.c (parse_mappings): Initialize "out" member of mapping
+       for CONVERT, fixing an uninitialized data bug.
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * recode.c (enlarge_dst_widths): Source isn't null-terminated, so
+       don't pretend it is.
+       (var_is_num_missing): MISSING should include system-missing values
+       too.
+
+Thu Feb  1 16:51:16 2007  Ben Pfaff  <blp@gnu.org>
+
+       * recode.c (find_src_numeric): Handle MAP_SYSMIS case, which was
+       carelessly overlooked until now.  Fixes bug #18917.  Thanks to
+       John Darrington for bug report and review.
+
+Sat Dec  9 18:48:20 2006  Ben Pfaff  <blp@gnu.org>
+
+       * compute.c (struct compute_trns): Remove `fv' member, which was
+       redundant with `variable'.
+
+Thu Nov 30 22:46:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * compute.c: Fix bug #17422, which reports that a variable created
+       by assignment in a COMPUTE command could not be used in the
+       computation expression.
+       (struct lvalue) Drop `var_name' member in favor of `variable'
+       pointer.  Add `is_new_variable' member to allow us to know whether
+       to delete the variable at destruction time, in case of an error.
+       (lvalue_parse) Create variable whose name is specified, if it does
+       not already exist, as a numeric variable.
+       (lvalue_get_type) Rewrite to work with revised lvalue structure.
+       New `dict' parameter, which propagates back up its call chain.
+       (lvalue_finalize) No need to create variable here since we did so
+       at parse time.
+       (lvalue_destroy) Destroy variable if `is_new_variable' set.
+
+Sat Oct  7 11:04:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk fail.c: Added a debug transformation which always fails.
+
+Sat May  6 16:02:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       Get rid of `char *c' member in union value, for cleanliness.
+
+       * recode.c: (union recode_value) New union.
+       (struct map_in) Change x, y types to union recode_value.
+       (struct map_out) Change value type to union recode_value.
+       (find_src_string) Wrap data_in() call so it uses a real `union
+       value'.
+
+Sat May  6 14:08:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * select-if.c (cmd_filter): Make FILTER without any further
+       keywords turn off filtering, with a warning, for compatibility.
+       Change errors from cascading failures to ordinary failures.  Check
+       for command terminator.
+
+Sat May  6 13:25:57 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, remove
+       PROCESS IF, which was deprecated anyway and can be easily
+       simulated with TEMPORARY followed by SELECT IF.
+
+       * select-if.c (cmd_process_if): Removed.
+       (global var process_if_expr) Removed, along with all references
+       globally.
+
+Tue Apr 25 13:23:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * select-if.c (cmd_process_if): Use SW instead of MW for warning
+       associated with a syntax file command.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index d0fe1cb6c03596a990cf26abacee9a5c7abd420b..ddb1021fe20a0b46e6370b1a8a98370d82d91d61 100644 (file)
@@ -8,3 +8,5 @@ language_xforms_sources = \
        src/language/xforms/sample.c \
        src/language/xforms/recode.c \
        src/language/xforms/select-if.c
+
+EXTRA_DIST += src/language/xforms/OChangeLog
index fb02c910a4ebfe29a3a85dd4a9c38631dc417abe..bdff1ac5246ed80e9afd428a4ec4518b077a9684 100644 (file)
@@ -161,7 +161,7 @@ cmd_recode (struct lexer *lexer, struct dataset *ds)
          This must be the final step; otherwise we'd have to
          delete destination variables on failure. */
       if (trns->src_vars != trns->dst_vars)
-        create_dst_vars (trns, dataset_dict (ds));
+       create_dst_vars (trns, dataset_dict (ds));
 
       /* Done. */
       add_transformation (ds,
@@ -230,6 +230,7 @@ parse_mappings (struct lexer *lexer, struct recode_trns *trns)
           do
             {
               struct map_in in;
+
               if (!parse_map_in (lexer, &in, trns->pool,
                                  trns->src_type, max_src_width))
                 return false;
@@ -240,7 +241,11 @@ parse_mappings (struct lexer *lexer, struct recode_trns *trns)
 
           if (!parse_map_out (lexer, trns->pool, &out))
             return false;
-          dst_type = val_type_from_width (out.width);
+
+         if (out.copy_input)
+           dst_type = trns->src_type;
+         else
+           dst_type = val_type_from_width (out.width);
           if (have_dst_type && dst_type != trns->dst_type)
             {
               msg (SE, _("Inconsistent target variable types.  "
@@ -289,8 +294,11 @@ static bool
 parse_map_in (struct lexer *lexer, struct map_in *in, struct pool *pool,
               enum val_type src_type, size_t max_src_width)
 {
+
   if (lex_match_id (lexer, "ELSE"))
+    {
     set_map_in_generic (in, MAP_ELSE);
+    }
   else if (src_type == VAL_NUMERIC)
     {
       if (lex_match_id (lexer, "MISSING"))
@@ -307,16 +315,21 @@ parse_map_in (struct lexer *lexer, struct map_in *in, struct pool *pool,
     }
   else
     {
-      if (!lex_force_string (lexer))
+      if (lex_match_id (lexer, "MISSING"))
+        set_map_in_generic (in, MAP_MISSING);
+      else if (!lex_force_string (lexer))
         return false;
-      set_map_in_str (in, pool, lex_tokstr (lexer), max_src_width);
-      lex_get (lexer);
-      if (lex_token (lexer) == T_ID
-          && lex_id_match (ss_cstr ("THRU"), ss_cstr (lex_tokid (lexer))))
-        {
-          msg (SE, _("THRU is not allowed with string variables."));
-          return false;
-        }
+      else 
+       {
+         set_map_in_str (in, pool, lex_tokstr (lexer), max_src_width);
+         lex_get (lexer);
+         if (lex_token (lexer) == T_ID
+             && lex_id_match (ss_cstr ("THRU"), ss_cstr (lex_tokid (lexer))))
+           {
+             msg (SE, _("THRU is not allowed with string variables."));
+             return false;
+           }
+       }
     }
 
   return true;
@@ -384,8 +397,11 @@ parse_map_out (struct lexer *lexer, struct pool *pool, struct map_out *out)
       set_map_out_str (out, pool, lex_tokstr (lexer));
       lex_get (lexer);
     }
-  else if (lex_match_id (lexer, "COPY"))
-    out->copy_input = true;
+  else if (lex_match_id (lexer, "COPY")) 
+    {
+      out->copy_input = true;
+      out->width = 0; 
+    }
   else
     {
       lex_error (lexer, _("expecting output value"));
@@ -461,6 +477,7 @@ parse_dst_vars (struct lexer *lexer, struct recode_trns *trns,
               return false;
             }
         }
+
     }
   else
     {
@@ -584,9 +601,10 @@ find_src_numeric (struct recode_trns *trns, double value, const struct variable
 /* Returns the output mapping in TRNS for an input of VALUE with
    the given WIDTH, or a null pointer if there is no mapping. */
 static const struct map_out *
-find_src_string (struct recode_trns *trns, const char *value, int width)
+find_src_string (struct recode_trns *trns, const char *value, const struct variable *src_var)
 {
   struct mapping *m;
+  int width = var_get_width (src_var);
 
   for (m = trns->mappings; m < trns->mappings + trns->map_cnt; m++)
     {
@@ -613,6 +631,9 @@ find_src_string (struct recode_trns *trns, const char *value, int width)
             out->value.f = uv.f;
             break;
           }
+       case MAP_MISSING:
+         match = var_is_str_missing (src_var, value, MV_ANY);
+         break;
         default:
           NOT_REACHED ();
         }
@@ -644,7 +665,7 @@ recode_trns_proc (void *trns_, struct ccase *c, casenumber case_idx UNUSED)
       if (trns->src_type == VAL_NUMERIC)
         out = find_src_numeric (trns, src_data->f, src_var);
       else
-        out = find_src_string (trns, src_data->s, var_get_width (src_var));
+        out = find_src_string (trns, src_data->s, src_var);
 
       if (trns->dst_type == VAL_NUMERIC)
         {
diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog
deleted file mode 100644 (file)
index 229b4f9..0000000
+++ /dev/null
@@ -1,819 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-
-       * hash.c (hsh_hash_int): Use gsl_isnan instead of isnan, as a
-       stopgap measure for portability until appropriate gnulib modules
-       are available.
-
-       * misc.h (macro isinf): Remove implementations of isinf, isnan,
-       and finite, because they were not effective and we are now using
-       the equivalent GSL functions.
-
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6427.  Reviewed by John Darrington.
-
-       * automake.mk: Remove moved files.
-
-       * syntax-gen.c: Moved to src/ui (and rewritten).
-
-       * syntax-gen.h: Ditto.
-
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6441.  Reviewed by John Darrington.
-
-       * str.c (ss_match_char_in): New function.
-
-2008-02-18  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6426.  Thanks to John Darrington for review.
-
-       * str.c (ds_read_line): Add argument to limit the length of the
-       line to be read.  Update all callers.
-
-2008-02-01  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6386.  Thanks to John Darrington for review.
-
-       * str.c (str_format_26adic): New function.
-
-2007-12-24  John Darrington <john@darrington.wattle.id.au>
-
-        * taint.c (taint_destroy): Return true if pointer is null.
-
-2007-11-25  Ben Pfaff  <blp@gnu.org>
-
-       * float-format.c (assemble_number): Only store 32 bits for Z short
-       format.  Partial fix for bug #21590.
-
-2007-11-08  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ds_read_stream): Change return value semantics to be more
-       useful.  Update all users.
-
-2007-11-03 John Darrington <john@darrington.wattle.id.au>
-
-       * i18n.c i18n.h: Added convertor from UTF8 to system.
-       This is needed for reading gnumeric files (and possibly others).
-
-2007-10-11  Ben Pfaff  <blp@gnu.org>
-
-       * xalloc.h: Removed.  Changed all users to include "xalloc.h" from
-       gnulib instead.
-
-       * xalloc.c: Removed.
-
-2007-10-11  Ben Pfaff  <blp@gnu.org>
-
-       * alloc.h (local_alloc): Removed.  Changed all users to use
-       xmalloca instead.
-       (local_free): Removed.  Changed all users to use freea instead.
-
-2007-10-11  Ben Pfaff  <blp@gnu.org>
-
-       * float-format.c (float_get_lowest): New function.
-       
-       * magic.c: Removed.
-
-       * magic.h: Removed.  Changed all references to NOT_INT,
-       NOT_DOUBLE, and NOT_LONG to use other constants.  Changed
-       references to second_lowest_value to call float_get_lowest.
-
-2007-10-10  Ben Pfaff  <blp@gnu.org>
-
-       We assume IEEE-754 now.
-
-       * float-format.h (enum float_format): Don't check for
-       FPREP_IEEE754 macro any longer.
-
-       * magic.h: Ditto.
-
-2007-09-16  Ben Pfaff  <blp@gnu.org>
-
-       * copyleft.c: Add trailing new-lines to lack-of-warranty
-       statement.
-
-2007-09-05 John Darrington <john@darrington.wattle.id.au>
-
-       * getl.c: Add extra members to struct getl_source, to maintain the
-       error mode and the syntax_mode. 
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       * getl.c (getl_append_source): Add source to *end* of list.
-       Otherwise the list ends up in reverse order.
-
-       * automake.mk (src/libpspp/version.c): Use $HOME instead of ~ in
-       paths.  We don't interpolate ~.
-
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       * str.h: Include xstrndup.h also.
-
-       * float-format.c (float_get_double): New function.
-
-2007-07-06  Ben Pfaff  <blp@gnu.org>
-
-       * copyleft.c (legal): Update startup notice to use format
-       recommended by latest GNU coding standards.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * array.c (binary_search): Fix assertion.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Add error propagation layer.  Patch #5916, slightly revised.
-
-       * automake.mk: Add new files.
-       
-       * taint.c: New file.
-
-       * taint.h: New file.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       Add ability for reverse iteration to tower code.
-       
-       * tower.c (tower_last): New function.
-       (tower_prev): New function.
-       (abt_to_tower_node): New function.
-       (first_node): Use abt_to_tower_node.
-       (last_node): New function.
-       (next_ndoe): Use abt_to_tower_node.
-       (prev_node): New function.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       * tower.c: Cache repeated lookups of a single tower element.  This
-       turns such lookups into O(1) operations without harming the big-O
-       of other operations.
-
-       * tower.h (struct tower): Add members for caching.
-
-       * range-set.c (range_set_clone): New function.
-
-       * array.c (insert_range): New function.
-       (insert_element): New function.
-       (move_range): New function.
-
-2007-04-25  Ben Pfaff  <blp@gnu.org>
-
-       * model-checker.c: Don't use type sighandler_t, which is a GNU
-       extension.  Reported by "Daniel E WILLIAMS"
-       <Daniel.E.Williams@state.or.us>.
-
-2007-04-25 John Darrington <john@darrington.wattle.id.au>
-
-       * i18n.c: Fixed bug converting long strings
-
-2007-04-22  Ben Pfaff  <blp@gnu.org>
-
-       Patch #5884.
-       
-       * ll.h (ll_for_each_reverse): New macro.
-       (ll_for_each_reverse_continue): New macro.
-       (ll_for_each_reverse_safe): New macro.
-       (ll_for_each_safe_reverse_continue): New macro.
-       (ll_for_each_reverse_preremove): New macro.
-       (ll_for_each_reverse_postremove): New macro.
-       (ll_remove__): Removed (dead code).
-       (ll_tail__): New macro.
-       (ll_prev__): New macro.
-
-2007-04-22  Ben Pfaff  <blp@gnu.org>
-
-       Implement model checker for testing purposes.
-
-       Patch #5873.
-       
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add
-       model-checker.[ch].  Alphabetize.
-
-       * model-checker.c: New file.
-
-       * model-checker.h: New file.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-
-       Apply patches #5828, #5837, #5841, #5843.
-
-       * abt.c (insert_relative): New function.
-       (abt_insert_after): New function.
-       (abt_insert_before): New function.
-
-       * range-map.c: New file.
-
-       * range-map.h: New file.
-
-       * range-set.c: New file.
-
-       * range-set.h: New file.
-
-       * tower.c: New file.
-
-       * tower.h: New file.
-
-2007-04-01  Ben Pfaff  <blp@gnu.org>
-
-       * bt.c: Need #include <limits.h>.  Thanks to "John McCabe-Dansted"
-       <gmatht@gmail.com> for pointing this out.
-
-2007-03-31  Ben Pfaff  <blp@gnu.org>
-
-       Patch #5827.
-
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add bt.c.
-
-       * bt.h: New file.
-
-       * bt.c: New file.
-
-2007-03-30  Ben Pfaff  <blp@gnu.org>
-
-       Patch #5829.
-
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add deque.c.
-
-       * deque.h: Completely rewrote.  Adapted client to new interface.
-
-       * deque.c: New file.
-
-2007-03-25  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add
-       sparse-array.[ch].
-
-       * pool.c (pool_zalloc): New function.
-       (pool_calloc): New function.
-
-       * sparse-array.c: New file.
-
-       * sparse-array.h: New file.
-
-Mon Mar  5 20:55:49 CET 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * i18n.c: Cast second argument of iconv using ICONV_CONST
-
-2007-02-22  Ben Pfaff  <blp@gnu.org>
-
-       * string.h: Don't include vsnprintf.h any more, because gnulib has
-       now absorbed it into string.h.
-
-Thu Feb 22 12:25:52 CET 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * syntax-gen.h syntax-gen.c: New files.
-
-Sun Feb 18 11:21:41 2007  Ben Pfaff  <blp@gnu.org>
-
-       * alloc.h: Remove useless parentheses in #if "defined" operator.
-
-       * misc.h: Ditto.
-
-Tue Feb  6 20:00:13 2007  Ben Pfaff  <blp@gnu.org>
-
-       * misc.h [!HAVE_ISINF] (isinf): Define only if isinf is not
-       defined as a macro, because mingw seems to have the macro without
-       the function.
-       [!HAVE_ISNAN] (isnan): Ditto, for symmetry only.
-       [!AHVE_FINITE] (finite): Ditto, for symmetry only.
-
-Tue Feb  6 19:58:46 2007  Ben Pfaff  <blp@gnu.org>
-
-       * compiler.h (PRINTF_FORMAT): Use __printf__ instead of printf to
-       avoid problem with "#define printf libintl_printf" that libintl is
-       fond of doing.
-       (SCANF_FORMAT): Ditto, for symmetry only.
-
-Tue Feb  6 19:47:10 2007  Ben Pfaff  <blp@gnu.org>
-
-       * float-format.h: [FPREP_IEEE754] [WORDS_BIGENDIAN] Add missing
-       comma.
-
-Wed Jan 24 21:13:32 2007  Ben Pfaff  <blp@gnu.org>
-
-       * abt.c: New file.
-
-       * abt.h: New file.
-
-       * automake.mk: Add abt.c, abt.h to sources.
-
-Sun Jan 14 21:44:18 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add deque.h to sources.
-       
-       * deque.h: New file.
-
-Wed Jan 10 06:49:38 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add heap.c, heap.h to sources.
-
-       * heap.c: New file.
-
-       * heap.h: New file.
-
-Sun Dec 10 13:54:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ss_tokenize): Skip the first delimiter character
-       following the token.  Otherwise, changing delimiters from token to
-       token can't have a sensible effect, because we'll get the previous
-       delimiter as part of the next token.
-       (ss_match_string): New function.
-
-Sat Dec  9 18:48:55 2006  Ben Pfaff  <blp@gnu.org>
-
-       * misc.h (macro range): Removed, as it was unused.
-
-Sat Dec  9 07:19:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * array.c: Removed gratuitous #include
-
-Thu Dec  7 20:33:23 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * getl.c getl.h : Changed signature of create function to take a 
-       string indicating the initial include path.
-
-Sun Dec  3 11:36:10 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.h (SS_LITERAL_INITIALIZER): Cast the string literal to "char
-       *".  This normally does nothing but when GCC's -Wwrite-strings is
-       used it fixes a warning that otherwise can't be avoided.
-
-Sun Dec  3 11:35:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ss_alloc_substring_pool): New function.
-       (ss_alloc_uninit_pool) New function.
-
-Sun Dec  3 11:28:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       * getl.h: (enum getl_syntax) New enumeration to distinguish
-       between "batch" and "interactive" in a clearer way than a bool.
-       (struct getl_interface) Add an arg to "read" to return the
-       intended syntax mode.  Add an arg to "filter" to specify the
-       syntax mode of the line to filter.
-
-       * getl.c (do_read_line): Instead of returning the syntax type of
-       the line read based on whether the source itself is interactive,
-       return it based on whether the line itself should be treated as
-       having batch or interactive syntax.  Also, adapt interface to the
-       new interfaces of lex_init() and getl_interface.
-
-Wed Nov 29 19:35:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * getl.c getl.h: New files. Created interface from base of 
-       language/line-buffer.[ch]
-
-       * msg-locator.c msg-locator.h: New files. Moved from
-       language/line-buffer.[ch]
-
-Fri Nov 24 17:27:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * misc.h: (min) Removed.  All references updated to use MIN, from
-       minmax.h provided by gnulib.
-       (max) Ditto (for MAX).
-
-Sun Nov 19 09:22:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ss_get_long): New function.
-       (ss_compare_case) Ditto.
-       (ss_equals) Ditto.
-       (ss_equals_case) Ditto.
-
-Tue Oct 31 19:28:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.h: [!HAVE_STRCHR] Drop compatibility code, because now we
-       assume a C89 compliant library.  (Gnulib makes this assumption so
-       we might as well too.)
-       [!HAVE_STRRCHR] Ditto.
-
-Thu Oct 26 20:19:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add the new files.
-
-       * legacy-encoding.c: New file.
-
-       * legacy-encoding.h: New file.
-
-       * float-format.c: New file.
-
-       * float-format.h: New file.
-
-       * integer-format.c: New file.
-
-       * integer-format.h: New file.
-
-Sun Oct 15 09:49:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * hash.c hash.h: Added hsh_create_pool, a hash which uses a pool
-       for its memory allocation.
-
-Mon Jul 31 15:49:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       * compiler.h: (macro CONST_FUNCTION) New macro.
-       (macro PURE_FUNCTION) New macro.
-
-Sun Jul 16 21:07:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       * message.c: (static int messages_disabled) New variable.
-       (msg_emit) Don't emit the message if messages are disabled.
-       (msg_disable) New function.
-       (msg_enable) New function.
-
-       * str.c: (free_string) New function.
-       (ds_register_pool) New function.
-       (ds_unregister_pool) New function.
-       (ds_set_length) New function.
-
-Mon Jul 10 17:26:58 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * llx.c: #included compiler.h and removed explicit preprocessor cruft.
-
-Fri Jul  7 20:01:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Add assertion.h.
-       
-       * assertion.h: New file.  Replaced usage of assert(0) and abort()
-       with NOT_REACHED() from this file throughout the source tree.
-
-       * message.c: (request_bug_report_and_abort) Revise message printed
-       to include request to include lines above the message, which
-       should include an assertion failure message in many cases.
-       (msg_assert_fail) Removed.
-
-       * message.h: (assert) Removed.
-       (request_bug_report_and_abort) Mark NO_RETURN.
-
-Mon Jul  3 09:36:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * i18n.c: Made character conversion tolerant of failure to create the 
-       necessary iconv structs.
-
-Sat Jul  1 15:32:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Add new files.
-
-       * ll.c: New file.
-
-       * ll.h: New file.
-
-       * llx.c: New file.
-
-       * llx.h: New file.
-
-Sun Jun 25 22:35:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       Optimize rehashing: we know that none of the entries in the hash
-       table are equal, so we need not compare them to each other during
-       rehashing.
-       
-       * hash.c: (locate_empty_entry) New function.
-       (rehash) Use locate_empty_entry() instead of
-       locate_matching_entry().
-
-Fri Jun  9 14:03:29 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * str.c (ss_empty): New function.  Replaces some uses of ls_init()
-       or ls_null().
-       (ss_cstr) New function.  Replaces some uses of ls_init().
-       (ss_buffer) New function.  Replaces some uses of ls_init().
-       (ss_substr) New function.
-       (ss_head) New function.
-       (ss_tail) New function.
-       (ss_alloc_substring) New function.  Replaces use of ls_create().
-       (ss_alloc_uninit) New function.
-       (ss_dealloc) New function.  Replaces use of ls_destroy().
-       (ss_truncate) New function.
-       (ss_rtrim) New function.
-       (ss_ltrim) New function.
-       (ss_trim) New function.
-       (ss_chomp) New function.
-       (ss_separate) New function.
-       (ss_tokenize) New function.
-       (ss_advance) New function.
-       (ds_create) Renamed ds_init_cstr().  Updated all callers.
-       (ss_match_char) New function.
-       (ss_get_char) New function.
-       (ss_get_until) New function.
-       (ss_get_chars) New function.
-       (ss_is_empty) New function.
-       (ss_length) New function.  Replaces ls_length().
-       (ss_data) New function.  Replaces many uses of ls_c_str().
-       (ss_end) New function.  Replaces ls_end().
-       (ss_at) New function.
-       (ss_first) New function.
-       (ss_last) New function.
-       (ss_span) New function.
-       (ss_cspan) New function.
-       (ss_compare) New function.
-       (ss_pointer_to_position) New function.
-       (ss_xstrdup) New function.
-       (ds_init) Renamed ds_init_empty().  All callers updated.
-       (ds_init_string) New function.
-       (ds_init_substring) Changed interface to take a struct substring.
-       Updated all callers.
-       (ds_init_cstr) New function.  Replaces ds_create().  All callers
-       updated.
-       (ds_assign_substring) Changed interface to take a struct
-       substring.  Updated all callers.
-       (ds_assign_buffer) Removed.  Changed all callers to use
-       ds_assign_substring().
-       (ds_assign_c_str) Renamed ds_assign_cstr().  All callers updated.
-       (ds_ss) New function.
-       (ds_substr) New function.
-       (ds_head) New function.
-       (ds_tail) New function.
-       (ds_rtrim) New function.  Replaces ds_rtrim_spaces().  All callers
-       updated.
-       (ds_ltrim) New function.  Replaces ds_ltrim_spaces().  All callers
-       updated.
-       (ds_trim) New function.  Replaces ds_trim_spaces().  All callers
-       updated.
-       (ds_rtrim_spaces) Removed.
-       (ds_ltrim_spaces) Removed.
-       (ds_trim_spaces) Removed.
-       (ds_separate) Changed interface to use substrings.  All callers
-       updated.
-       (ds_tokenize) Changed interface to use substrings.  All callers
-       updated.
-       (ds_c_str) Renamed ds_cstr().  All callers updated.
-       (ds_span) Changed interface to use substring for SKIP_SET and
-       dropped OFS.  All callers updated.
-       (ds_cspan) Changed interface to use substring for STOP_SET and
-       dropped OFS.  All callers updated.
-       (ds_find_char) New function.
-       (ds_compare) New function.
-       (ds_pointer_to_position) New function.
-       (ds_xstrdup) New function.  Replaced all users of
-       xstrdup(ds_c_str(s)) by a call to this function.
-       (ds_gets) Renamed ds_read_line().  All callers updated.
-       (ds_get_config_line) Renamed ds_read_config_line().  All callers
-       updated.
-       (ds_puts) Renamed ds_put_cstr().  All callers updated.
-       (ds_put_substring) New function.  Replaces ds_concat().  All
-       callers updated.
-       (ds_concat) Removed.
-       (ds_append_uninit) Renamed ds_put_uninit().  All callers updated.
-       (ds_printf) Renamed ds_put_format().  All callers updated.
-       (ds_vprintf) Renamed ds_put_vformat().  All callers updated.
-       (ds_putc) Renamed ds_put_char().  All callers updated.
-       (ds_putc_multiple) Renamed ds_put_char_multiple().  All callers
-       updated.
-       (ls_create) Removed.  Replaced by ss_alloc_substring().
-       (ls_create_buffer) Removed.  Replaced by ss_alloc_substring().
-       (ls_init) Removed.  Replaced by ss_buffer().
-       (ls_shallow_copy) Removed.  Just use assignment.
-       (ls_destroy) Removed.  Replaced by ss_dealloc().
-       (ls_null) Removed.
-       (ls_null_p) Removed.
-       (ls_empty_p) Removed.  Replaced by ss_is_empty().
-       (ls_c_str) Removed.
-       (ls_end) Removed.  Replaced by ss_end().
-
-       * str.h (struct fixed_string): Renamed struct substring, updated
-       all users.
-       (CC_SPACES) New macro.
-       (CC_DIGITS) Ditto.
-       (CC_XDIGITS) Ditto.
-       (CC_LETTERS) Ditto.
-       (CC_ALNUM) Ditto.
-       (SS_EMPTY_INITIALIZER) Ditto.
-       (SS_LITERAL_INITIALIZER) Ditto.
-       (struct string) Removed string, length members.  Add substring
-       member.
-       (DS_INITIALIZER) Rename DS_EMPTY_INITIALIZER.
-
-Tue May 30 19:45:12 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * i18n.c i18n.h: New files.
-
-Tue May 16 06:50:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (src/libpspp/version.c): Removed groff_font_path,
-       which is no longer used.
-
-       * message.c (request_bug_report_and_abort): Don't print
-       groff_font_path, which no longer exists.
-
-       * version.h (locale_dir): Removed groff_font_path.
-
-Sun May 14 22:06:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (spprintf): Moved definition of spprintf() here, from
-       str.h.
-
-       * str.h: (nsprintf) Removed.  Changed all users to use sprintf()
-       instead.
-       (nvsprintf) Removed.  Changed all users to use vsprintf() instead.
-
-Sun May 14 20:52:20 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ds_init): Remove `capacity' argument and just initialize
-       the string to a capacity of zero.  Updated all callers.
-
-Tue May  9 09:56:57 2006  Ben Pfaff  <blp@gnu.org>
-
-       * va_copy.h: Removed.  Now use va_copy() provided by gnulib
-       instead.
-
-       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Removed va_copy.h.
-
-Sun May  7 18:17:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       * pool.c (pool_vasprintf): New function.
-       (pool_asprintf) New function.
-
-Sun May  7 17:09:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       * compiler.h: (macro WARN_UNUSED_RESULT) New macro.
-
-Sun May  7 14:32:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       * va_copy.h: New header.
-
-       * str.c: Use header instead of inlining va_copy() macro
-       implementation.
-
-Sun May  7 10:06:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * array.c array.h: Constness of sort.
-
-Thu May  4 18:01:37 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * message.c message.h: Added functions to create and copy a msg.
-
-Tue May  2 15:41:50 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ds_append_uninit): No need to add 1 to arg passed to
-       ds_extend(), because the argument does not include space for a
-       null terminator.  Also, fix warning.
-
-Tue Apr 25 11:07:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       Finish reforming error message support.  In this phase, move
-       message.c into libpspp.
-       
-       * message.c: Move here from src/.  Also remove a few unneeded
-       headers.
-
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add message.c. 
-
-Tue Apr 25 10:54:44 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, drop
-       actual message printing from core code, substituting a callback,
-       and add the callback to each UI.  Also, move verbose_msg() into
-       its own module.
-
-       * automake.mk (src_libpspp_libpspp_a_SOURCES): Added
-       verbose-msg.c, verbose-msg.h.
-
-       * verbose-msg.c: New file.
-
-       * verbose-msg.h: New file.
-
-Mon Apr 24 17:26:47 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, rename
-       all the message functions and types to start with "msg", except
-       for the ones that will be moving to other modules anyway.
-
-       All references to the identifiers below were updated likewise.
-       
-       * message.h: (enum file_locator) Renamed `enum msg_locator'.
-       (struct error) Renamed `struct msg'.
-       (err_assert_fail) Renamed msg_assert_fail().
-
-Sun Apr 23 22:07:06 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-       
-       * message.h: (struct error) Remove `title' member.  Add `text'
-       member.
-       
-Sun Apr 16 20:43:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we
-       divide the classification of messages along "category" and
-       "severity" axes.
-
-       * message.h: (enum msg_class) Named this set of enumerations.
-       (enum msg_category) New enum: MSG_GENERAL, MSG_SYNTAX, MSG_DATA.
-       (enum msg_severity) New enum: MSG_ERROR, MSG_WARNING, MSG_NOTE.
-       (msg_class_to_category) New inline function.
-       (msg_class_to_severity) New inline function.
-       (msg_class_from_category_and_severity) New inline function.
-       (struct error) Removed `class' member, added `category',
-       `severity'.  Updated all users of this struct to use the new
-       members.
-
-Sun Apr 16 20:33:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c (ds_vprintf): Don't try to write into the string if it is
-       null.
-
-Sun Apr 16 18:52:41 2006  Ben Pfaff  <blp@gnu.org>
-
-       GNU standards require "file name" instead of "filename" in
-       documentation.  It's nice for our code to follow the convention
-       too.
-       
-       * message.h: (struct file_locator) Rename filename member to
-       file_name.  Updated all references.
-
-Sun Apr 16 16:05:43 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we get
-       rid of VM() and the other msg() support for "verbosity", replacing
-       it by a new function verbose_msg().
-
-       * message.h: (enum ERR_CLASS_COUNT) Renamed ERR_CLASS_CNT.
-       (enum ERR_CLASS_MASK) Removed.
-       (enum ERR_VERBOSITY_SHIFT) Removed.
-       (enum ERR_VERBOSITY_MASK) Removed.
-       (macro VM) Removed.
-
-Sun Apr 16 11:48:07 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start reforming error message support.  In this phase, we get rid
-       of "installation errors" and change all uses of msg() in the
-       output drivers to uses of error() or error_at_line().
-
-       * message.h: Remove IE, IS enums.
-
-Mon Apr  3 11:10:21 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c: (ds_separate) Change interface for cleanliness and
-       consistency with ds_tokenize(), and rewrite to shorten and
-       simplify.  Updated all callers.
-       (ds_tokenize) New function.
-
-Fri Mar 31 10:38:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       Add freaderror() analogous to fwriteerror() in gnulib.
-
-       * freaderror.c: New file.
-
-       * freaderror.h: New file.
-
-Thu Mar 30 16:15:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.c: (ds_create) Adjust capacity selection.
-       (ds_init) Use MAX macro for clarity.
-       (ds_create_substr) Rewrote.
-       (ds_replace) Renamed ds_assign_c_str(), reimplemented.  Changed
-       all callers to use a ds_assign_*() function.
-       (ds_init_substring) New function.
-       (ds_assign_string) New function.
-       (ds_assign_substring) New function.
-       (ds_assign_buffer) New function.
-       (ds_assign_c_str) New function.
-       (ds_truncate) Rewrote for clarity.
-       (ds_rpad) Reimplement in terms of ds_putc_multiple().
-       (ds_ltrim_spaces) Reimplement.
-       (ds_trim_spaces) New function.
-       (ds_separate) New function.
-       (ds_c_str) Make tolerant of null pointer, allowing static
-       initialization of strings.
-       (ds_find) Rename ds_span(), change interface.
-       (ds_n_find) Rename ds_cspan(), change interface.
-       (ds_at) New function.
-       (ds_first) Reimplement in terms of ds_at().
-       (remove_comment) New function.
-       (ds_get_config_line) Reimplement in terms of other functions.
-       Change type of LINE_NUMBER parameter.  Updated all callers.
-       (ds_vprintf) Modify for clarity.
-       (ds_putc) Better to be safe than sorry.
-       (ds_putc_multiple) New function.
-
-       * str.h: (struct string) Reorder members.
-       (macro DS_INITIALIZER) New macro that can be used to initialize a
-       string (as empty).
-       (ds_c_str) Remove inline version.
-
-Tue Mar 28 13:49:11 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * str.[ch]: New functions ds_create_substr, ds_find, ds_n_find, 
-       ds_ltrim_spaces
-
-Sat Mar  4 12:59:01 2006  Ben Pfaff  <blp@gnu.org>
-
-       * compiler.h: New file.
-
-Sat Mar  4 11:55:16 2006  Ben Pfaff  <blp@gnu.org>
-
-       * str.h: Now assume that sprintf() returns the correct value.
-       Always implement spprintf as a static inline function.  Change
-       nsprintf, nvsprintf to simple macros that call sprintf, vsprintf.
-
-       * str.c: Remove spprintf, nsprintf, nvsprintf conditional
-       definitions.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/libpspp/OChangeLog b/src/libpspp/OChangeLog
new file mode 100644 (file)
index 0000000..229b4f9
--- /dev/null
@@ -0,0 +1,819 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+
+       * hash.c (hsh_hash_int): Use gsl_isnan instead of isnan, as a
+       stopgap measure for portability until appropriate gnulib modules
+       are available.
+
+       * misc.h (macro isinf): Remove implementations of isinf, isnan,
+       and finite, because they were not effective and we are now using
+       the equivalent GSL functions.
+
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6427.  Reviewed by John Darrington.
+
+       * automake.mk: Remove moved files.
+
+       * syntax-gen.c: Moved to src/ui (and rewritten).
+
+       * syntax-gen.h: Ditto.
+
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6441.  Reviewed by John Darrington.
+
+       * str.c (ss_match_char_in): New function.
+
+2008-02-18  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6426.  Thanks to John Darrington for review.
+
+       * str.c (ds_read_line): Add argument to limit the length of the
+       line to be read.  Update all callers.
+
+2008-02-01  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6386.  Thanks to John Darrington for review.
+
+       * str.c (str_format_26adic): New function.
+
+2007-12-24  John Darrington <john@darrington.wattle.id.au>
+
+        * taint.c (taint_destroy): Return true if pointer is null.
+
+2007-11-25  Ben Pfaff  <blp@gnu.org>
+
+       * float-format.c (assemble_number): Only store 32 bits for Z short
+       format.  Partial fix for bug #21590.
+
+2007-11-08  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ds_read_stream): Change return value semantics to be more
+       useful.  Update all users.
+
+2007-11-03 John Darrington <john@darrington.wattle.id.au>
+
+       * i18n.c i18n.h: Added convertor from UTF8 to system.
+       This is needed for reading gnumeric files (and possibly others).
+
+2007-10-11  Ben Pfaff  <blp@gnu.org>
+
+       * xalloc.h: Removed.  Changed all users to include "xalloc.h" from
+       gnulib instead.
+
+       * xalloc.c: Removed.
+
+2007-10-11  Ben Pfaff  <blp@gnu.org>
+
+       * alloc.h (local_alloc): Removed.  Changed all users to use
+       xmalloca instead.
+       (local_free): Removed.  Changed all users to use freea instead.
+
+2007-10-11  Ben Pfaff  <blp@gnu.org>
+
+       * float-format.c (float_get_lowest): New function.
+       
+       * magic.c: Removed.
+
+       * magic.h: Removed.  Changed all references to NOT_INT,
+       NOT_DOUBLE, and NOT_LONG to use other constants.  Changed
+       references to second_lowest_value to call float_get_lowest.
+
+2007-10-10  Ben Pfaff  <blp@gnu.org>
+
+       We assume IEEE-754 now.
+
+       * float-format.h (enum float_format): Don't check for
+       FPREP_IEEE754 macro any longer.
+
+       * magic.h: Ditto.
+
+2007-09-16  Ben Pfaff  <blp@gnu.org>
+
+       * copyleft.c: Add trailing new-lines to lack-of-warranty
+       statement.
+
+2007-09-05 John Darrington <john@darrington.wattle.id.au>
+
+       * getl.c: Add extra members to struct getl_source, to maintain the
+       error mode and the syntax_mode. 
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       * getl.c (getl_append_source): Add source to *end* of list.
+       Otherwise the list ends up in reverse order.
+
+       * automake.mk (src/libpspp/version.c): Use $HOME instead of ~ in
+       paths.  We don't interpolate ~.
+
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       * str.h: Include xstrndup.h also.
+
+       * float-format.c (float_get_double): New function.
+
+2007-07-06  Ben Pfaff  <blp@gnu.org>
+
+       * copyleft.c (legal): Update startup notice to use format
+       recommended by latest GNU coding standards.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * array.c (binary_search): Fix assertion.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Add error propagation layer.  Patch #5916, slightly revised.
+
+       * automake.mk: Add new files.
+       
+       * taint.c: New file.
+
+       * taint.h: New file.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       Add ability for reverse iteration to tower code.
+       
+       * tower.c (tower_last): New function.
+       (tower_prev): New function.
+       (abt_to_tower_node): New function.
+       (first_node): Use abt_to_tower_node.
+       (last_node): New function.
+       (next_ndoe): Use abt_to_tower_node.
+       (prev_node): New function.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       * tower.c: Cache repeated lookups of a single tower element.  This
+       turns such lookups into O(1) operations without harming the big-O
+       of other operations.
+
+       * tower.h (struct tower): Add members for caching.
+
+       * range-set.c (range_set_clone): New function.
+
+       * array.c (insert_range): New function.
+       (insert_element): New function.
+       (move_range): New function.
+
+2007-04-25  Ben Pfaff  <blp@gnu.org>
+
+       * model-checker.c: Don't use type sighandler_t, which is a GNU
+       extension.  Reported by "Daniel E WILLIAMS"
+       <Daniel.E.Williams@state.or.us>.
+
+2007-04-25 John Darrington <john@darrington.wattle.id.au>
+
+       * i18n.c: Fixed bug converting long strings
+
+2007-04-22  Ben Pfaff  <blp@gnu.org>
+
+       Patch #5884.
+       
+       * ll.h (ll_for_each_reverse): New macro.
+       (ll_for_each_reverse_continue): New macro.
+       (ll_for_each_reverse_safe): New macro.
+       (ll_for_each_safe_reverse_continue): New macro.
+       (ll_for_each_reverse_preremove): New macro.
+       (ll_for_each_reverse_postremove): New macro.
+       (ll_remove__): Removed (dead code).
+       (ll_tail__): New macro.
+       (ll_prev__): New macro.
+
+2007-04-22  Ben Pfaff  <blp@gnu.org>
+
+       Implement model checker for testing purposes.
+
+       Patch #5873.
+       
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add
+       model-checker.[ch].  Alphabetize.
+
+       * model-checker.c: New file.
+
+       * model-checker.h: New file.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+
+       Apply patches #5828, #5837, #5841, #5843.
+
+       * abt.c (insert_relative): New function.
+       (abt_insert_after): New function.
+       (abt_insert_before): New function.
+
+       * range-map.c: New file.
+
+       * range-map.h: New file.
+
+       * range-set.c: New file.
+
+       * range-set.h: New file.
+
+       * tower.c: New file.
+
+       * tower.h: New file.
+
+2007-04-01  Ben Pfaff  <blp@gnu.org>
+
+       * bt.c: Need #include <limits.h>.  Thanks to "John McCabe-Dansted"
+       <gmatht@gmail.com> for pointing this out.
+
+2007-03-31  Ben Pfaff  <blp@gnu.org>
+
+       Patch #5827.
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add bt.c.
+
+       * bt.h: New file.
+
+       * bt.c: New file.
+
+2007-03-30  Ben Pfaff  <blp@gnu.org>
+
+       Patch #5829.
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add deque.c.
+
+       * deque.h: Completely rewrote.  Adapted client to new interface.
+
+       * deque.c: New file.
+
+2007-03-25  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add
+       sparse-array.[ch].
+
+       * pool.c (pool_zalloc): New function.
+       (pool_calloc): New function.
+
+       * sparse-array.c: New file.
+
+       * sparse-array.h: New file.
+
+Mon Mar  5 20:55:49 CET 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * i18n.c: Cast second argument of iconv using ICONV_CONST
+
+2007-02-22  Ben Pfaff  <blp@gnu.org>
+
+       * string.h: Don't include vsnprintf.h any more, because gnulib has
+       now absorbed it into string.h.
+
+Thu Feb 22 12:25:52 CET 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * syntax-gen.h syntax-gen.c: New files.
+
+Sun Feb 18 11:21:41 2007  Ben Pfaff  <blp@gnu.org>
+
+       * alloc.h: Remove useless parentheses in #if "defined" operator.
+
+       * misc.h: Ditto.
+
+Tue Feb  6 20:00:13 2007  Ben Pfaff  <blp@gnu.org>
+
+       * misc.h [!HAVE_ISINF] (isinf): Define only if isinf is not
+       defined as a macro, because mingw seems to have the macro without
+       the function.
+       [!HAVE_ISNAN] (isnan): Ditto, for symmetry only.
+       [!AHVE_FINITE] (finite): Ditto, for symmetry only.
+
+Tue Feb  6 19:58:46 2007  Ben Pfaff  <blp@gnu.org>
+
+       * compiler.h (PRINTF_FORMAT): Use __printf__ instead of printf to
+       avoid problem with "#define printf libintl_printf" that libintl is
+       fond of doing.
+       (SCANF_FORMAT): Ditto, for symmetry only.
+
+Tue Feb  6 19:47:10 2007  Ben Pfaff  <blp@gnu.org>
+
+       * float-format.h: [FPREP_IEEE754] [WORDS_BIGENDIAN] Add missing
+       comma.
+
+Wed Jan 24 21:13:32 2007  Ben Pfaff  <blp@gnu.org>
+
+       * abt.c: New file.
+
+       * abt.h: New file.
+
+       * automake.mk: Add abt.c, abt.h to sources.
+
+Sun Jan 14 21:44:18 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add deque.h to sources.
+       
+       * deque.h: New file.
+
+Wed Jan 10 06:49:38 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add heap.c, heap.h to sources.
+
+       * heap.c: New file.
+
+       * heap.h: New file.
+
+Sun Dec 10 13:54:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ss_tokenize): Skip the first delimiter character
+       following the token.  Otherwise, changing delimiters from token to
+       token can't have a sensible effect, because we'll get the previous
+       delimiter as part of the next token.
+       (ss_match_string): New function.
+
+Sat Dec  9 18:48:55 2006  Ben Pfaff  <blp@gnu.org>
+
+       * misc.h (macro range): Removed, as it was unused.
+
+Sat Dec  9 07:19:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * array.c: Removed gratuitous #include
+
+Thu Dec  7 20:33:23 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * getl.c getl.h : Changed signature of create function to take a 
+       string indicating the initial include path.
+
+Sun Dec  3 11:36:10 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.h (SS_LITERAL_INITIALIZER): Cast the string literal to "char
+       *".  This normally does nothing but when GCC's -Wwrite-strings is
+       used it fixes a warning that otherwise can't be avoided.
+
+Sun Dec  3 11:35:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ss_alloc_substring_pool): New function.
+       (ss_alloc_uninit_pool) New function.
+
+Sun Dec  3 11:28:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       * getl.h: (enum getl_syntax) New enumeration to distinguish
+       between "batch" and "interactive" in a clearer way than a bool.
+       (struct getl_interface) Add an arg to "read" to return the
+       intended syntax mode.  Add an arg to "filter" to specify the
+       syntax mode of the line to filter.
+
+       * getl.c (do_read_line): Instead of returning the syntax type of
+       the line read based on whether the source itself is interactive,
+       return it based on whether the line itself should be treated as
+       having batch or interactive syntax.  Also, adapt interface to the
+       new interfaces of lex_init() and getl_interface.
+
+Wed Nov 29 19:35:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * getl.c getl.h: New files. Created interface from base of 
+       language/line-buffer.[ch]
+
+       * msg-locator.c msg-locator.h: New files. Moved from
+       language/line-buffer.[ch]
+
+Fri Nov 24 17:27:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * misc.h: (min) Removed.  All references updated to use MIN, from
+       minmax.h provided by gnulib.
+       (max) Ditto (for MAX).
+
+Sun Nov 19 09:22:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ss_get_long): New function.
+       (ss_compare_case) Ditto.
+       (ss_equals) Ditto.
+       (ss_equals_case) Ditto.
+
+Tue Oct 31 19:28:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.h: [!HAVE_STRCHR] Drop compatibility code, because now we
+       assume a C89 compliant library.  (Gnulib makes this assumption so
+       we might as well too.)
+       [!HAVE_STRRCHR] Ditto.
+
+Thu Oct 26 20:19:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add the new files.
+
+       * legacy-encoding.c: New file.
+
+       * legacy-encoding.h: New file.
+
+       * float-format.c: New file.
+
+       * float-format.h: New file.
+
+       * integer-format.c: New file.
+
+       * integer-format.h: New file.
+
+Sun Oct 15 09:49:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * hash.c hash.h: Added hsh_create_pool, a hash which uses a pool
+       for its memory allocation.
+
+Mon Jul 31 15:49:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       * compiler.h: (macro CONST_FUNCTION) New macro.
+       (macro PURE_FUNCTION) New macro.
+
+Sun Jul 16 21:07:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       * message.c: (static int messages_disabled) New variable.
+       (msg_emit) Don't emit the message if messages are disabled.
+       (msg_disable) New function.
+       (msg_enable) New function.
+
+       * str.c: (free_string) New function.
+       (ds_register_pool) New function.
+       (ds_unregister_pool) New function.
+       (ds_set_length) New function.
+
+Mon Jul 10 17:26:58 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * llx.c: #included compiler.h and removed explicit preprocessor cruft.
+
+Fri Jul  7 20:01:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Add assertion.h.
+       
+       * assertion.h: New file.  Replaced usage of assert(0) and abort()
+       with NOT_REACHED() from this file throughout the source tree.
+
+       * message.c: (request_bug_report_and_abort) Revise message printed
+       to include request to include lines above the message, which
+       should include an assertion failure message in many cases.
+       (msg_assert_fail) Removed.
+
+       * message.h: (assert) Removed.
+       (request_bug_report_and_abort) Mark NO_RETURN.
+
+Mon Jul  3 09:36:42 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * i18n.c: Made character conversion tolerant of failure to create the 
+       necessary iconv structs.
+
+Sat Jul  1 15:32:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Add new files.
+
+       * ll.c: New file.
+
+       * ll.h: New file.
+
+       * llx.c: New file.
+
+       * llx.h: New file.
+
+Sun Jun 25 22:35:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       Optimize rehashing: we know that none of the entries in the hash
+       table are equal, so we need not compare them to each other during
+       rehashing.
+       
+       * hash.c: (locate_empty_entry) New function.
+       (rehash) Use locate_empty_entry() instead of
+       locate_matching_entry().
+
+Fri Jun  9 14:03:29 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * str.c (ss_empty): New function.  Replaces some uses of ls_init()
+       or ls_null().
+       (ss_cstr) New function.  Replaces some uses of ls_init().
+       (ss_buffer) New function.  Replaces some uses of ls_init().
+       (ss_substr) New function.
+       (ss_head) New function.
+       (ss_tail) New function.
+       (ss_alloc_substring) New function.  Replaces use of ls_create().
+       (ss_alloc_uninit) New function.
+       (ss_dealloc) New function.  Replaces use of ls_destroy().
+       (ss_truncate) New function.
+       (ss_rtrim) New function.
+       (ss_ltrim) New function.
+       (ss_trim) New function.
+       (ss_chomp) New function.
+       (ss_separate) New function.
+       (ss_tokenize) New function.
+       (ss_advance) New function.
+       (ds_create) Renamed ds_init_cstr().  Updated all callers.
+       (ss_match_char) New function.
+       (ss_get_char) New function.
+       (ss_get_until) New function.
+       (ss_get_chars) New function.
+       (ss_is_empty) New function.
+       (ss_length) New function.  Replaces ls_length().
+       (ss_data) New function.  Replaces many uses of ls_c_str().
+       (ss_end) New function.  Replaces ls_end().
+       (ss_at) New function.
+       (ss_first) New function.
+       (ss_last) New function.
+       (ss_span) New function.
+       (ss_cspan) New function.
+       (ss_compare) New function.
+       (ss_pointer_to_position) New function.
+       (ss_xstrdup) New function.
+       (ds_init) Renamed ds_init_empty().  All callers updated.
+       (ds_init_string) New function.
+       (ds_init_substring) Changed interface to take a struct substring.
+       Updated all callers.
+       (ds_init_cstr) New function.  Replaces ds_create().  All callers
+       updated.
+       (ds_assign_substring) Changed interface to take a struct
+       substring.  Updated all callers.
+       (ds_assign_buffer) Removed.  Changed all callers to use
+       ds_assign_substring().
+       (ds_assign_c_str) Renamed ds_assign_cstr().  All callers updated.
+       (ds_ss) New function.
+       (ds_substr) New function.
+       (ds_head) New function.
+       (ds_tail) New function.
+       (ds_rtrim) New function.  Replaces ds_rtrim_spaces().  All callers
+       updated.
+       (ds_ltrim) New function.  Replaces ds_ltrim_spaces().  All callers
+       updated.
+       (ds_trim) New function.  Replaces ds_trim_spaces().  All callers
+       updated.
+       (ds_rtrim_spaces) Removed.
+       (ds_ltrim_spaces) Removed.
+       (ds_trim_spaces) Removed.
+       (ds_separate) Changed interface to use substrings.  All callers
+       updated.
+       (ds_tokenize) Changed interface to use substrings.  All callers
+       updated.
+       (ds_c_str) Renamed ds_cstr().  All callers updated.
+       (ds_span) Changed interface to use substring for SKIP_SET and
+       dropped OFS.  All callers updated.
+       (ds_cspan) Changed interface to use substring for STOP_SET and
+       dropped OFS.  All callers updated.
+       (ds_find_char) New function.
+       (ds_compare) New function.
+       (ds_pointer_to_position) New function.
+       (ds_xstrdup) New function.  Replaced all users of
+       xstrdup(ds_c_str(s)) by a call to this function.
+       (ds_gets) Renamed ds_read_line().  All callers updated.
+       (ds_get_config_line) Renamed ds_read_config_line().  All callers
+       updated.
+       (ds_puts) Renamed ds_put_cstr().  All callers updated.
+       (ds_put_substring) New function.  Replaces ds_concat().  All
+       callers updated.
+       (ds_concat) Removed.
+       (ds_append_uninit) Renamed ds_put_uninit().  All callers updated.
+       (ds_printf) Renamed ds_put_format().  All callers updated.
+       (ds_vprintf) Renamed ds_put_vformat().  All callers updated.
+       (ds_putc) Renamed ds_put_char().  All callers updated.
+       (ds_putc_multiple) Renamed ds_put_char_multiple().  All callers
+       updated.
+       (ls_create) Removed.  Replaced by ss_alloc_substring().
+       (ls_create_buffer) Removed.  Replaced by ss_alloc_substring().
+       (ls_init) Removed.  Replaced by ss_buffer().
+       (ls_shallow_copy) Removed.  Just use assignment.
+       (ls_destroy) Removed.  Replaced by ss_dealloc().
+       (ls_null) Removed.
+       (ls_null_p) Removed.
+       (ls_empty_p) Removed.  Replaced by ss_is_empty().
+       (ls_c_str) Removed.
+       (ls_end) Removed.  Replaced by ss_end().
+
+       * str.h (struct fixed_string): Renamed struct substring, updated
+       all users.
+       (CC_SPACES) New macro.
+       (CC_DIGITS) Ditto.
+       (CC_XDIGITS) Ditto.
+       (CC_LETTERS) Ditto.
+       (CC_ALNUM) Ditto.
+       (SS_EMPTY_INITIALIZER) Ditto.
+       (SS_LITERAL_INITIALIZER) Ditto.
+       (struct string) Removed string, length members.  Add substring
+       member.
+       (DS_INITIALIZER) Rename DS_EMPTY_INITIALIZER.
+
+Tue May 30 19:45:12 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * i18n.c i18n.h: New files.
+
+Tue May 16 06:50:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (src/libpspp/version.c): Removed groff_font_path,
+       which is no longer used.
+
+       * message.c (request_bug_report_and_abort): Don't print
+       groff_font_path, which no longer exists.
+
+       * version.h (locale_dir): Removed groff_font_path.
+
+Sun May 14 22:06:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (spprintf): Moved definition of spprintf() here, from
+       str.h.
+
+       * str.h: (nsprintf) Removed.  Changed all users to use sprintf()
+       instead.
+       (nvsprintf) Removed.  Changed all users to use vsprintf() instead.
+
+Sun May 14 20:52:20 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ds_init): Remove `capacity' argument and just initialize
+       the string to a capacity of zero.  Updated all callers.
+
+Tue May  9 09:56:57 2006  Ben Pfaff  <blp@gnu.org>
+
+       * va_copy.h: Removed.  Now use va_copy() provided by gnulib
+       instead.
+
+       * automake.mk: (src_libpspp_libpspp_a_SOURCES) Removed va_copy.h.
+
+Sun May  7 18:17:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * pool.c (pool_vasprintf): New function.
+       (pool_asprintf) New function.
+
+Sun May  7 17:09:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       * compiler.h: (macro WARN_UNUSED_RESULT) New macro.
+
+Sun May  7 14:32:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       * va_copy.h: New header.
+
+       * str.c: Use header instead of inlining va_copy() macro
+       implementation.
+
+Sun May  7 10:06:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * array.c array.h: Constness of sort.
+
+Thu May  4 18:01:37 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * message.c message.h: Added functions to create and copy a msg.
+
+Tue May  2 15:41:50 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ds_append_uninit): No need to add 1 to arg passed to
+       ds_extend(), because the argument does not include space for a
+       null terminator.  Also, fix warning.
+
+Tue Apr 25 11:07:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Finish reforming error message support.  In this phase, move
+       message.c into libpspp.
+       
+       * message.c: Move here from src/.  Also remove a few unneeded
+       headers.
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Add message.c. 
+
+Tue Apr 25 10:54:44 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk (src_libpspp_libpspp_a_SOURCES): Added
+       verbose-msg.c, verbose-msg.h.
+
+       * verbose-msg.c: New file.
+
+       * verbose-msg.h: New file.
+
+Mon Apr 24 17:26:47 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, rename
+       all the message functions and types to start with "msg", except
+       for the ones that will be moving to other modules anyway.
+
+       All references to the identifiers below were updated likewise.
+       
+       * message.h: (enum file_locator) Renamed `enum msg_locator'.
+       (struct error) Renamed `struct msg'.
+       (err_assert_fail) Renamed msg_assert_fail().
+
+Sun Apr 23 22:07:06 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+       
+       * message.h: (struct error) Remove `title' member.  Add `text'
+       member.
+       
+Sun Apr 16 20:43:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we
+       divide the classification of messages along "category" and
+       "severity" axes.
+
+       * message.h: (enum msg_class) Named this set of enumerations.
+       (enum msg_category) New enum: MSG_GENERAL, MSG_SYNTAX, MSG_DATA.
+       (enum msg_severity) New enum: MSG_ERROR, MSG_WARNING, MSG_NOTE.
+       (msg_class_to_category) New inline function.
+       (msg_class_to_severity) New inline function.
+       (msg_class_from_category_and_severity) New inline function.
+       (struct error) Removed `class' member, added `category',
+       `severity'.  Updated all users of this struct to use the new
+       members.
+
+Sun Apr 16 20:33:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c (ds_vprintf): Don't try to write into the string if it is
+       null.
+
+Sun Apr 16 18:52:41 2006  Ben Pfaff  <blp@gnu.org>
+
+       GNU standards require "file name" instead of "filename" in
+       documentation.  It's nice for our code to follow the convention
+       too.
+       
+       * message.h: (struct file_locator) Rename filename member to
+       file_name.  Updated all references.
+
+Sun Apr 16 16:05:43 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we get
+       rid of VM() and the other msg() support for "verbosity", replacing
+       it by a new function verbose_msg().
+
+       * message.h: (enum ERR_CLASS_COUNT) Renamed ERR_CLASS_CNT.
+       (enum ERR_CLASS_MASK) Removed.
+       (enum ERR_VERBOSITY_SHIFT) Removed.
+       (enum ERR_VERBOSITY_MASK) Removed.
+       (macro VM) Removed.
+
+Sun Apr 16 11:48:07 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start reforming error message support.  In this phase, we get rid
+       of "installation errors" and change all uses of msg() in the
+       output drivers to uses of error() or error_at_line().
+
+       * message.h: Remove IE, IS enums.
+
+Mon Apr  3 11:10:21 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c: (ds_separate) Change interface for cleanliness and
+       consistency with ds_tokenize(), and rewrite to shorten and
+       simplify.  Updated all callers.
+       (ds_tokenize) New function.
+
+Fri Mar 31 10:38:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       Add freaderror() analogous to fwriteerror() in gnulib.
+
+       * freaderror.c: New file.
+
+       * freaderror.h: New file.
+
+Thu Mar 30 16:15:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.c: (ds_create) Adjust capacity selection.
+       (ds_init) Use MAX macro for clarity.
+       (ds_create_substr) Rewrote.
+       (ds_replace) Renamed ds_assign_c_str(), reimplemented.  Changed
+       all callers to use a ds_assign_*() function.
+       (ds_init_substring) New function.
+       (ds_assign_string) New function.
+       (ds_assign_substring) New function.
+       (ds_assign_buffer) New function.
+       (ds_assign_c_str) New function.
+       (ds_truncate) Rewrote for clarity.
+       (ds_rpad) Reimplement in terms of ds_putc_multiple().
+       (ds_ltrim_spaces) Reimplement.
+       (ds_trim_spaces) New function.
+       (ds_separate) New function.
+       (ds_c_str) Make tolerant of null pointer, allowing static
+       initialization of strings.
+       (ds_find) Rename ds_span(), change interface.
+       (ds_n_find) Rename ds_cspan(), change interface.
+       (ds_at) New function.
+       (ds_first) Reimplement in terms of ds_at().
+       (remove_comment) New function.
+       (ds_get_config_line) Reimplement in terms of other functions.
+       Change type of LINE_NUMBER parameter.  Updated all callers.
+       (ds_vprintf) Modify for clarity.
+       (ds_putc) Better to be safe than sorry.
+       (ds_putc_multiple) New function.
+
+       * str.h: (struct string) Reorder members.
+       (macro DS_INITIALIZER) New macro that can be used to initialize a
+       string (as empty).
+       (ds_c_str) Remove inline version.
+
+Tue Mar 28 13:49:11 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * str.[ch]: New functions ds_create_substr, ds_find, ds_n_find, 
+       ds_ltrim_spaces
+
+Sat Mar  4 12:59:01 2006  Ben Pfaff  <blp@gnu.org>
+
+       * compiler.h: New file.
+
+Sat Mar  4 11:55:16 2006  Ben Pfaff  <blp@gnu.org>
+
+       * str.h: Now assume that sprintf() returns the correct value.
+       Always implement spprintf as a static inline function.  Change
+       nsprintf, nvsprintf to simple macros that call sprintf, vsprintf.
+
+       * str.c: Remove spprintf, nsprintf, nvsprintf conditional
+       definitions.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index a697e4021b3c6893d6061875cce62db02c30f234..0c20643bbc71908cd818b1d1de81d9430ba40539 100644 (file)
@@ -1,9 +1,9 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
 
-noinst_LIBRARIES += src/libpspp/libpspp.a
+noinst_LTLIBRARIES += src/libpspp/libpspp.la
 
-src_libpspp_libpspp_a_SOURCES = \
+src_libpspp_libpspp_la_SOURCES = \
        src/libpspp/abt.c \
        src/libpspp/abt.h \
        src/libpspp/array.c \
@@ -23,10 +23,16 @@ src_libpspp_libpspp_a_SOURCES = \
        src/libpspp/freaderror.h \
        src/libpspp/getl.c \
        src/libpspp/getl.h \
+       src/libpspp/hash-functions.c \
+       src/libpspp/hash-functions.h \
        src/libpspp/hash.c \
        src/libpspp/hash.h \
        src/libpspp/heap.c \
        src/libpspp/heap.h \
+       src/libpspp/hmap.c \
+       src/libpspp/hmap.h \
+       src/libpspp/hmapx.c \
+       src/libpspp/hmapx.h \
        src/libpspp/i18n.c \
        src/libpspp/i18n.h \
        src/libpspp/integer-format.c \
@@ -41,8 +47,6 @@ src_libpspp_libpspp_a_SOURCES = \
        src/libpspp/message.h \
        src/libpspp/misc.c \
        src/libpspp/misc.h \
-       src/libpspp/model-checker.c \
-       src/libpspp/model-checker.h \
        src/libpspp/msg-locator.c \
        src/libpspp/msg-locator.h \
        src/libpspp/pool.c \
@@ -67,9 +71,9 @@ src_libpspp_libpspp_a_SOURCES = \
 
 DISTCLEANFILES+=src/libpspp/version.c
 
-src_libpspp_libpspp_a_CPPFLAGS = -I $(top_srcdir)/src/libpspp $(AM_CPPFLAGS)
+src_libpspp_libpspp_la_CPPFLAGS = -I $(top_srcdir)/src/libpspp $(AM_CPPFLAGS)
 
-nodist_src_libpspp_libpspp_a_SOURCES = src/libpspp/version.c
+nodist_src_libpspp_libpspp_la_SOURCES = src/libpspp/version.c
 
 src/libpspp/version.c: $(top_srcdir)/AUTHORS
        @$(MKDIR_P) src/libpspp
@@ -91,3 +95,5 @@ src/libpspp/version.c: $(top_srcdir)/AUTHORS
        sed -e 's/^/  \"/' -e 's/$$/\",/' $(top_srcdir)/AUTHORS >> $@
        echo "0 };" >> $@
 
+
+EXTRA_DIST += src/libpspp/OChangeLog
diff --git a/src/libpspp/hash-functions.c b/src/libpspp/hash-functions.c
new file mode 100644 (file)
index 0000000..2318777
--- /dev/null
@@ -0,0 +1,90 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 1997-9, 2000, 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <libpspp/hash-functions.h>
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+
+/* Fowler-Noll-Vo hash constants, for 32-bit word sizes. */
+#define FNV_32_PRIME 16777619u
+#define FNV_32_BASIS 2166136261u
+
+/* Fowler-Noll-Vo 32-bit hash, for bytes. */
+unsigned
+hsh_hash_bytes (const void *buf_, size_t size)
+{
+  const unsigned char *buf = (const unsigned char *) buf_;
+  unsigned hash;
+
+  assert (buf != NULL);
+
+  hash = FNV_32_BASIS;
+  while (size-- > 0)
+    hash = (hash * FNV_32_PRIME) ^ *buf++;
+
+  return hash;
+}
+
+/* Fowler-Noll-Vo 32-bit hash, for strings. */
+unsigned
+hsh_hash_string (const char *s_)
+{
+  const unsigned char *s = (const unsigned char *) s_;
+  unsigned hash;
+
+  assert (s != NULL);
+
+  hash = FNV_32_BASIS;
+  while (*s != '\0')
+    hash = (hash * FNV_32_PRIME) ^ *s++;
+
+  return hash;
+}
+
+/* Fowler-Noll-Vo 32-bit hash, for case-insensitive strings. */
+unsigned
+hsh_hash_case_string (const char *s_)
+{
+  const unsigned char *s = (const unsigned char *) s_;
+  unsigned hash;
+
+  assert (s != NULL);
+
+  hash = FNV_32_BASIS;
+  while (*s != '\0')
+    hash = (hash * FNV_32_PRIME) ^ toupper (*s++);
+
+  return hash;
+}
+
+/* Hash for ints. */
+unsigned
+hsh_hash_int (int i)
+{
+  return hsh_hash_bytes (&i, sizeof i);
+}
+
+/* Hash for double. */
+unsigned
+hsh_hash_double (double d)
+{
+  if (!isnan (d))
+    return hsh_hash_bytes (&d, sizeof d);
+  else
+    return 0;
+}
diff --git a/src/libpspp/hash-functions.h b/src/libpspp/hash-functions.h
new file mode 100644 (file)
index 0000000..328f4de
--- /dev/null
@@ -0,0 +1,28 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBPSPP_HASH_FUNCTIONS_H
+#define LIBPSPP_HASH_FUNCTIONS_H 1
+
+#include <stddef.h>
+
+unsigned hsh_hash_bytes (const void *, size_t);
+unsigned hsh_hash_string (const char *);
+unsigned hsh_hash_case_string (const char *);
+unsigned hsh_hash_int (int);
+unsigned hsh_hash_double (double);
+
+#endif /* libpspp/hash-functions.h */
index 627751e16adcdd8d9dacee018a44741de2c17903..eb43b54e7fedf24d7db0dd569cc34d885bb91dd4 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2008 Free Software Foundation, Inc.
 
    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
@@ -19,8 +19,6 @@
 #include "hash.h"
 #include "message.h"
 #include <assert.h>
-#include <ctype.h>
-#include <gsl/gsl_math.h>
 #include <limits.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -71,74 +69,6 @@ next_power_of_2 (size_t x)
     }
 }
 
-/* Fowler-Noll-Vo hash constants, for 32-bit word sizes. */
-#define FNV_32_PRIME 16777619u
-#define FNV_32_BASIS 2166136261u
-
-/* Fowler-Noll-Vo 32-bit hash, for bytes. */
-unsigned
-hsh_hash_bytes (const void *buf_, size_t size)
-{
-  const unsigned char *buf = (const unsigned char *) buf_;
-  unsigned hash;
-
-  assert (buf != NULL);
-
-  hash = FNV_32_BASIS;
-  while (size-- > 0)
-    hash = (hash * FNV_32_PRIME) ^ *buf++;
-
-  return hash;
-}
-
-/* Fowler-Noll-Vo 32-bit hash, for strings. */
-unsigned
-hsh_hash_string (const char *s_)
-{
-  const unsigned char *s = (const unsigned char *) s_;
-  unsigned hash;
-
-  assert (s != NULL);
-
-  hash = FNV_32_BASIS;
-  while (*s != '\0')
-    hash = (hash * FNV_32_PRIME) ^ *s++;
-
-  return hash;
-}
-
-/* Fowler-Noll-Vo 32-bit hash, for case-insensitive strings. */
-unsigned
-hsh_hash_case_string (const char *s_)
-{
-  const unsigned char *s = (const unsigned char *) s_;
-  unsigned hash;
-
-  assert (s != NULL);
-
-  hash = FNV_32_BASIS;
-  while (*s != '\0')
-    hash = (hash * FNV_32_PRIME) ^ toupper (*s++);
-
-  return hash;
-}
-
-/* Hash for ints. */
-unsigned
-hsh_hash_int (int i)
-{
-  return hsh_hash_bytes (&i, sizeof i);
-}
-
-/* Hash for double. */
-unsigned
-hsh_hash_double (double d)
-{
-  if (!gsl_isnan (d))
-    return hsh_hash_bytes (&d, sizeof d);
-  else
-    return 0;
-}
 \f
 /* Hash tables. */
 
index 59efbe56223a21e8bb253ea972d914148544b1d5..57fc2678d09548ad50922b9130298afb6cf80cac 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stddef.h>
 #include <stdbool.h>
+#include <libpspp/hash-functions.h>
 
 typedef int hsh_compare_func (const void *, const void *, const void *aux);
 typedef unsigned hsh_hash_func (const void *, const void *aux);
@@ -30,13 +31,6 @@ struct hsh_iterator
     size_t next;               /* Index of next entry. */
   };
 
-/* Hash functions. */
-unsigned hsh_hash_bytes (const void *, size_t);
-unsigned hsh_hash_string (const char *);
-unsigned hsh_hash_case_string (const char *);
-unsigned hsh_hash_int (int);
-unsigned hsh_hash_double (double);
-
 /* Hash tables. */
 struct hsh_table *hsh_create (int m, hsh_compare_func *,
                               hsh_hash_func *, hsh_free_func *,
diff --git a/src/libpspp/hmap.c b/src/libpspp/hmap.c
new file mode 100644 (file)
index 0000000..081d7cb
--- /dev/null
@@ -0,0 +1,186 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libpspp/hmap.h>
+#include <assert.h>
+#include <stdlib.h>
+
+static size_t capacity_to_mask (size_t capacity);
+
+/* Initializes MAP as a new hash map that is initially empty. */
+void
+hmap_init (struct hmap *map)
+{
+  map->count = 0;
+  map->mask = 0;
+  map->buckets = &map->one;
+  map->one = NULL;
+}
+
+/* Exchanges the contents of hash maps A and B. */
+void
+hmap_swap (struct hmap *a, struct hmap *b)
+{
+  struct hmap tmp = *a;
+  *a = *b;
+  *b = tmp;
+  if (!a->mask)
+    a->buckets = &a->one;
+  if (!b->mask)
+    b->buckets = &b->one;
+}
+
+/* Frees the memory, if any, allocated by hash map MAP.  This has
+   no effect on the actual data items in MAP, if any, because the
+   client is responsible for allocating and freeing them.  It
+   could, however, render them inaccessible if the only pointers
+   to them were from MAP itself, so in such a situation one
+   should iterate through the map and free the data items before
+   destroying it. */
+void
+hmap_destroy (struct hmap *map) 
+{
+  if (map != NULL && map->buckets != &map->one) 
+    free (map->buckets);
+}
+
+/* Reallocates MAP's hash buckets so that NEW_MASK becomes the
+   hash value bit-mask used to choose a hash bucket, then
+   rehashes any data elements in MAP into the new hash buckets.
+
+   NEW_MASK must be a power of 2 minus 1 (including 0), that is,
+   its value in binary must be all 1-bits.  */
+static void
+hmap_rehash (struct hmap *map, size_t new_mask) 
+{
+  struct hmap_node **new_buckets;
+  struct hmap_node *node, *next;
+
+  assert ((new_mask & (new_mask + 1)) == 0);
+  if (new_mask)
+    new_buckets = calloc (new_mask + 1, sizeof *new_buckets);
+  else 
+    {
+      new_buckets = &map->one;
+      new_buckets[0] = NULL;
+    }
+      
+  if (map->count > 0)
+    {
+      for (node = hmap_first (map); node != NULL; node = next)
+        {
+          size_t new_idx = node->hash & new_mask;
+          struct hmap_node **new_bucket = &new_buckets[new_idx];
+          next = hmap_next (map, node);
+          node->next = *new_bucket;
+          *new_bucket = node;
+        } 
+    }
+  if (map->buckets != &map->one)
+    free (map->buckets);
+  map->buckets = new_buckets;
+  map->mask = new_mask;
+}
+
+/* Ensures that MAP has sufficient space to store at least
+   CAPACITY data elements, allocating a new set of buckets and
+   rehashing if necessary. */
+void
+hmap_reserve (struct hmap *map, size_t capacity)
+{
+  if (capacity > hmap_capacity (map))
+    hmap_rehash (map, capacity_to_mask (capacity));
+}
+
+/* Shrinks MAP's set of buckets to the minimum number needed to
+   store its current number of elements, allocating a new set of
+   buckets and rehashing if that would save space. */
+void
+hmap_shrink (struct hmap *map) 
+{
+  size_t new_mask = capacity_to_mask (map->count);
+  if (new_mask < map->mask) 
+    hmap_rehash (map, new_mask); 
+}
+
+/* Moves NODE around in MAP to compensate for its hash value
+   having changed to NEW_HASH.
+
+   This function does not verify that MAP does not already
+   contain a data item that duplicates NODE's new value.  If
+   duplicates should be disallowed (which is the usual case),
+   then the client must check for duplicates before changing
+   NODE's value. */
+void
+hmap_changed (struct hmap *map, struct hmap_node *node, size_t new_hash)
+{
+  if ((new_hash ^ node->hash) & map->mask) 
+    {
+      hmap_delete (map, node);
+      hmap_insert_fast (map, node, new_hash);
+    }
+  else
+    node->hash = new_hash;
+}
+
+/* Hash map nodes may be moved around in memory as necessary,
+   e.g. as the result of an realloc operation on a block that
+   contains a node.  Once this is done, call this function
+   passing NODE that was moved, its former location in memory
+   OLD, and its hash map MAP before attempting any other
+   operation on MAP, NODE, or any other node in MAP.
+
+   It is not safe to move more than one node, then to call this
+   function for each node.  Instead, move a single node, call
+   this function, move another node, and so on.  Alternatively,
+   remove all affected nodes from the hash map, move them, then
+   re-insert all of them.
+
+   Assuming uniform hashing and no duplicate data items in MAP,
+   this function runs in constant time. */
+void
+hmap_moved (struct hmap *map,
+            struct hmap_node *node, const struct hmap_node *old) 
+{
+  struct hmap_node **p = &map->buckets[node->hash & map->mask];
+  while (*p != old)
+    p = &(*p)->next;
+  *p = node;
+}
+\f
+/* Returns the minimum-value mask required to allow for a hash
+   table capacity of at least CAPACITY.  The return value will be
+   a bit-mask suitable for use as the "mask" member of struct
+   hmap, that is, a power of 2 minus 1 (including 0). */
+static size_t
+capacity_to_mask (size_t capacity) 
+{
+  /* Calculate the minimum mask necesary to support the given
+     capacity. */
+  size_t mask = 0;
+  while (hmap_mask_to_capacity__ (mask) < capacity)
+    mask = (mask << 1) | 1;
+
+  /* If the mask is nonzero, make it at least 3, because there is
+     little point in allocating an array of just 2 pointers. */
+  mask |= (mask & 1) << 1;
+
+  return mask;
+}
diff --git a/src/libpspp/hmap.h b/src/libpspp/hmap.h
new file mode 100644 (file)
index 0000000..e73d84f
--- /dev/null
@@ -0,0 +1,509 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/* Hash table with separate chaining.
+
+   This header (hmap.h) supplies an "embedded" implementation of
+   a hash table that uses linked lists to resolve collisions
+   ("separate chaining").  Its companion header (hmapx.h)
+   supplies a "external" implementation that is otherwise
+   similar.  The two variants are described briefly here.  The
+   embedded variant, for which this is the header, is described
+   in slightly more detail below.  Each function also has a
+   detailed usage comment at its point of definition.  (Many of
+   those definitions are inline in this file, because they are so
+   simple.  Others are in hmap.c.)
+
+   The "hmap" embedded hash table implementation puts the hash
+   table node (which includes the linked list used for resolving
+   collisions) within the data structure that the hash table
+   contains.  This makes allocation efficient, in space and time,
+   because no additional call into an allocator is needed to
+   obtain memory for the hash table node.  It also makes it easy
+   to find the hash table node associated with a given object.
+   However, it's difficult to include a given object in an
+   arbitrary number of hash tables.
+
+   The "hmapx" external hash table implementation allocates hash
+   table nodes separately from the objects in the hash table.
+   Inserting and removing hash table elements requires dynamic
+   allocation, so it is normally slower and takes more memory
+   than the embedded implementation.  It also requires searching
+   the table to find the node associated with a given object.
+   However, it's easy to include a given object in an arbitrary
+   number of hash tables.  It's also possible to create an
+   external hash table without adding a member to the data
+   structure that the hash table contains. */
+
+#ifndef LIBPSPP_HMAP_H
+#define LIBPSPP_HMAP_H 1
+
+/* Embedded hash table with separate chaining.
+
+   To create an embedded hash table, declare an instance of
+   struct hmap, then initialize it with hmap_init():
+     struct hmap map;
+     hmap_init (&map);
+   or, alternatively:
+     struct hmap map = HMAP_INITIALIZER (map);
+   
+   Each node in the hash table, presumably a structure type, must
+   include a struct hmap_node member.  Here's an example:
+     struct foo
+       {
+         struct hmap_node node;   // hmap_node member.
+         const char *string;      // Another member.
+       };
+   The hash table functions work with pointers to struct
+   hmap_node.  To obtain a pointer to your structure type given a
+   pointer to struct hmap_node, use the HMAP_DATA macro.
+
+   Inserting and deleting elements is straightforward.  Use
+   hmap_insert() to insert an element and hmap_delete() to delete
+   an element, e.g.:
+     struct foo my_foo;
+     my_foo.string = "My string";
+     hmap_insert (&map, &my_foo.node, hsh_hash_string (my_foo.string));
+     ...
+     hmap_delete (&map, &my_foo.node);
+   You must pass the element's hash value as one of
+   hmap_insert()'s arguments.  The hash table saves this hash
+   value for use later to speed searches and to rehash as the
+   hash table grows.
+
+   hmap_insert() does not check whether the newly inserted
+   element duplicates an element already in the hash table.  The
+   client is responsible for doing so, if this is desirable.
+
+   The hash table does not provide a direct way to search for an
+   existing element.  Instead, it provides the means to iterate
+   over all the elements in the hash table with a given hash
+   value.  It is easy to compose a search function from such a
+   building block.  For example:
+     const struct foo *
+     find_foo (const struct hmap *map, const char *name)
+     {
+       const struct foo *foo;
+       size_t hash;
+
+       hash = hsh_hash_string (name);
+       HMAP_FOR_EACH_WITH_HASH (foo, struct foo, node, hash, map)
+         if (!strcmp (foo->name, name))
+           break;
+       return foo;
+     }
+
+   Here is how to iterate through the elements currently in the
+   hash table:
+     struct foo *foo;
+     HMAP_FOR_EACH (foo, struct foo, node, &map)
+       {
+         ...do something with foo...
+       }
+   */
+
+#include <stddef.h>
+
+/* Returns the data structure corresponding to the given NODE,
+   assuming that NODE is embedded as the given MEMBER name in
+   data type STRUCT.  NODE must not be a null pointer. */
+#define HMAP_DATA(NODE, STRUCT, MEMBER)                         \
+  ((STRUCT *) ((char *) (NODE) - offsetof (STRUCT, MEMBER)))
+
+/* Like HMAP_DATA, except that a null NODE yields a null pointer
+   result. */
+#define HMAP_NULLABLE_DATA(NODE, STRUCT, MEMBER)        \
+  hmap_nullable_data__ (NODE, offsetof (STRUCT, MEMBER))
+
+/* Hash table node. */
+struct hmap_node
+  {
+    struct hmap_node *next;     /* Next in chain. */
+    size_t hash;                /* Hash value. */
+  };
+
+static inline size_t hmap_node_hash (const struct hmap_node *);
+
+/* Hash table. */
+struct hmap
+  {
+    size_t count;               /* Number of inserted nodes. */
+    size_t mask;                /* Number of buckets (power of 2), minus 1. */
+    struct hmap_node **buckets; /* Array of buckets. */
+    struct hmap_node *one;      /* One bucket, to eliminate corner cases. */
+  };
+
+/* Suitable for use as the initializer for a struct hmap named
+   MAP.  Typical usage:
+       struct hmap map = HMAP_INITIALIZER (map);
+   HMAP_INITIALIZER() is an alternative to hmap_init(). */
+#define HMAP_INITIALIZER(MAP) { 0, 0, &(MAP).one, NULL }
+
+/* Creation and destruction. */
+void hmap_init (struct hmap *);
+void hmap_swap (struct hmap *, struct hmap *);
+void hmap_destroy (struct hmap *);
+
+/* Storage management. */
+void hmap_reserve (struct hmap *, size_t capacity);
+void hmap_shrink (struct hmap *);
+
+/* Search.  Refer to the large comment near the top of this file
+   for an example.*/
+static inline struct hmap_node *hmap_first_with_hash (const struct hmap *,
+                                                      size_t hash);
+static inline struct hmap_node *hmap_next_with_hash (const struct hmap_node *);
+
+/* Insertion and deletion. */
+static inline void hmap_insert (struct hmap *, struct hmap_node *,
+                                size_t hash);
+static inline void hmap_insert_fast (struct hmap *, struct hmap_node *,
+                                     size_t hash);
+static inline void hmap_delete (struct hmap *, struct hmap_node *);
+
+/* Iteration. */
+static inline struct hmap_node *hmap_first (const struct hmap *);
+static inline struct hmap_node *hmap_next (const struct hmap *,
+                                           const struct hmap_node *);
+
+/* Counting. */
+static inline size_t hmap_count (const struct hmap *);
+static inline size_t hmap_capacity (const struct hmap *);
+
+/* Updating data elements. */
+void hmap_changed (struct hmap *, struct hmap_node *, size_t new_hash);
+void hmap_moved (struct hmap *,
+                 struct hmap_node *, const struct hmap_node *old);
+
+/* Convenience macros for search.
+
+   These macros automatically use HMAP_DATA to obtain the data
+   elements that encapsulate hmap nodes, which often saves typing
+   and can make code easier to read.  Refer to the large comment
+   near the top of this file for an example.
+
+   These macros evaluate HASH only once.  They evaluate their
+   other arguments many times. */
+#define HMAP_FIRST_WITH_HASH(STRUCT, MEMBER, HMAP, HASH)                \
+  HMAP_NULLABLE_DATA (hmap_first_with_hash (HMAP, HASH), STRUCT, MEMBER)
+#define HMAP_NEXT_WITH_HASH(DATA, STRUCT, MEMBER)                       \
+  HMAP_NULLABLE_DATA (hmap_next_with_hash (&(DATA)->MEMBER), STRUCT, MEMBER)
+#define HMAP_FOR_EACH_WITH_HASH(DATA, STRUCT, MEMBER, HASH, HMAP)       \
+  for ((DATA) = HMAP_FIRST_WITH_HASH (STRUCT, MEMBER, HMAP, HASH);      \
+       (DATA) != NULL;                                                  \
+       (DATA) = HMAP_NEXT_WITH_HASH (DATA, STRUCT, MEMBER))
+#define HMAP_FOR_EACH_WITH_HASH_SAFE(DATA, NEXT, STRUCT, MEMBER, HASH, HMAP) \
+  for ((DATA) = HMAP_FIRST_WITH_HASH (STRUCT, MEMBER, HMAP, HASH);      \
+       ((DATA) != NULL                                                  \
+        ? ((NEXT) = HMAP_NEXT_WITH_HASH (DATA, STRUCT, MEMBER), 1)      \
+        : 0);                                                           \
+       (DATA) = (NEXT))
+
+/* Convenience macros for iteration.
+
+   These macros automatically use HMAP_DATA to obtain the data
+   elements that encapsulate hmap nodes, which often saves typing
+   and can make code easier to read.  Refer to the large comment
+   near the top of this file for an example.
+
+   These macros evaluate their arguments many times. */
+#define HMAP_FIRST(STRUCT, MEMBER, HMAP)                        \
+  HMAP_NULLABLE_DATA (hmap_first (HMAP), STRUCT, MEMBER)
+#define HMAP_NEXT(DATA, STRUCT, MEMBER, HMAP)                           \
+  HMAP_NULLABLE_DATA (hmap_next (HMAP, &(DATA)->MEMBER), STRUCT, MEMBER)
+#define HMAP_FOR_EACH(DATA, STRUCT, MEMBER, HMAP)       \
+  for ((DATA) = HMAP_FIRST (STRUCT, MEMBER, HMAP);      \
+       (DATA) != NULL;                                  \
+       (DATA) = HMAP_NEXT (DATA, STRUCT, MEMBER, HMAP))
+#define HMAP_FOR_EACH_SAFE(DATA, NEXT, STRUCT, MEMBER, HMAP)    \
+  for ((DATA) = HMAP_FIRST (STRUCT, MEMBER, HMAP);              \
+       ((DATA) != NULL                                          \
+        ? ((NEXT) = HMAP_NEXT (DATA, STRUCT, MEMBER, HMAP), 1)  \
+        : 0);                                                   \
+       (DATA) = (NEXT))
+\f
+/* Inline definitions. */
+
+static inline struct hmap_node *hmap_find_hash__ (struct hmap_node *, size_t);
+static inline struct hmap_node *hmap_first_nonempty_bucket__ (
+  const struct hmap *, size_t start);
+static inline size_t hmap_mask_to_capacity__ (size_t mask);
+
+/* Returns the hash value associated with NODE. */
+size_t
+hmap_node_hash (const struct hmap_node *node) 
+{
+  return node->hash;
+}
+
+/* Returns the first node in MAP that has hash value HASH, or a
+   null pointer if MAP does not contain any node with that hash
+   value.
+
+   Assuming uniform hashing and no duplicate data items in MAP,
+   this function runs in constant time.  (Amortized over an
+   iteration over all data items with a given HASH, its runtime
+   is proportional to the length of the hash chain for HASH, so
+   given a pathological hash function, e.g. one that returns a
+   constant value, its runtime degenerates to linear in the
+   length of NODE's hash chain.)
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmap_capacity().  Calls to hmap_insert(), hmap_reserve(), and
+   hmap_shrink() can change the capacity of a hash map.
+   Inserting a node with hmap_insert_fast() or deleting one with
+   hmap_delete() will not change the relative ordering of nodes.
+
+   The HMAP_FOR_EACH_WITH_HASH and HMAP_FOR_EACH_WITH_HASH_SAFE
+   macros provide convenient ways to iterate over all the nodes
+   with a given hash.  The HMAP_FIRST_WITH_HASH macro is an
+   interface to this particular function that is often more
+   convenient. */
+static inline struct hmap_node *
+hmap_first_with_hash (const struct hmap *map, size_t hash)
+{
+  return hmap_find_hash__ (map->buckets[hash & map->mask], hash);
+}
+
+/* Returns the next node in MAP after NODE that has the same hash
+   value as NODE, or a null pointer if MAP does not contain any
+   more nodes with that hash value.
+
+   Assuming uniform hashing and no duplicate data items in MAP,
+   this function runs in constant time.  (Amortized over an
+   iteration over all data items with a given HASH, its runtime
+   is proportional to the length of the hash chain for HASH, so
+   given a pathological hash function, e.g. one that returns a
+   constant value, its runtime degenerates to linear in the
+   length of NODE's hash chain.)
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmap_capacity().  Calls to hmap_insert(), hmap_reserve(), and
+   hmap_shrink() can change the capacity of a hash map.
+   Inserting a node with hmap_insert_fast() or deleting one with
+   hmap_delete() will not change the relative ordering of nodes.
+
+   The HMAP_FOR_EACH_WITH_HASH and HMAP_FOR_EACH_WITH_HASH_SAFE
+   macros provide convenient ways to iterate over all the nodes
+   with a given hash.  The HMAP_NEXT_WITH_HASH macro is an
+   interface to this particular function that is often more
+   convenient. */
+static inline struct hmap_node *
+hmap_next_with_hash (const struct hmap_node *node) 
+{
+  return hmap_find_hash__ (node->next, node->hash);
+}
+
+/* Inserts NODE into MAP with hash value HASH.  If the insertion
+   causes MAP's current capacity, as reported by hmap_capacity(),
+   to be exceeded, rehashes MAP with an increased number of hash
+   buckets.
+
+   This function runs in constant time amortized over all the
+   insertions into MAP.
+
+   This function does not verify that MAP does not already
+   contain a data item with the same value as NODE.  If
+   duplicates should be disallowed (which is the usual case),
+   then the client must check for duplicates itself before
+   inserting the new node. */
+static inline void
+hmap_insert (struct hmap *map, struct hmap_node *node, size_t hash)
+{
+  hmap_insert_fast (map, node, hash);
+  if (map->count > hmap_capacity (map))
+    hmap_reserve (map, map->count);
+}
+
+/* Inserts NODE into MAP with hash value HASH.  Does not check
+   whether this causes MAP's current capacity to be exceeded.
+   The caller must take responsibility for that (or use
+   hmap_insert() instead).
+
+   This function runs in constant time.
+
+   This function does not verify that MAP does not already
+   contain a data item with the same value as NODE.  If
+   duplicates should be disallowed (which is the usual case),
+   then the client must check for duplicates itself before
+   inserting the new node. */
+static inline void
+hmap_insert_fast (struct hmap *map, struct hmap_node *node, size_t hash) 
+{
+  struct hmap_node **bucket = &map->buckets[hash & map->mask];
+  node->hash = hash;
+  node->next = *bucket;
+  *bucket = node;
+  map->count++;
+}
+
+/* Removes NODE from MAP.  The client is responsible for freeing
+   any data associated with NODE, if necessary.
+
+   Assuming uniform hashing, this function runs in constant time.
+   (Its runtime is proportional to the position of NODE in its
+   hash chain, so given a pathological hash function, e.g. one
+   that returns a constant value, its runtime degenerates to
+   linear in the length of NODE's hash chain.)
+
+   This function never reduces the number of buckets in MAP.
+   When one deletes a large number of nodes from a hash table,
+   calling hmap_shrink() afterward may therefore save a small
+   amount of memory.  It is also more expensive to iterate
+   through a very sparse hash table than a denser one, so
+   shrinking the hash table could also save some time.  However,
+   rehashing has an immediate cost that must be weighed against
+   these benefits.
+
+   hmap_delete() does not change NODE's hash value reported by
+   hmap_node_hash(). */
+static inline void
+hmap_delete (struct hmap *map, struct hmap_node *node)
+{
+  struct hmap_node **bucket = &map->buckets[node->hash & map->mask];
+  while (*bucket != node)
+    bucket = &(*bucket)->next;
+  *bucket = (*bucket)->next;
+  map->count--;
+}
+
+/* Returns the first node in MAP, or a null pointer if MAP is
+   empty.
+
+   Amortized over iterating through every data element in MAP,
+   this function runs in constant time.  However, this assumes
+   that MAP is not excessively sparse, that is, that
+   hmap_capacity(MAP) is at most a constant factor greater than
+   hmap_count(MAP).  This will always be true unless many nodes
+   have been inserted into MAP and then most or all of them
+   deleted; in such a case, calling hmap_shrink() is advised.
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmap_capacity().  Calls to hmap_insert(), hmap_reserve(), and
+   hmap_shrink() can change the capacity of a hash map.
+   Inserting a node with hmap_insert_fast() or deleting one with
+   hmap_delete() will not change the relative ordering of nodes.
+
+   The HMAP_FOR_EACH and HMAP_FOR_EACH_SAFE macros provide
+   convenient ways to iterate over all the nodes in a hash map.
+   The HMAP_FIRST macro is an interface to this particular
+   function that is often more convenient. */
+static inline struct hmap_node *
+hmap_first (const struct hmap *map) 
+{
+  return hmap_first_nonempty_bucket__ (map, 0);
+}
+
+/* Returns the next node in MAP following NODE, or a null pointer
+   if NODE is the last node in MAP.
+
+   Amortized over iterating through every data element in MAP,
+   this function runs in constant time.  However, this assumes
+   that MAP is not excessively sparse, that is, that
+   hmap_capacity(MAP) is at most a constant factor greater than
+   hmap_count(MAP).  This will always be true unless many nodes
+   have been inserted into MAP and then most or all of them
+   deleted; in such a case, calling hmap_shrink() is advised.
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmap_capacity().  Calls to hmap_insert(), hmap_reserve(), and
+   hmap_shrink() can change the capacity of a hash map.
+   Inserting a node with hmap_insert_fast() or deleting one with
+   hmap_delete() will not change the relative ordering of nodes.
+
+   The HMAP_FOR_EACH and HMAP_FOR_EACH_SAFE macros provide
+   convenient ways to iterate over all the nodes in a hash map.
+   The HMAP_NEXT macro is an interface to this particular
+   function that is often more convenient. */
+static inline struct hmap_node *
+hmap_next (const struct hmap *map, const struct hmap_node *node) 
+{
+  return (node->next != NULL
+          ? node->next
+          : hmap_first_nonempty_bucket__ (map, (node->hash & map->mask) + 1));
+}
+
+/* Returns the number of data items currently in MAP. */
+static inline size_t
+hmap_count (const struct hmap *map) 
+{
+  return map->count;
+}
+
+/* Returns the current capacity of MAP, that is, the maximum
+   number of data elements that MAP may hold before it becomes
+   advisable to rehash.
+
+   The capacity is advisory only: it is possible to insert any
+   number of data elements into a hash map regardless of its
+   capacity.  However, inserting many more elements than the
+   map's capacity will degrade search performance. */
+static inline size_t
+hmap_capacity (const struct hmap *map) 
+{
+  return hmap_mask_to_capacity__ (map->mask);
+}
+\f
+/* Implementation details. */
+
+/* Returns the first node at or after NODE in NODE's chain that
+   has hash value HASH. */
+static inline struct hmap_node *
+hmap_find_hash__ (struct hmap_node *node, size_t hash) 
+{
+  for (; node != NULL; node = node->next) 
+    if (node->hash == hash)
+      break;
+  return node;
+}
+
+/* Returns the first node in the lowest-numbered nonempty bucket
+   in MAP whose index is START or higher, or a null pointer if
+   all such buckets are empty. */
+static inline struct hmap_node *
+hmap_first_nonempty_bucket__ (const struct hmap *map, size_t start)
+{
+  size_t i;
+
+  for (i = start; i <= map->mask; i++)
+    if (map->buckets[i] != NULL)
+      return map->buckets[i];
+  return NULL;
+}
+
+/* Returns the hash table capacity associated with a given MASK,
+   which should be a value for the "mask" member of struct hmap.
+   MASK must be a power of 2 minus 1 (including 0), that is, its
+   value in binary must be all 1-bits.  */
+static inline size_t
+hmap_mask_to_capacity__ (size_t mask) 
+{
+  return (mask + 1) * 2;
+}
+
+/* Helper for HMAP_NULLABLE_DATA (to avoid evaluating its NODE
+   argument more than once).  */
+static inline void *
+hmap_nullable_data__ (struct hmap_node *node, size_t member_offset)
+{ 
+  return node != NULL ? (char *) node - member_offset : NULL;
+}
+
+#endif /* libpspp/hmap.h */
diff --git a/src/libpspp/hmapx.c b/src/libpspp/hmapx.c
new file mode 100644 (file)
index 0000000..d732450
--- /dev/null
@@ -0,0 +1,99 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libpspp/hmapx.h>
+#include <stdlib.h>
+#include "xalloc.h"
+
+/* Frees the memory, if any, allocated by hash map MAP, including
+   all hmapx_nodes that it contains.  The user-defined data items
+   that the hmapx_nodes point to are not affected.  If those
+   items should be freed, then it should be done by iterating
+   through MAP's contents before destroying MAP. */
+void
+hmapx_destroy (struct hmapx *map) 
+{
+  if (map != NULL) 
+    {
+      if (hmapx_count (map) > 0) 
+        {
+          struct hmapx_node *node, *next;
+          for (node = hmapx_first (map); node != NULL; node = next)
+            {
+              next = hmapx_next (map, node);
+              free (node); 
+            }
+        }
+      hmap_destroy (&map->hmap);
+    }
+}
+
+/* Allocates and returns a new hmapx_node with DATA as its data
+   item. */
+static struct hmapx_node *
+make_hmapx_node (void *data) 
+{
+  struct hmapx_node *node = xmalloc (sizeof *node);
+  node->data = data;
+  return node;
+}
+
+/* Inserts DATA into MAP with hash value HASH and returns the new
+   hmapx_node created to contain DATA.  If the insertion causes
+   MAP's current capacity, as reported by hmapx_capacity(), to be
+   exceeded, rehashes MAP with an increased number of hash
+   buckets.
+
+   This function runs in constant time amortized over all the
+   insertions into MAP.
+
+   This function does not verify that MAP does not already
+   contain a data item with the same value as DATA.  If
+   duplicates should be disallowed (which is the usual case),
+   then the client must check for duplicates itself before
+   inserting the new item. */
+struct hmapx_node *
+hmapx_insert (struct hmapx *map, void *data, size_t hash) 
+{
+  struct hmapx_node *node = make_hmapx_node (data);
+  hmap_insert (&map->hmap, &node->hmap_node, hash);
+  return node;
+}
+
+/* Inserts DATA into MAP with hash value HASH and returns the new
+   hmapx_node created to contain DATA.  Does not check whether
+   this causes MAP's current capacity to be exceeded.  The caller
+   must take responsibility for that (or use hmapx_insert()
+   instead).
+
+   This function runs in constant time.
+
+   This function does not verify that MAP does not already
+   contain a data item with the same value as DATA.  If
+   duplicates should be disallowed (which is the usual case),
+   then the client must check for duplicates itself before
+   inserting the new node. */
+struct hmapx_node *
+hmapx_insert_fast (struct hmapx *map, void *data, size_t hash) 
+{
+  struct hmapx_node *node = make_hmapx_node (data);
+  hmap_insert_fast (&map->hmap, &node->hmap_node, hash);
+  return node;
+}
diff --git a/src/libpspp/hmapx.h b/src/libpspp/hmapx.h
new file mode 100644 (file)
index 0000000..32a4452
--- /dev/null
@@ -0,0 +1,468 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/* Hash table with separate chaining.
+
+   This header (hmapx.h) supplies an "external" implementation of
+   a hash table that uses linked lists to resolve collisions
+   ("separate chaining").  Its companion header (hmap.h) supplies
+   a "embedded" implementation that is otherwise similar.  The
+   two variants are described briefly here.  The external
+   variant, for which this is the header, is described in
+   slightly more detail below.  Each function also has a detailed
+   usage comment at its point of definition.  (Many of those
+   definitions are inline in this file, because they are so
+   simple.  Others are in hmapx.c.)
+
+   The "hmap" embedded hash table implementation puts the hash
+   table node (which includes the linked list used for resolving
+   collisions) within the data structure that the hash table
+   contains.  This makes allocation efficient, in space and time,
+   because no additional call into an allocator is needed to
+   obtain memory for the hash table node.  It also makes it easy
+   to find the hash table node associated with a given object.
+   However, it's difficult to include a given object in an
+   arbitrary number of hash tables.
+
+   The "hmapx" external hash table implementation allocates hash
+   table nodes separately from the objects in the hash table.
+   Inserting and removing hash table elements requires dynamic
+   allocation, so it is normally slower and takes more memory
+   than the embedded implementation.  It also requires searching
+   the table to find the node associated with a given object.
+   However, it's easy to include a given object in an arbitrary
+   number of hash tables.  It's also possible to create an
+   external hash table without adding a member to the data
+   structure that the hash table contains. */
+
+#ifndef LIBPSPP_HMAPX_H
+#define LIBPSPP_HMAPX_H 1
+
+/* External hash table with separate chaining.
+
+   To create an external hash table, declare an instance of
+   struct hmapx, then initialize it with hmapx_init():
+     struct hmapx map;
+     hmapx_init (&map);
+   or, alternatively:
+     struct hmapx map = HMAPX_INITIALIZER (map);
+
+   An hmapx data structure contains data represented as void *.
+   The hmapx_insert() function inserts such a datum and returns
+   the address of a newly created struct hmapx_node that
+   represents the new element:
+     struct foo {
+       const char *key;
+       const char *value;
+     };
+     struct foo foo = {"key", "value"};
+     struct hmapx_node *node;
+     node = hmapx_insert (&map, &foo, hsh_hash_string (foo.key));
+   The element's hash value must be passed as one of
+   hmapx_insert()'s arguments.  The hash table saves this hash
+   value for use later to speed searches and to rehash as the
+   hash table grows.
+
+   hmapx_insert() does not check whether the newly inserted
+   element duplicates an element already in the hash table.  The
+   client is responsible for doing so, if this is desirable.
+
+   Use hmapx_delete() to delete an element from the hash table,
+   passing in its hmapx_node:
+     hmapx_delete (&map, node);
+   Deleting an element frees its node.
+
+   The hash table does not provide a direct way to search for an
+   existing element.  Instead, it provides the means to iterate
+   over all the elements in the hash table with a given hash
+   value.  It is easy to compose a search function from such a
+   building block.  For example:
+     struct hmapx_node *
+     find_node (const struct hmapx *map, const char *target)
+     {
+       struct hmapx_node *node;
+       struct foo *foo;
+       HMAPX_FOR_EACH_WITH_HASH (foo, node, hsh_hash_string (target), map)
+         if (!strcmp (foo->key, target))
+           break;
+       return node;
+     }
+   This function's client can extract the data item from the
+   returned hmapx_node using the hmapx_node_data() function.  The
+   hmapx_node can also be useful directly as an argument to other
+   hmapx functions, such as hmapx_delete().
+
+   Here is how to iterate through the elements currently in the
+   hash table:
+     struct hmapx_node *node;
+     const char *string;
+     HMAPX_FOR_EACH (data, node, &map)
+       {
+         ...do something with string...
+       }
+   */
+
+#include <libpspp/hmap.h>
+#include <stdlib.h>
+
+/* Hash table node. */
+struct hmapx_node
+  {
+    struct hmap_node hmap_node; /* Underlying hash node. */
+    void *data;                 /* User data. */
+  };
+
+static inline void *hmapx_node_data (const struct hmapx_node *);
+static inline size_t hmapx_node_hash (const struct hmapx_node *);
+
+/* Hash table. */
+struct hmapx
+  {
+    struct hmap hmap;
+  };
+
+/* Suitable for use as the initializer for a struct hmapx named
+   MAP.  Typical usage:
+       struct hmap map = HMAPX_INITIALIZER (map);
+   HMAPX_INITIALIZER() is an alternative to hmapx_init(). */
+#define HMAPX_INITIALIZER(MAP) { HMAP_INITIALIZER (MAP.hmap) }
+
+/* Creation and destruction. */
+static inline void hmapx_init (struct hmapx *);
+static inline void hmapx_swap (struct hmapx *, struct hmapx *);
+void hmapx_destroy (struct hmapx *);
+
+/* Storage management. */
+static inline void hmapx_reserve (struct hmapx *, size_t capacity);
+static inline void hmapx_shrink (struct hmapx *);
+
+/* Search. */
+static inline struct hmapx_node *hmapx_first_with_hash (struct hmapx *,
+                                                        size_t hash);
+static inline struct hmapx_node *hmapx_next_with_hash (struct hmapx_node *);
+
+/* Insertion and deletion. */
+struct hmapx_node *hmapx_insert (struct hmapx *, void *, size_t hash);
+struct hmapx_node *hmapx_insert_fast (struct hmapx *, void *, size_t hash);
+static inline void hmapx_delete (struct hmapx *, struct hmapx_node *);
+
+/* Iteration. */
+static inline struct hmapx_node *hmapx_first (const struct hmapx *);
+static inline struct hmapx_node *hmapx_next (const struct hmapx *,
+                                             const struct hmapx_node *);
+
+/* Counting. */
+static inline size_t hmapx_count (const struct hmapx *);
+static inline size_t hmapx_capacity (const struct hmapx *);
+
+/* Updating data elements. */
+static inline void hmapx_change (struct hmapx *,
+                                 struct hmapx_node *, void *, size_t new_hash);
+static inline void hmapx_changed (struct hmapx *, struct hmapx_node *,
+                                  size_t new_hash);
+static inline void hmapx_move (struct hmapx_node *, void *);
+
+/* Convenience macros for search.
+
+   These macros automatically use hmapx_node_data() to obtain the
+   data elements that encapsulate hmap nodes, which often saves
+   typing and can make code easier to read.  Refer to the large
+   comment near the top of this file for an example.
+
+   These macros evaluate HASH only once.  They evaluate their
+   other arguments many times. */
+#define HMAPX_FOR_EACH_WITH_HASH(DATA, NODE, HASH, HMAPX)               \
+  for ((NODE) = hmapx_first_with_hash (HMAPX, HASH);                    \
+       (NODE) != NULL ? ((DATA) = hmapx_node_data (NODE), 1) : 0;       \
+       (NODE) = hmapx_next_with_hash (NODE))
+#define HMAPX_FOR_EACH_WITH_HASH_SAFE(DATA, NODE, NEXT, HASH, HMAPX)    \
+  for ((NODE) = hmapx_first_with_hash (HMAPX, HASH);                    \
+       ((NODE) != NULL                                                  \
+        ? ((DATA) = hmapx_node_data (NODE),                             \
+           (NEXT) = hmapx_next_with_hash (NODE),                        \
+           1)                                                           \
+        : 0);                                                           \
+       (NODE) = (NEXT))
+
+/* Convenience macros for iteration.
+
+   These macros automatically use hmapx_node_data() to obtain the
+   data elements that encapsulate hmap nodes, which often saves
+   typing and can make code easier to read.  Refer to the large
+   comment near the top of this file for an example. 
+
+   These macros evaluate their arguments many times. */
+#define HMAPX_FOR_EACH(DATA, NODE, HMAPX)                               \
+  for ((NODE) = hmapx_first (HMAPX);                                    \
+       (NODE) != NULL ? ((DATA) = hmapx_node_data (NODE), 1) : 0;       \
+       (NODE) = hmapx_next (HMAPX, NODE))
+#define HMAPX_FOR_EACH_SAFE(DATA, NODE, NEXT, HMAPX)                    \
+  for ((NODE) = hmapx_first (HMAPX);                                    \
+       ((NODE) != NULL                                                  \
+        ? ((DATA) = hmapx_node_data (NODE),                             \
+           (NEXT) = hmapx_next (HMAPX, NODE),                           \
+           1)                                                           \
+        : 0);                                                           \
+       (NODE) = (NEXT))
+\f
+/* Inline definitions. */
+
+/* Returns the data stored in NODE. */
+static inline void *
+hmapx_node_data (const struct hmapx_node *node)
+{
+  return node->data;
+}
+
+/* Returns the hash value stored in NODE */
+static inline size_t
+hmapx_node_hash (const struct hmapx_node *node)
+{
+  return hmap_node_hash (&node->hmap_node);
+}
+
+/* Initializes MAP as a new hash map that is initially empty. */
+static inline void
+hmapx_init (struct hmapx *map) 
+{
+  hmap_init (&map->hmap);
+}
+
+/* Exchanges the contents of hash maps A and B. */
+static inline void
+hmapx_swap (struct hmapx *a, struct hmapx *b)
+{
+  hmap_swap (&a->hmap, &b->hmap);
+}
+
+/* Ensures that MAP has sufficient space to store at least
+   CAPACITY data elements, allocating a new set of buckets and
+   rehashing if necessary. */
+static inline void
+hmapx_reserve (struct hmapx *map, size_t capacity)
+{
+  hmap_reserve (&map->hmap, capacity);
+}
+
+/* Shrinks MAP's set of buckets to the minimum number needed to
+   store its current number of elements, allocating a new set of
+   buckets and rehashing if that would save space. */
+static inline void
+hmapx_shrink (struct hmapx *map) 
+{
+  hmap_shrink (&map->hmap);
+}
+
+/* Returns the first node in MAP that has hash value HASH, or a
+   null pointer if MAP does not contain any node with that hash
+   value.
+
+   Assuming uniform hashing and no duplicate data items in MAP,
+   this function runs in constant time.  (Amortized over an
+   iteration over all data items with a given HASH, its runtime
+   is proportional to the length of the hash chain for HASH, so
+   given a pathological hash function, e.g. one that returns a
+   constant value, its runtime degenerates to linear in the
+   length of NODE's hash chain.)
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmapx_capacity().  Calls to hmapx_insert(), hmapx_reserve(),
+   and hmapx_shrink() can change the capacity of a hash map.
+   Inserting a node with hmapx_insert_fast() or deleting one with
+   hmapx_delete() will not change the relative ordering of nodes.
+
+   The HMAPX_FOR_EACH_WITH_HASH and HMAPX_FOR_EACH_WITH_HASH_SAFE
+   macros provide convenient ways to iterate over all the nodes
+   with a given hash. */
+static inline struct hmapx_node *
+hmapx_first_with_hash (struct hmapx *map, size_t hash) 
+{
+  return HMAP_FIRST_WITH_HASH (struct hmapx_node, hmap_node, &map->hmap, hash);
+}
+
+/* Returns the next node in MAP after NODE that has the same hash
+   value as NODE, or a null pointer if MAP does not contain any
+   more nodes with that hash value.
+
+   Assuming uniform hashing and no duplicate data items in MAP,
+   this function runs in constant time.  (Amortized over an
+   iteration over all data items with a given HASH, its runtime
+   is proportional to the length of the hash chain for HASH, so
+   given a pathological hash function, e.g. one that returns a
+   constant value, its runtime degenerates to linear in the
+   length of NODE's hash chain.)
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmapx_capacity().  Calls to hmapx_insert(), hmapx_reserve(),
+   and hmapx_shrink() can change the capacity of a hash map.
+   Inserting a node with hmapx_insert_fast() or deleting one with
+   hmapx_delete() will not change the relative ordering of nodes.
+
+   The HMAPX_FOR_EACH_WITH_HASH and HMAPX_FOR_EACH_WITH_HASH_SAFE
+   macros provide convenient ways to iterate over all the nodes
+   with a given hash. */
+static inline struct hmapx_node *
+hmapx_next_with_hash (struct hmapx_node *node) 
+{
+  return HMAP_NEXT_WITH_HASH (node, struct hmapx_node, hmap_node);
+}
+
+/* Removes NODE from MAP and frees NODE.  The client is
+   responsible for freeing the user data associated with NODE, if
+   appropriate.
+
+   Assuming uniform hashing, this function runs in constant time.
+   (Its runtime is proportional to the position of NODE in its
+   hash chain, so given a pathological hash function, e.g. one
+   that returns a constant value, its runtime degenerates to
+   linear in the length of NODE's hash chain.)
+
+   This function never reduces the number of buckets in MAP.
+   When one deletes a large number of nodes from a hash table,
+   calling hmapx_shrink() afterward may therefore save a small
+   amount of memory.  It is also more expensive to iterate
+   through a very sparse hash table than a denser one, so
+   shrinking the hash table could also save some time.  However,
+   rehashing has an immediate cost that must be weighed against
+   these benefits.
+
+   hmapx_delete() does not change NODE's hash value reported by
+   hmapx_node_hash(). */
+static inline void
+hmapx_delete (struct hmapx *map, struct hmapx_node *node) 
+{
+  hmap_delete (&map->hmap, &node->hmap_node);
+  free (node);
+}
+
+/* Returns the first node in MAP, or a null pointer if MAP is
+   empty.
+
+   Amortized over iterating through every data element in MAP,
+   this function runs in constant time.  However, this assumes
+   that MAP is not excessively sparse, that is, that
+   hmapx_capacity(MAP) is at most a constant factor greater than
+   hmapx_count(MAP).  This will always be true unless many nodes
+   have been inserted into MAP and then most or all of them
+   deleted; in such a case, calling hmapx_shrink() is advised.
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmapx_capacity().  Calls to hmapx_insert(), hmapx_reserve(),
+   and hmapx_shrink() can change the capacity of a hash map.
+   Inserting a node with hmapx_insert_fast() or deleting one with
+   hmapx_delete() will not change the relative ordering of nodes.
+
+   The HMAPX_FOR_EACH and HMAPX_FOR_EACH_SAFE macros provide
+   convenient ways to iterate over all the nodes in a hash
+   map. */
+static inline struct hmapx_node *
+hmapx_first (const struct hmapx *map) 
+{
+  return HMAP_FIRST (struct hmapx_node, hmap_node, &map->hmap);
+}
+
+/* Returns the next node in MAP following NODE, or a null pointer
+   if NODE is the last node in MAP.
+
+   Amortized over iterating through every data element in MAP,
+   this function runs in constant time.  However, this assumes
+   that MAP is not excessively sparse, that is, that
+   hmapx_capacity(MAP) is at most a constant factor greater than
+   hmapx_count(MAP).  This will always be true unless many nodes
+   have been inserted into MAP and then most or all of them
+   deleted; in such a case, calling hmapx_shrink() is advised.
+
+   Nodes are returned in arbitrary order that may change whenever
+   the hash table's current capacity changes, as reported by
+   hmapx_capacity().  Calls to hmapx_insert(), hmapx_reserve(),
+   and hmapx_shrink() can change the capacity of a hash map.
+   Inserting a node with hmapx_insert_fast() or deleting one with
+   hmapx_delete() will not change the relative ordering of nodes.
+
+   The HMAPX_FOR_EACH and HMAPX_FOR_EACH_SAFE macros provide
+   convenient ways to iterate over all the nodes in a hash
+   map. */
+static inline struct hmapx_node *
+hmapx_next (const struct hmapx *map, const struct hmapx_node *node) 
+{
+  return HMAP_NEXT (node, struct hmapx_node, hmap_node, &map->hmap);
+}
+
+/* Returns the number of data items currently in MAP. */
+static inline size_t
+hmapx_count (const struct hmapx *map) 
+{
+  return hmap_count (&map->hmap);
+}
+
+/* Returns the current capacity of MAP, that is, the maximum
+   number of data elements that MAP may hold before it becomes
+   advisable to rehash.
+
+   The capacity is advisory only: it is possible to insert any
+   number of data elements into a hash map regardless of its
+   capacity.  However, inserting many more elements than the
+   map's capacity will degrade search performance. */
+static inline size_t
+hmapx_capacity (const struct hmapx *map) 
+{
+  return hmap_capacity (&map->hmap);
+}
+
+/* Changes NODE's data to DATA and its hash value to NEW_HASH.
+   NODE must reside in MAP.
+
+   This function does not verify that MAP does not already
+   contain a data item that duplicates DATA.  If duplicates
+   should be disallowed (which is the usual case), then the
+   client must check for duplicates before changing NODE's
+   value. */
+static inline void
+hmapx_change (struct hmapx *map,
+              struct hmapx_node *node, void *data, size_t new_hash) 
+{
+  hmapx_move (node, data);
+  hmapx_changed (map, node, new_hash);
+}
+
+/* Moves NODE around in MAP to compensate for its hash value
+   having changed to NEW_HASH.
+
+   This function does not verify that MAP does not already
+   contain a data item that duplicates the new value of NODE's
+   data.  If duplicates should be disallowed (which is the usual
+   case), then the client must check for duplicates before
+   changing NODE's value. */
+static inline void
+hmapx_changed (struct hmapx *map, struct hmapx_node *node, size_t new_hash) 
+{
+  hmap_changed (&map->hmap, &node->hmap_node, new_hash);
+}
+
+/* Updates NODE to compensate for its data item having moved
+   around in memory to new location DATA.  The data item's value
+   and hash value should not have changed.  (If they have
+   changed, call hmapx_change() instead.) */
+static inline void
+hmapx_move (struct hmapx_node *node, void *data)
+{
+  node->data = data;
+}
+
+#endif /* libpspp/hmapx.h */
index 70780eff968a6ec62c071da23229a4ebaac49fcc..bda2676c86788eabcfa24a937f7802cbe19c955d 100644 (file)
 #include <localcharset.h>
 #include "xstrndup.h"
 
+#if HAVE_NL_LANGINFO
+#include <langinfo.h>
+#endif
+
 
 static char *locale = 0;
 static const char *charset;
@@ -213,3 +217,32 @@ i18n_done (void)
     }
 }
 
+
+
+
+/* Return the system local's idea of the
+   decimal seperator character */
+char
+get_system_decimal (void)
+{
+  char *radix_char = NULL;
+
+  char *ol = setlocale (LC_NUMERIC, NULL);
+  setlocale (LC_NUMERIC, "");
+
+#if HAVE_NL_LANGINFO
+  radix_char = nl_langinfo (RADIXCHAR);
+#else
+  {
+    char *buf = xmalloc (10);
+    snprintf (buf, 10, "%f", 2.5);
+    radix_char = &buf[1];
+  }
+#endif
+
+  /* We MUST leave LC_NUMERIC untouched, since it would
+     otherwise interfere with data_{in,out} */
+  setlocale (LC_NUMERIC, ol);
+  return *radix_char;
+}
+
index 0633ebc82f807b9fb1d89429c3bf99fa9699930c..db15bad86940a955f0a0a942af548a8a7b177edb 100644 (file)
@@ -36,5 +36,8 @@ enum conv_id
 char * recode_string (enum conv_id how,  const char *text, int len);
 
 
+/* Return the decimal separator according to the
+   system locale */
+char get_system_decimal (void);
 
 #endif /* i18n.h */
index 96ef9a2033502ea47483e83be00ed0549def21ce..65ecf55f2cad759a50085a85e90f1e3c79cf7f02 100644 (file)
@@ -336,9 +336,9 @@ struct ll *ll_find_partition (const struct ll *r0, const struct ll *r1,
 #define ll_tail__(STRUCT, MEMBER, LIST)                         \
         ll_data__ (ll_tail (LIST), STRUCT, MEMBER, LIST)
 #define ll_next__(DATA, STRUCT, MEMBER, LIST)                           \
-        ll_data__ (ll_next (&DATA->MEMBER), STRUCT, MEMBER, LIST)
+        ll_data__ (ll_next (&(DATA)->MEMBER), STRUCT, MEMBER, LIST)
 #define ll_prev__(DATA, STRUCT, MEMBER, LIST)                           \
-        ll_data__ (ll_prev (&DATA->MEMBER), STRUCT, MEMBER, LIST)
+        ll_data__ (ll_prev (&(DATA)->MEMBER), STRUCT, MEMBER, LIST)
 \f
 /* Inline functions. */
 
index e33d588fd8c0db6ca722278eb3c77260a6081d82..3b02515709ca9969c8d67eab5c9c2210e4822d1e 100644 (file)
@@ -14,8 +14,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-#if !math_misc_h
-#define math_misc_h 1
+#if !libpspp_misc_h
+#define libpspp_misc_h 1
 
 #include <float.h>
 #include <math.h>
@@ -60,4 +60,21 @@ pow4 (double x)
   return y;
 }
 
-#endif /* math/misc.h */
+/* Set *DEST to the lower of *DEST and SRC */
+static inline void
+minimize (double *dest, double src)
+{
+  if (src < *dest)
+    *dest = src;
+}
+
+
+/* Set *DEST to the greater of *DEST and SRC */
+static inline void
+maximize (double *dest, double src)
+{
+  if (src > *dest)
+    *dest = src;
+}
+
+#endif /* libpspp/misc.h */
diff --git a/src/libpspp/model-checker.c b/src/libpspp/model-checker.c
deleted file mode 100644 (file)
index cb51c48..0000000
+++ /dev/null
@@ -1,1466 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include <libpspp/model-checker.h>
-
-#include <limits.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include <data/val-type.h>
-#include <libpspp/bit-vector.h>
-#include <libpspp/compiler.h>
-#include <libpspp/deque.h>
-#include <libpspp/str.h>
-#include <math/moments.h>
-
-#include "error.h"
-#include "minmax.h"
-#include "xalloc.h"
-\f
-/* Initializes PATH as an empty path. */
-void
-mc_path_init (struct mc_path *path)
-{
-  path->ops = NULL;
-  path->length = 0;
-  path->capacity = 0;
-}
-
-/* Copies the contents of OLD into NEW. */
-void
-mc_path_copy (struct mc_path *new, const struct mc_path *old)
-{
-  if (old->length > new->capacity)
-    {
-      new->capacity = old->length;
-      free (new->ops);
-      new->ops = xnmalloc (new->capacity, sizeof *new->ops);
-    }
-  new->length = old->length;
-  memcpy (new->ops, old->ops, old->length * sizeof *new->ops);
-}
-
-/* Adds OP to the end of PATH. */
-void
-mc_path_push (struct mc_path *path, int op)
-{
-  if (path->length >= path->capacity)
-    path->ops = xnrealloc (path->ops, ++path->capacity, sizeof *path->ops);
-  path->ops[path->length++] = op;
-}
-
-/* Removes and returns the operation at the end of PATH. */
-int
-mc_path_pop (struct mc_path *path)
-{
-  int back = mc_path_back (path);
-  path->length--;
-  return back;
-}
-
-/* Returns the operation at the end of PATH. */
-int
-mc_path_back (const struct mc_path *path)
-{
-  assert (path->length > 0);
-  return path->ops[path->length - 1];
-}
-
-/* Destroys PATH. */
-void
-mc_path_destroy (struct mc_path *path)
-{
-  free (path->ops);
-  path->ops = NULL;
-}
-
-/* Returns the operation in position INDEX in PATH.
-   INDEX must be less than the length of PATH. */
-int
-mc_path_get_operation (const struct mc_path *path, size_t index)
-{
-  assert (index < path->length);
-  return path->ops[index];
-}
-
-/* Returns the number of operations in PATH. */
-size_t
-mc_path_get_length (const struct mc_path *path)
-{
-  return path->length;
-}
-
-/* Appends the operations in PATH to STRING, separating each one
-   with a single space. */
-void
-mc_path_to_string (const struct mc_path *path, struct string *string)
-{
-  size_t i;
-
-  for (i = 0; i < mc_path_get_length (path); i++)
-    {
-      if (i > 0)
-        ds_put_char (string, ' ');
-      ds_put_format (string, "%d", mc_path_get_operation (path, i));
-    }
-}
-\f
-/* Search options. */
-struct mc_options
-  {
-    /* Search strategy. */
-    enum mc_strategy strategy;          /* Type of strategy. */
-    int max_depth;                      /* Limit on depth (or INT_MAX). */
-    int hash_bits;                      /* Number of bits to hash (or 0). */
-    unsigned int seed;                  /* Random seed for MC_RANDOM
-                                           or MC_DROP_RANDOM. */
-    struct mc_path follow_path;         /* Path for MC_PATH. */
-
-    /* Queue configuration. */
-    int queue_limit;                    /* Maximum length of queue. */
-    enum mc_queue_limit_strategy queue_limit_strategy;
-                                        /* How to choose state to drop
-                                           from queue. */
-
-    /* Stop conditions. */
-    int max_unique_states;              /* Maximum unique states to process. */
-    int max_errors;                     /* Maximum errors to detect. */
-    double time_limit;                  /* Maximum time in seconds. */
-
-    /* Output configuration. */
-    int verbosity;                      /* 0=low, 1=normal, 2+=high. */
-    int failure_verbosity;              /* If greater than verbosity,
-                                           verbosity of error replays. */
-    FILE *output_file;                  /* File to receive output. */
-
-    /* How to report intermediate progress. */
-    int progress_usec;                  /* Microseconds between reports. */
-    mc_progress_func *progress_func;    /* Function to call on each report. */
-
-    /* Client data. */
-    void *aux;
-  };
-
-/* Default progress function. */
-static bool
-default_progress (struct mc *mc)
-{
-  if (mc_results_get_stop_reason (mc_get_results (mc)) == MC_CONTINUING)
-    putc ('.', stderr);
-  else
-    putc ('\n', stderr);
-  return true;
-}
-
-/* Do-nothing progress function. */
-static bool
-null_progress (struct mc *mc UNUSED)
-{
-  return true;
-}
-
-/* Creates and returns a set of options initialized to the
-   defaults. */
-struct mc_options *
-mc_options_create (void)
-{
-  struct mc_options *options = xmalloc (sizeof *options);
-
-  options->strategy = MC_BROAD;
-  options->max_depth = INT_MAX;
-  options->hash_bits = 20;
-  options->seed = 0;
-  mc_path_init (&options->follow_path);
-
-  options->queue_limit = 10000;
-  options->queue_limit_strategy = MC_DROP_RANDOM;
-
-  options->max_unique_states = INT_MAX;
-  options->max_errors = 1;
-  options->time_limit = 0.0;
-
-  options->verbosity = 1;
-  options->failure_verbosity = 2;
-  options->output_file = stdout;
-  options->progress_usec = 250000;
-  options->progress_func = default_progress;
-
-  options->aux = NULL;
-
-  return options;
-}
-
-/* Returns a copy of the given OPTIONS. */
-struct mc_options *
-mc_options_clone (const struct mc_options *options)
-{
-  return xmemdup (options, sizeof *options);
-}
-
-/* Destroys OPTIONS. */
-void
-mc_options_destroy (struct mc_options *options)
-{
-  mc_path_destroy (&options->follow_path);
-  free (options);
-}
-
-/* Returns the search strategy used for OPTIONS.  The choices
-   are:
-
-   - MC_BROAD (the default): Breadth-first search.  First tries
-     all the operations with depth 1, then those with depth 2,
-     then those with depth 3, and so on.
-
-     This search algorithm finds the least number of operations
-     needed to trigger a given bug.
-
-   - MC_DEEP: Depth-first search.  Searches downward in the tree
-     of states as fast as possible.  Good for finding bugs that
-     require long sequences of operations to trigger.
-
-   - MC_RANDOM: Random-first search.  Searches through the tree
-     of states in random order.  The standard C library's rand
-     function selects the search path; you can control the seed
-     passed to srand using mc_options_set_seed.
-
-   - MC_PATH: Explicit path.  Applies an explicitly specified
-     sequence of operations. */
-enum mc_strategy
-mc_options_get_strategy (const struct mc_options *options)
-{
-  return options->strategy;
-}
-
-/* Sets the search strategy used for OPTIONS to STRATEGY.
-
-   This function cannot be used to set MC_PATH as the search
-   strategy.  Use mc_options_set_follow_path instead. */
-void
-mc_options_set_strategy (struct mc_options *options, enum mc_strategy strategy)
-{
-  assert (strategy == MC_BROAD
-          || strategy == MC_DEEP
-          || strategy == MC_RANDOM);
-  options->strategy = strategy;
-}
-
-/* Returns OPTION's random seed used by MC_RANDOM and
-   MC_DROP_RANDOM. */
-unsigned int
-mc_options_get_seed (const struct mc_options *options)
-{
-  return options->seed;
-}
-
-/* Set OPTION's random seed used by MC_RANDOM and MC_DROP_RANDOM
-   to SEED. */
-void
-mc_options_set_seed (struct mc_options *options, unsigned int seed)
-{
-  options->seed = seed;
-}
-
-/* Returns the maximum depth to which OPTIONS's search will
-   descend.  The initial states are at depth 1, states produced
-   as their mutations are at depth 2, and so on. */
-int
-mc_options_get_max_depth (const struct mc_options *options)
-{
-  return options->max_depth;
-}
-
-/* Sets the maximum depth to which OPTIONS's search will descend
-   to MAX_DEPTH.  The initial states are at depth 1, states
-   produced as their mutations are at depth 2, and so on. */
-void
-mc_options_set_max_depth (struct mc_options *options, int max_depth)
-{
-  options->max_depth = max_depth;
-}
-
-/* Returns the base-2 log of the number of bits in OPTIONS's hash
-   table.  The hash table is used for dropping states that are
-   probably duplicates: any state with a given hash value, as
-   will only be processed once.  A return value of 0 indicates
-   that the model checker will not discard duplicate states based
-   on their hashes.
-
-   The hash table is a power of 2 bits long, by default 2**20
-   bits (128 kB).  Depending on how many states you expect the
-   model checker to check, how much memory you're willing to let
-   the hash table take up, and how worried you are about missing
-   states due to hash collisions, you could make it larger or
-   smaller.
-
-   The "birthday paradox" points to a reasonable way to size your
-   hash table.  If you expect the model checker to check about
-   2**N states, then, assuming a perfect hash, you need a hash
-   table of 2**(N+1) bits to have a 50% chance of seeing a hash
-   collision, 2**(N+2) bits to have a 25% chance, and so on. */
-int
-mc_options_get_hash_bits (const struct mc_options *options)
-{
-  return options->hash_bits;
-}
-
-/* Sets the base-2 log of the number of bits in OPTIONS's hash
-   table to HASH_BITS.  A HASH_BITS value of 0 requests that the
-   model checker not discard duplicate states based on their
-   hashes.  (This causes the model checker to never terminate in
-   many cases.) */
-void
-mc_options_set_hash_bits (struct mc_options *options, int hash_bits)
-{
-  assert (hash_bits >= 0);
-  options->hash_bits = MIN (hash_bits, CHAR_BIT * sizeof (unsigned int) - 1);
-}
-
-/* Returns the path set in OPTIONS by mc_options_set_follow_path.
-   May be used only if the search strategy is MC_PATH. */
-const struct mc_path *
-mc_options_get_follow_path (const struct mc_options *options)
-{
-  assert (options->strategy == MC_PATH);
-  return &options->follow_path;
-}
-
-/* Sets, in OPTIONS, the search algorithm to MC_PATH and the path
-   to be the explicit path specified in FOLLOW_PATH. */
-void
-mc_options_set_follow_path (struct mc_options *options,
-                            const struct mc_path *follow_path)
-{
-  assert (mc_path_get_length (follow_path) > 0);
-  options->strategy = MC_PATH;
-  mc_path_copy (&options->follow_path, follow_path);
-}
-
-/* Returns the maximum number of queued states in OPTIONS.  The
-   default value is 10,000.  The primary reason to limit the
-   number of queued states is to conserve memory, so if you can
-   afford the memory and your model needs more room in the queue,
-   you can raise the limit.  Conversely, if your models are large
-   or memory is constrained, you can reduce the limit.
-
-   Following the execution of the model checker, you can find out
-   the maximum queue length during the run by calling
-   mc_results_get_max_queue_length. */
-int
-mc_options_get_queue_limit (const struct mc_options *options)
-{
-  return options->queue_limit;
-}
-
-/* Sets the maximum number of queued states in OPTIONS to
-   QUEUE_LIMIT.  */
-void
-mc_options_set_queue_limit (struct mc_options *options, int queue_limit)
-{
-  assert (queue_limit > 0);
-  options->queue_limit = queue_limit;
-}
-
-/* Returns the queue limit strategy used by OPTIONS, that is,
-   when a new state must be inserted into a full state queue is
-   full, how the state to be dropped is chosen.  The choices are:
-
-   - MC_DROP_NEWEST: Drop the newest state; that is, do not
-     insert the new state into the queue at all.
-
-   - MC_DROP_OLDEST: Drop the state that has been enqueued for
-     the longest.
-
-   - MC_DROP_RANDOM (the default): Drop a randomly selected state
-     from the queue.  The standard C library's rand function
-     selects the state to drop; you can control the seed passed
-     to srand using mc_options_set_seed. */
-enum mc_queue_limit_strategy
-mc_options_get_queue_limit_strategy (const struct mc_options *options)
-{
-  return options->queue_limit_strategy;
-}
-
-/* Sets the queue limit strategy used by OPTIONS to STRATEGY.
-
-   This setting has no effect unless the model being checked
-   causes the state queue to overflow (see
-   mc_options_get_queue_limit). */
-void
-mc_options_set_queue_limit_strategy (struct mc_options *options,
-                                     enum mc_queue_limit_strategy strategy)
-{
-  assert (strategy == MC_DROP_NEWEST
-          || strategy == MC_DROP_OLDEST
-          || strategy == MC_DROP_RANDOM);
-  options->queue_limit_strategy = strategy;
-}
-
-/* Returns OPTIONS's maximum number of unique states that the
-   model checker will examine before terminating.  The default is
-   INT_MAX. */
-int
-mc_options_get_max_unique_states (const struct mc_options *options)
-{
-  return options->max_unique_states;
-}
-
-/* Sets OPTIONS's maximum number of unique states that the model
-   checker will examine before terminating to
-   MAX_UNIQUE_STATE. */
-void
-mc_options_set_max_unique_states (struct mc_options *options,
-                                  int max_unique_states)
-{
-  options->max_unique_states = max_unique_states;
-}
-
-/* Returns the maximum number of errors that OPTIONS will allow
-   the model checker to encounter before terminating.  The
-   default is 1. */
-int
-mc_options_get_max_errors (const struct mc_options *options)
-{
-  return options->max_errors;
-}
-
-/* Sets the maximum number of errors that OPTIONS will allow the
-   model checker to encounter before terminating to
-   MAX_ERRORS. */
-void
-mc_options_set_max_errors (struct mc_options *options, int max_errors)
-{
-  options->max_errors = max_errors;
-}
-
-/* Returns the maximum amount of time, in seconds, that OPTIONS will allow the
-   model checker to consume before terminating.  The
-   default of 0.0 means that time consumption is unlimited. */
-double
-mc_options_get_time_limit (const struct mc_options *options)
-{
-  return options->time_limit;
-}
-
-/* Sets the maximum amount of time, in seconds, that OPTIONS will
-   allow the model checker to consume before terminating to
-   TIME_LIMIT.  A value of 0.0 means that time consumption is
-   unlimited; otherwise, the return value will be positive. */
-void
-mc_options_set_time_limit (struct mc_options *options, double time_limit)
-{
-  assert (time_limit >= 0.0);
-  options->time_limit = time_limit;
-}
-
-/* Returns the level of verbosity for output messages specified
-   by OPTIONS.  The default verbosity level is 1.
-
-   A verbosity level of 0 inhibits all messages except for
-   errors; a verbosity level of 1 also allows warnings; a
-   verbosity level of 2 also causes a description of each state
-   added to be output; a verbosity level of 3 also causes a
-   description of each duplicate state to be output.  Verbosity
-   levels less than 0 or greater than 3 are allowed but currently
-   have no additional effect. */
-int
-mc_options_get_verbosity (const struct mc_options *options)
-{
-  return options->verbosity;
-}
-
-/* Sets the level of verbosity for output messages specified
-   by OPTIONS to VERBOSITY. */
-void
-mc_options_set_verbosity (struct mc_options *options, int verbosity)
-{
-  options->verbosity = verbosity;
-}
-
-/* Returns the level of verbosity for failures specified by
-   OPTIONS.  The default failure verbosity level is 2.
-
-   The failure verbosity level has an effect only when an error
-   is reported, and only when the failure verbosity level is
-   higher than the regular verbosity level.  When this is the
-   case, the model checker replays the error path at the higher
-   verbosity level specified.  This has the effect of outputting
-   an explicit, human-readable description of the sequence of
-   operations that caused the error. */
-int
-mc_options_get_failure_verbosity (const struct mc_options *options)
-{
-  return options->failure_verbosity;
-}
-
-/* Sets the level of verbosity for failures specified by OPTIONS
-   to FAILURE_VERBOSITY. */
-void
-mc_options_set_failure_verbosity (struct mc_options *options,
-                                  int failure_verbosity)
-{
-  options->failure_verbosity = failure_verbosity;
-}
-
-/* Returns the output file used for messages printed by the model
-   checker specified by OPTIONS.  The default is stdout. */
-FILE *
-mc_options_get_output_file (const struct mc_options *options)
-{
-  return options->output_file;
-}
-
-/* Sets the output file used for messages printed by the model
-   checker specified by OPTIONS to OUTPUT_FILE.
-
-   The model checker does not automatically close the specified
-   output file.  If this is desired, the model checker's client
-   must do so. */
-void
-mc_options_set_output_file (struct mc_options *options,
-                            FILE *output_file)
-{
-  options->output_file = output_file;
-}
-
-/* Returns the number of microseconds between calls to the
-   progress function specified by OPTIONS.   The default is
-   250,000 (1/4 second).  A value of 0 disables progress
-   reporting. */
-int
-mc_options_get_progress_usec (const struct mc_options *options)
-{
-  return options->progress_usec;
-}
-
-/* Sets the number of microseconds between calls to the progress
-   function specified by OPTIONS to PROGRESS_USEC.  A value of 0
-   disables progress reporting. */
-void
-mc_options_set_progress_usec (struct mc_options *options, int progress_usec)
-{
-  assert (progress_usec >= 0);
-  options->progress_usec = progress_usec;
-}
-
-/* Returns the function called to report progress specified by
-   OPTIONS.  The function used by default prints '.' to
-   stderr. */
-mc_progress_func *
-mc_options_get_progress_func (const struct mc_options *options)
-{
-  return options->progress_func;
-}
-
-/* Sets the function called to report progress specified by
-   OPTIONS to PROGRESS_FUNC.  A non-null function must be
-   specified; to disable progress reporting, set the progress
-   reporting interval to 0.
-
-   PROGRESS_FUNC will be called zero or more times while the
-   model checker's run is ongoing.  For these calls to the
-   progress function, mc_results_get_stop_reason will return
-   MC_CONTINUING.  It will also be called exactly once soon
-   before mc_run returns, in which case
-   mc_results_get_stop_reason will return a different value. */
-void
-mc_options_set_progress_func (struct mc_options *options,
-                              mc_progress_func *progress_func)
-{
-  assert (options->progress_func != NULL);
-  options->progress_func = progress_func;
-}
-
-/* Returns the auxiliary data set in OPTIONS by the client.  The
-   default is a null pointer.
-
-   This auxiliary data value can be retrieved by the
-   client-specified functions in struct mc_class during a model
-   checking run using mc_get_aux. */
-void *
-mc_options_get_aux (const struct mc_options *options)
-{
-  return options->aux;
-}
-
-/* Sets the auxiliary data in OPTIONS to AUX. */
-void
-mc_options_set_aux (struct mc_options *options, void *aux)
-{
-  options->aux = aux;
-}
-\f
-/* Results of a model checking run. */
-struct mc_results
-  {
-    /* Overall results. */
-    enum mc_stop_reason stop_reason;    /* Why the run ended. */
-    int unique_state_count;             /* Number of unique states checked. */
-    int error_count;                    /* Number of errors found. */
-
-    /* Depth statistics. */
-    int max_depth_reached;              /* Max depth state examined. */
-    struct moments1 *depth_moments;     /* Enables reporting mean depth. */
-
-    /* If error_count > 0, path to the last error reported. */
-    struct mc_path error_path;
-
-    /* States dropped... */
-    int duplicate_dropped_states;       /* ...as duplicates. */
-    int off_path_dropped_states;        /* ...as off-path (MC_PATH only). */
-    int depth_dropped_states;           /* ...due to excessive depth. */
-    int queue_dropped_states;           /* ...due to queue overflow. */
-
-    /* Queue statistics. */
-    int queued_unprocessed_states;      /* Enqueued but never dequeued. */
-    int max_queue_length;               /* Maximum queue length observed. */
-
-    /* Timing. */
-    struct timeval start;               /* Start of model checking run. */
-    struct timeval end;                 /* End of model checking run. */
-  };
-
-/* Creates, initializes, and returns a new set of results. */
-static struct mc_results *
-mc_results_create (void)
-{
-  struct mc_results *results = xcalloc (1, sizeof (struct mc_results));
-  results->stop_reason = MC_CONTINUING;
-  results->depth_moments = moments1_create (MOMENT_MEAN);
-  gettimeofday (&results->start, NULL);
-  return results;
-}
-
-/* Destroys RESULTS. */
-void
-mc_results_destroy (struct mc_results *results)
-{
-  if (results != NULL)
-    {
-      moments1_destroy (results->depth_moments);
-      mc_path_destroy (&results->error_path);
-      free (results);
-    }
-}
-
-/* Returns RESULTS's reason that the model checking run
-   terminated.  The possible reasons are:
-
-   - MC_CONTINUING: The run is not actually yet complete.  This
-     can only be returned before mc_run has returned, e.g. when
-     the progress function set by mc_options_set_progress_func
-     examines the run's results.
-
-   - MC_SUCCESS: The run completed because the queue emptied.
-     The entire state space might not have been explored due to a
-     requested limit on maximum depth, hash collisions, etc.
-
-   - MC_MAX_UNIQUE_STATES: The run completed because as many
-     unique states have been checked as were requested (using
-     mc_options_set_max_unique_states).
-
-   - MC_MAX_ERROR_COUNT: The run completed because the maximum
-     requested number of errors (by default, 1 error) was
-     reached.
-
-   - MC_END_OF_PATH: The run completed because the path specified
-     with mc_options_set_follow_path was fully traversed.
-
-   - MC_TIMEOUT: The run completed because the time limit set
-     with mc_options_set_time_limit was exceeded.
-
-   - MC_INTERRUPTED: The run completed because SIGINT was caught
-     (typically, due to the user typing Ctrl+C). */
-enum mc_stop_reason
-mc_results_get_stop_reason (const struct mc_results *results)
-{
-  return results->stop_reason;
-}
-
-/* Returns the number of unique states checked specified by
-   RESULTS. */
-int
-mc_results_get_unique_state_count (const struct mc_results *results)
-{
-  return results->unique_state_count;
-}
-
-/* Returns the number of errors found specified by RESULTS. */
-int
-mc_results_get_error_count (const struct mc_results *results)
-{
-  return results->error_count;
-}
-
-/* Returns the maximum depth reached during the model checker run
-   represented by RESULTS.  The initial states are at depth 1,
-   their child states at depth 2, and so on. */
-int
-mc_results_get_max_depth_reached (const struct mc_results *results)
-{
-  return results->max_depth_reached;
-}
-
-/* Returns the mean depth reached during the model checker run
-   represented by RESULTS. */
-double
-mc_results_get_mean_depth_reached (const struct mc_results *results)
-{
-  double mean;
-  moments1_calculate (results->depth_moments, NULL, &mean, NULL, NULL, NULL);
-  return mean != SYSMIS ? mean : 0.0;
-}
-
-/* Returns the path traversed to obtain the last error
-   encountered during the model checker run represented by
-   RESULTS.  Returns a null pointer if the run did not report any
-   errors. */
-const struct mc_path *
-mc_results_get_error_path (const struct mc_results *results)
-{
-  return results->error_count > 0 ? &results->error_path : NULL;
-}
-
-/* Returns the number of states dropped as duplicates (based on
-   hash value) during the model checker run represented by
-   RESULTS. */
-int
-mc_results_get_duplicate_dropped_states (const struct mc_results *results)
-{
-  return results->duplicate_dropped_states;
-}
-
-/* Returns the number of states dropped because they were off the
-   path specified by mc_options_set_follow_path during the model
-   checker run represented by RESULTS.  A nonzero value here
-   indicates a missing call to mc_include_state in the
-   client-supplied mutation function. */
-int
-mc_results_get_off_path_dropped_states (const struct mc_results *results)
-{
-  return results->off_path_dropped_states;
-}
-
-/* Returns the number of states dropped because their depth
-   exceeded the maximum specified with mc_options_set_max_depth
-   during the model checker run represented by RESULTS. */
-int
-mc_results_get_depth_dropped_states (const struct mc_results *results)
-{
-  return results->depth_dropped_states;
-}
-
-/* Returns the number of states dropped from the queue due to
-   queue overflow during the model checker run represented by
-   RESULTS. */
-int
-mc_results_get_queue_dropped_states (const struct mc_results *results)
-{
-  return results->queue_dropped_states;
-}
-
-/* Returns the number of states that were checked and enqueued
-   but never dequeued and processed during the model checker run
-   represented by RESULTS.  This is zero if the stop reason is
-   MC_CONTINUING or MC_SUCCESS; otherwise, it is the number of
-   states in the queue at the time that the checking run
-   stopped. */
-int
-mc_results_get_queued_unprocessed_states (const struct mc_results *results)
-{
-  return results->queued_unprocessed_states;
-}
-
-/* Returns the maximum length of the queue during the model
-   checker run represented by RESULTS.  If this is equal to the
-   maximum queue length, then the queue (probably) overflowed
-   during the run; otherwise, it did not overflow. */
-int
-mc_results_get_max_queue_length (const struct mc_results *results)
-{
-  return results->max_queue_length;
-}
-
-/* Returns the time at which the model checker run represented by
-   RESULTS started. */
-struct timeval
-mc_results_get_start (const struct mc_results *results)
-{
-  return results->start;
-}
-
-/* Returns the time at which the model checker run represented by
-   RESULTS ended.  (This function may not be called while the run
-   is still ongoing.) */
-struct timeval
-mc_results_get_end (const struct mc_results *results)
-{
-  assert (results->stop_reason != MC_CONTINUING);
-  return results->end;
-}
-
-/* Returns the number of seconds obtained by subtracting time Y
-   from time X. */
-static double
-timeval_subtract (struct timeval x, struct timeval y)
-{
-  /* From libc.info. */
-  double difference;
-
-  /* Perform the carry for the later subtraction by updating Y. */
-  if (x.tv_usec < y.tv_usec) {
-    int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
-    y.tv_usec -= 1000000 * nsec;
-    y.tv_sec += nsec;
-  }
-  if (x.tv_usec - y.tv_usec > 1000000) {
-    int nsec = (x.tv_usec - y.tv_usec) / 1000000;
-    y.tv_usec += 1000000 * nsec;
-    y.tv_sec -= nsec;
-  }
-
-  /* Compute the time remaining to wait.
-     `tv_usec' is certainly positive. */
-  difference = (x.tv_sec - y.tv_sec) + (x.tv_usec - y.tv_usec) / 1000000.0;
-  if (x.tv_sec < y.tv_sec)
-    difference = -difference;
-  return difference;
-}
-
-
-/* Returns the duration, in seconds, of the model checker run
-   represented by RESULTS.  (This function may not be called
-   while the run is still ongoing.) */
-double
-mc_results_get_duration (const struct mc_results *results)
-{
-  assert (results->stop_reason != MC_CONTINUING);
-  return timeval_subtract (results->end, results->start);
-}
-\f
-/* An active model checking run. */
-struct mc
-  {
-    /* Related data structures. */
-    const struct mc_class *class;
-    struct mc_options *options;
-    struct mc_results *results;
-
-    /* Array of 2**(options->hash_bits) bits representing states
-       already visited. */
-    unsigned char *hash;
-
-    /* State queue. */
-    struct mc_state **queue;            /* Array of pointers to states. */
-    struct deque queue_deque;           /* Deque. */
-
-    /* State currently being built by "init" or "mutate". */
-    struct mc_path path;                /* Path to current state. */
-    struct string path_string;          /* Buffer for path_string function. */
-    bool state_named;                   /* mc_name_operation called? */
-    bool state_error;                   /* mc_error called? */
-
-    /* Statistics for calling the progress function. */
-    unsigned int progress;              /* Current progress value. */
-    unsigned int next_progress;         /* Next value to call progress func. */
-    unsigned int prev_progress;         /* Last value progress func called. */
-    struct timeval prev_progress_time;  /* Last time progress func called. */
-
-    /* Information for handling and restoring SIGINT. */
-    bool interrupted;                   /* SIGINT received? */
-    bool *saved_interrupted_ptr;        /* Saved value of interrupted_ptr. */
-    void (*saved_sigint) (int);         /* Saved SIGINT handler. */
-  };
-
-/* A state in the queue. */
-struct mc_state
-  {
-    struct mc_path path;                /* Path to this state. */
-    void *data;                         /* Client-supplied data. */
-  };
-
-/* Points to the current struct mc's "interrupted" member. */
-static bool *interrupted_ptr = NULL;
-
-static const char *path_string (struct mc *);
-static void free_state (const struct mc *, struct mc_state *);
-static void stop (struct mc *, enum mc_stop_reason);
-static struct mc_state *make_state (const struct mc *, void *);
-static size_t random_queue_index (struct mc *);
-static void enqueue_state (struct mc *, struct mc_state *);
-static void do_error_state (struct mc *);
-static void next_operation (struct mc *);
-static bool is_off_path (const struct mc *);
-static void sigint_handler (int signum);
-static void init_mc (struct mc *,
-                     const struct mc_class *, struct mc_options *);
-static void finish_mc (struct mc *);
-
-/* Runs the model checker on the client-specified CLASS with the
-   client-specified OPTIONS.  OPTIONS may be a null pointer if
-   the defaults are acceptable.  Destroys OPTIONS; use
-   mc_options_clone if a copy is needed.
-
-   Returns the results of the model checking run, which must be
-   destroyed by the client with mc_results_destroy.
-
-   To pass auxiliary data to the functions in CLASS, use
-   mc_options_set_aux on OPTIONS, which may be retrieved from the
-   CLASS functions using mc_get_aux. */
-struct mc_results *
-mc_run (const struct mc_class *class, struct mc_options *options)
-{
-  struct mc mc;
-
-  init_mc (&mc, class, options);
-  while (!deque_is_empty (&mc.queue_deque)
-         && mc.results->stop_reason == MC_CONTINUING)
-    {
-      struct mc_state *state = mc.queue[deque_pop_front (&mc.queue_deque)];
-      mc_path_copy (&mc.path, &state->path);
-      mc_path_push (&mc.path, 0);
-      class->mutate (&mc, state->data);
-      free_state (&mc, state);
-      if (mc.interrupted)
-        stop (&mc, MC_INTERRUPTED);
-    }
-  finish_mc (&mc);
-
-  return mc.results;
-}
-
-/* Tests whether the current operation is one that should be
-   performed, checked, and enqueued.  If so, returns true.
-   Otherwise, returns false and, unless checking is stopped,
-   advances to the next state.  The caller should then advance
-   to the next operation.
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-bool
-mc_include_state (struct mc *mc)
-{
-  if (mc->results->stop_reason != MC_CONTINUING)
-    return false;
-  else if (is_off_path (mc))
-    {
-      next_operation (mc);
-      return false;
-    }
-  else
-    return true;
-}
-
-/* Tests whether HASH represents a state that has (probably)
-   already been enqueued.  If not, returns false and marks HASH
-   so that it will be treated as a duplicate in the future.  If
-   so, returns true and advances to the next state.  The
-   caller should then advance to the next operation.
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-bool
-mc_discard_dup_state (struct mc *mc, unsigned int hash)
-{
-  if (mc->options->hash_bits > 0)
-    {
-      hash &= (1u << mc->options->hash_bits) - 1;
-      if (TEST_BIT (mc->hash, hash))
-        {
-          if (mc->options->verbosity > 2)
-            fprintf (mc->options->output_file,
-                     "    [%s] discard duplicate state\n", path_string (mc));
-          mc->results->duplicate_dropped_states++;
-          next_operation (mc);
-          return true;
-        }
-      SET_BIT (mc->hash, hash);
-    }
-  return false;
-}
-
-/* Names the current state NAME, which may contain
-   printf-style format specifications.  NAME should be a
-   human-readable name for the current operation.
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-void
-mc_name_operation (struct mc *mc, const char *name, ...)
-{
-  va_list args;
-
-  va_start (args, name);
-  mc_vname_operation (mc, name, args);
-  va_end (args);
-}
-
-/* Names the current state NAME, which may contain
-   printf-style format specifications, for which the
-   corresponding arguments must be given in ARGS.  NAME should be
-   a human-readable name for the current operation.
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-void
-mc_vname_operation (struct mc *mc, const char *name, va_list args)
-{
-  if (mc->state_named && mc->options->verbosity > 0)
-    fprintf (mc->options->output_file, "  [%s] warning: duplicate call "
-             "to mc_name_operation (missing call to mc_add_state?)\n",
-             path_string (mc));
-  mc->state_named = true;
-
-  if (mc->options->verbosity > 1)
-    {
-      fprintf (mc->options->output_file, "  [%s] ", path_string (mc));
-      vfprintf (mc->options->output_file, name, args);
-      putc ('\n', mc->options->output_file);
-    }
-}
-
-/* Reports the given error MESSAGE for the current operation.
-   The resulting state should still be passed to mc_add_state
-   when all relevant error messages have been issued.  The state
-   will not, however, be enqueued for later mutation of its own.
-
-   By default, model checking stops after the first error
-   encountered.
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-void
-mc_error (struct mc *mc, const char *message, ...)
-{
-  va_list args;
-
-  if (mc->results->stop_reason != MC_CONTINUING)
-    return;
-
-  if (mc->options->verbosity > 1)
-    fputs ("    ", mc->options->output_file);
-  fprintf (mc->options->output_file, "[%s] error: ",
-           path_string (mc));
-  va_start (args, message);
-  vfprintf (mc->options->output_file, message, args);
-  va_end (args);
-  putc ('\n', mc->options->output_file);
-
-  mc->state_error = true;
-}
-
-/* Enqueues DATA as the state corresponding to the current
-   operation.  The operation should have been named with a call
-   to mc_name_operation, and it should have been checked by the
-   caller (who should have reported any errors with mc_error).
-
-   This function should be called from the client-provided
-   "mutate" function, according to the pattern explained in the
-   big comment at the top of model-checker.h. */
-void
-mc_add_state (struct mc *mc, void *data)
-{
-  if (!mc->state_named && mc->options->verbosity > 0)
-    fprintf (mc->options->output_file, "  [%s] warning: unnamed state\n",
-             path_string (mc));
-
-  if (mc->results->stop_reason != MC_CONTINUING)
-    {
-      /* Nothing to do. */
-    }
-  else if (mc->state_error)
-    do_error_state (mc);
-  else if (is_off_path (mc))
-    mc->results->off_path_dropped_states++;
-  else if (mc->path.length + 1 > mc->options->max_depth)
-    mc->results->depth_dropped_states++;
-  else
-    {
-      /* This is the common case. */
-      mc->results->unique_state_count++;
-      if (mc->results->unique_state_count >= mc->options->max_unique_states)
-        stop (mc, MC_MAX_UNIQUE_STATES);
-      enqueue_state (mc, make_state (mc, data));
-      next_operation (mc);
-      return;
-    }
-
-  mc->class->destroy (mc, data);
-  next_operation (mc);
-}
-
-/* Returns the options that were passed to mc_run for model
-   checker MC. */
-const struct mc_options *
-mc_get_options (const struct mc *mc)
-{
-  return mc->options;
-}
-
-/* Returns the current state of the results for model checker
-   MC.  This function is appropriate for use from the progress
-   function set by mc_options_set_progress_func.
-
-   Not all of the results are meaningful before model checking
-   completes. */
-const struct mc_results *
-mc_get_results (const struct mc *mc)
-{
-  return mc->results;
-}
-
-/* Returns the auxiliary data set on the options passed to mc_run
-   with mc_options_set_aux. */
-void *
-mc_get_aux (const struct mc *mc)
-{
-  return mc_options_get_aux (mc_get_options (mc));
-}
-\f
-/* Expresses MC->path as a string and returns the string. */
-static const char *
-path_string (struct mc *mc)
-{
-  ds_clear (&mc->path_string);
-  mc_path_to_string (&mc->path, &mc->path_string);
-  return ds_cstr (&mc->path_string);
-}
-
-/* Frees STATE, including client data. */
-static void
-free_state (const struct mc *mc, struct mc_state *state)
-{
-  mc->class->destroy (mc, state->data);
-  mc_path_destroy (&state->path);
-  free (state);
-}
-
-/* Sets STOP_REASON as the reason that MC's processing stopped,
-   unless MC is already stopped. */
-static void
-stop (struct mc *mc, enum mc_stop_reason stop_reason)
-{
-  if (mc->results->stop_reason == MC_CONTINUING)
-    mc->results->stop_reason = stop_reason;
-}
-
-/* Creates and returns a new state whose path is copied from
-   MC->path and whose data is specified by DATA. */
-static struct mc_state *
-make_state (const struct mc *mc, void *data)
-{
-  struct mc_state *new = xmalloc (sizeof *new);
-  mc_path_init (&new->path);
-  mc_path_copy (&new->path, &mc->path);
-  new->data = data;
-  return new;
-}
-
-/* Returns the index in MC->queue of a random element in the
-   queue. */
-static size_t
-random_queue_index (struct mc *mc)
-{
-  assert (!deque_is_empty (&mc->queue_deque));
-  return deque_front (&mc->queue_deque,
-                      rand () % deque_count (&mc->queue_deque));
-}
-
-/* Adds NEW to MC's state queue, dropping a state if necessary
-   due to overflow. */
-static void
-enqueue_state (struct mc *mc, struct mc_state *new)
-{
-  size_t idx;
-
-  if (new->path.length > mc->results->max_depth_reached)
-    mc->results->max_depth_reached = new->path.length;
-  moments1_add (mc->results->depth_moments, new->path.length, 1.0);
-
-  if (deque_count (&mc->queue_deque) < mc->options->queue_limit)
-    {
-      /* Add new state to queue. */
-      if (deque_is_full (&mc->queue_deque))
-        mc->queue = deque_expand (&mc->queue_deque,
-                                   mc->queue, sizeof *mc->queue);
-      switch (mc->options->strategy)
-        {
-        case MC_BROAD:
-          idx = deque_push_back (&mc->queue_deque);
-          break;
-        case MC_DEEP:
-          idx = deque_push_front (&mc->queue_deque);
-          break;
-        case MC_RANDOM:
-          if (!deque_is_empty (&mc->queue_deque))
-            {
-              idx = random_queue_index (mc);
-              mc->queue[deque_push_front (&mc->queue_deque)]
-                = mc->queue[idx];
-            }
-          else
-            idx = deque_push_front (&mc->queue_deque);
-          break;
-        case MC_PATH:
-          assert (deque_is_empty (&mc->queue_deque));
-          assert (!is_off_path (mc));
-          idx = deque_push_back (&mc->queue_deque);
-          if (mc->path.length
-              >= mc_path_get_length (&mc->options->follow_path))
-            stop (mc, MC_END_OF_PATH);
-          break;
-        default:
-          NOT_REACHED ();
-        }
-      if (deque_count (&mc->queue_deque) > mc->results->max_queue_length)
-        mc->results->max_queue_length = deque_count (&mc->queue_deque);
-    }
-  else
-    {
-      /* Queue has reached limit, so replace an existing
-         state. */
-      assert (mc->options->strategy != MC_PATH);
-      assert (!deque_is_empty (&mc->queue_deque));
-      mc->results->queue_dropped_states++;
-      switch (mc->options->queue_limit_strategy)
-        {
-        case MC_DROP_NEWEST:
-          free_state (mc, new);
-          return;
-        case MC_DROP_OLDEST:
-          switch (mc->options->strategy)
-            {
-            case MC_BROAD:
-              idx = deque_front (&mc->queue_deque, 0);
-              break;
-            case MC_DEEP:
-              idx = deque_back (&mc->queue_deque, 0);
-              break;
-            case MC_RANDOM:
-            case MC_PATH:
-            default:
-              NOT_REACHED ();
-            }
-          break;
-        case MC_DROP_RANDOM:
-          idx = random_queue_index (mc);
-          break;
-        default:
-          NOT_REACHED ();
-        }
-      free_state (mc, mc->queue[idx]);
-    }
-  mc->queue[idx] = new;
-}
-
-/* Process an error state being added to MC. */
-static void
-do_error_state (struct mc *mc)
-{
-  mc->results->error_count++;
-  if (mc->results->error_count >= mc->options->max_errors)
-    stop (mc, MC_MAX_ERROR_COUNT);
-
-  mc_path_copy (&mc->results->error_path, &mc->path);
-
-  if (mc->options->failure_verbosity > mc->options->verbosity)
-    {
-      struct mc_options *path_options;
-
-      fprintf (mc->options->output_file, "[%s] retracing error path:\n",
-               path_string (mc));
-      path_options = mc_options_clone (mc->options);
-      mc_options_set_verbosity (path_options, mc->options->failure_verbosity);
-      mc_options_set_failure_verbosity (path_options, 0);
-      mc_options_set_follow_path (path_options, &mc->path);
-
-      mc_results_destroy (mc_run (mc->class, path_options));
-
-      putc ('\n', mc->options->output_file);
-    }
-}
-
-/* Advances MC to start processing the operation following the
-   current one. */
-static void
-next_operation (struct mc *mc)
-{
-  mc_path_push (&mc->path, mc_path_pop (&mc->path) + 1);
-  mc->state_error = false;
-  mc->state_named = false;
-
-  if (++mc->progress >= mc->next_progress)
-    {
-      struct timeval now;
-      double elapsed, delta;
-
-      if (mc->results->stop_reason == MC_CONTINUING
-          && !mc->options->progress_func (mc))
-        stop (mc, MC_INTERRUPTED);
-
-      gettimeofday (&now, NULL);
-
-      if (mc->options->time_limit > 0.0
-          && (timeval_subtract (now, mc->results->start)
-              > mc->options->time_limit))
-        stop (mc, MC_TIMEOUT);
-
-      elapsed = timeval_subtract (now, mc->prev_progress_time);
-      if (elapsed > 0.0)
-        {
-          /* Re-estimate the amount of progress to take
-             progress_usec microseconds. */
-          unsigned int progress = mc->progress - mc->prev_progress;
-          double progress_sec = mc->options->progress_usec / 1000000.0;
-          delta = progress / elapsed * progress_sec;
-        }
-      else
-        {
-          /* No measurable time at all elapsed during that amount
-             of progress.  Try doubling the amount of progress
-             required. */
-          delta = (mc->progress - mc->prev_progress) * 2;
-        }
-
-      if (delta > 0.0 && delta + mc->progress + 1.0 < UINT_MAX)
-        mc->next_progress = mc->progress + delta + 1.0;
-      else
-        mc->next_progress = mc->progress + (mc->progress - mc->prev_progress);
-
-      mc->prev_progress = mc->progress;
-      mc->prev_progress_time = now;
-    }
-}
-
-/* Returns true if we're tracing an explicit path but the current
-   operation produces a state off that path, false otherwise. */
-static bool
-is_off_path (const struct mc *mc)
-{
-  return (mc->options->strategy == MC_PATH
-          && (mc_path_back (&mc->path)
-              != mc_path_get_operation (&mc->options->follow_path,
-                                        mc->path.length - 1)));
-}
-
-/* Handler for SIGINT. */
-static void
-sigint_handler (int signum UNUSED)
-{
-  /* Just mark the model checker as interrupted. */
-  *interrupted_ptr = true;
-}
-
-/* Initializes MC as a model checker with the given CLASS and
-   OPTIONS.  OPTIONS may be null to use the default options. */
-static void
-init_mc (struct mc *mc, const struct mc_class *class,
-         struct mc_options *options)
-{
-  /* Validate and adjust OPTIONS. */
-  if (options == NULL)
-    options = mc_options_create ();
-  assert (options->queue_limit_strategy != MC_DROP_OLDEST
-          || options->strategy != MC_RANDOM);
-  if (options->strategy == MC_PATH)
-    {
-      options->max_depth = INT_MAX;
-      options->hash_bits = 0;
-    }
-  if (options->progress_usec == 0)
-    {
-      options->progress_func = null_progress;
-      if (options->time_limit > 0.0)
-        options->progress_usec = 250000;
-    }
-
-  /* Initialize MC. */
-  mc->class = class;
-  mc->options = options;
-  mc->results = mc_results_create ();
-
-  mc->hash = (mc->options->hash_bits > 0
-              ? xcalloc (1, DIV_RND_UP (1 << mc->options->hash_bits, CHAR_BIT))
-              : NULL);
-
-  mc->queue = NULL;
-  deque_init_null (&mc->queue_deque);
-
-  mc_path_init (&mc->path);
-  mc_path_push (&mc->path, 0);
-  ds_init_empty (&mc->path_string);
-  mc->state_named = false;
-  mc->state_error = false;
-
-  mc->progress = 0;
-  mc->next_progress = mc->options->progress_usec != 0 ? 100 : UINT_MAX;
-  mc->prev_progress = 0;
-  mc->prev_progress_time = mc->results->start;
-
-  if (mc->options->strategy == MC_RANDOM
-      || options->queue_limit_strategy == MC_DROP_RANDOM)
-    srand (mc->options->seed);
-
-  mc->interrupted = false;
-  mc->saved_interrupted_ptr = interrupted_ptr;
-  interrupted_ptr = &mc->interrupted;
-  mc->saved_sigint = signal (SIGINT, sigint_handler);
-
-  class->init (mc);
-}
-
-/* Complete the model checker run for MC. */
-static void
-finish_mc (struct mc *mc)
-{
-  /* Restore signal handlers. */
-  signal (SIGINT, mc->saved_sigint);
-  interrupted_ptr = mc->saved_interrupted_ptr;
-
-  /* Mark the run complete. */
-  stop (mc, MC_SUCCESS);
-  gettimeofday (&mc->results->end, NULL);
-
-  /* Empty the queue. */
-  mc->results->queued_unprocessed_states = deque_count (&mc->queue_deque);
-  while (!deque_is_empty (&mc->queue_deque))
-    {
-      struct mc_state *state = mc->queue[deque_pop_front (&mc->queue_deque)];
-      free_state (mc, state);
-    }
-
-  /* Notify the progress function of completion. */
-  mc->options->progress_func (mc);
-
-  /* Free memory. */
-  mc_path_destroy (&mc->path);
-  ds_destroy (&mc->path_string);
-  free (mc->options);
-  free (mc->queue);
-  free (mc->hash);
-}
diff --git a/src/libpspp/model-checker.h b/src/libpspp/model-checker.h
deleted file mode 100644 (file)
index 8c86fae..0000000
+++ /dev/null
@@ -1,463 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-/* Implementation-level model checker.
-
-   A model checker is a tool for software testing and
-   verification that works by exploring all the possible states
-   in a system and verifying their internal consistency.  A
-   conventional model checker requires that the code in a system
-   be translated into a specification language.  The model
-   checker then verifies the specification, rather than the code.
-
-   This is instead an implementation-level model checker, which
-   does not require a separate specification.  Instead, the model
-   checker requires writing a second implementation of the system
-   being checked.  The second implementation can usually be made
-   almost trivial in comparison to the one being checked, because
-   it's usually acceptable for its performance to be
-   comparatively poor, e.g. O(N^2) instead of O(lg N), and thus
-   to use much simpler algorithms.
-
-   For introduction to the implementation-level model checking
-   approach used here, please refer to the following papers:
-
-     Musuvathi, Park, Chou, Engler, Dill, "CMC: A Pragmatic
-     Approach to Model Checking Real Code", Proceedings of the
-     Fifth Symposium on Operating Systems Design and
-     Implementation (OSDI), Dec 2002.
-     http://sprout.stanford.edu/PAPERS/CMC-OSDI-2002/CMC-OSDI-2002.pdf
-
-     Yang, Twohey, Engler, Musuvathi, "Using Model Checking to
-     Find Serious File System Errors", Proceedings of the Sixth
-     Symposium on Operating System Design and Implementation
-     (OSDI), Dec 2004.
-     http://www.stanford.edu/~engler/osdi04-fisc.pdf
-
-     Yang, Twohey, Pfaff, Sar, Engler, "EXPLODE: A Lightweight,
-     General Approach to Finding Serious Errors in Storage
-     Systems", First Workshop on the Evaluation of Software
-     Defect Detection Tools (BUGS), June 2005.
-     http://benpfaff.org/papers/explode.pdf
-
-   Use of a model checker is appropriate when the system being
-   checked is difficult to test using handwritten tests.  This
-   can be the case, for example, when the system has a
-   complicated internal state that is difficult to reason about
-   over a long series of operations.
-
-   The implementation model checker works by putting a set of one
-   of more initial states in a queue (and checking them for
-   consistency).  Then the model checker removes a state from the
-   queue and applies all possible operations of interest to it
-   ("mutates" it), obtaining a set of zero or more child states
-   (and checking each of them for consistency).  Each of these
-   states is itself added to the queue.  The model checker
-   continues dequeuing states and mutating and checking them
-   until the queue is empty.
-
-   In pseudo-code, the process looks like this:
-
-     Q = { initial states }
-     while Q is not empty:
-       S = dequeue(Q)
-       for each operation applicable to S do:
-         T = operation(S)
-         check(T)
-         enqueue(Q, T)
-
-   In many cases this process will never terminate, because every
-   state has one or more child states.  For some systems this is
-   unavoidable, but in others we can make the process finite by
-   pursuing a few stratagems:
-
-     1. Limit the maximum size of the system; for example, limit
-        the number of rows and columns in the implementation of a
-        table being checked.  The client of the model checker is
-        responsible for implementing such limits.
-
-     2. Avoid checking a single state more than one time.  This
-        model checker provides assistance for this function by
-        allowing the client to provide a hash of the system state.
-        States with identical hashes will only be checked once
-        during a single run.
-
-   When a system cannot be made finite, or when a finite system
-   is too large to check in a practical amount of time, the model
-   checker provides multiple ways to limit the checking run:
-   based on maximum depth, maximum unique states checked, maximum
-   errors found (by default, 1), or maximum time used for
-   checking.
-
-   The client of the model checker must provide three functions
-   via function pointers embedded into a "struct mc_class":
-
-     1. void init (struct mc *mc);
-
-        This function is called once at the beginning of a
-        checking run.  It checks one or more initial states and
-        adds them to the model checker's queue.  (If it does not
-        add any states to the queue, then there is nothing to
-        check.)
-
-        Here's an outline for writing the init function:
-
-          void
-          init_foo (struct mc *mc)
-          {
-            struct foo *foo;
-
-            mc_name_operation (mc, "initial state");
-            foo = generate_initial_foo ();
-            if (!state_is_consistent (foo))
-              mc_error (mc, "inconsistent state");
-            mc_add_state (mc, foo);
-          }
-
-     2. void mutate (struct mc *mc, const void *data);
-
-        This function is called when a dequeued state is ready to
-        be mutated.  For each operation that can be applied to
-        the client-specified DATA, it applies that operation to a
-        clone of the DATA, checks that the clone is consistent,
-        and adds the clone to the model checker's queue.
-
-        Here's an outline for writing the mutate function:
-
-          void
-          mutate_foo (struct mc *mc, void *state_)
-          {
-            struct foo *state = state_;
-
-            for (...each operation...)
-              if (mc_include_state (mc))
-                {
-                  struct foo *clone;
-
-                  mc_name_operation (mc, "do operation %s", ...);
-                  clone = clone_foo (state);
-                  do_operation (clone);
-                  if (!mc_discard_dup_state (mc, hash_foo (clone)))
-                    {
-                      if (!state_is_consistent (clone))
-                        mc_error (mc, "inconsistent state");
-                      mc_add_state (mc, clone);
-                    }
-                  else
-                    destroy_foo (clone);
-                }
-          }
-
-        Notes on the above outline:
-
-          - The call to mc_include_state allows currently
-            uninteresting operations to be skipped.  It is not
-            essential.
-
-          - The call to mc_name_operation should give the current
-            operation a human-readable name.  The name may
-            include printf-style format specifications.
-
-            When an error occurs, the model checker (by default)
-            replays the sequence of operations performed to reach
-            the error, printing the name of the operation at each
-            step, which is often sufficient information in itself
-            to debug the error.
-
-            At higher levels of verbosity, the name is printed
-            for each operation.
-
-          - Operations should be performed on a copy of the data
-            provided.  The data provided should not be destroyed
-            or modified.
-
-          - The call to mc_discard_dup_state is needed to discard
-            (probably) duplicate states.  It is otherwise
-            optional.
-
-            To reduce the probability of collisions, use a
-            high-quality hash function.  MD4 is a reasonable
-            choice: it is fast but high-quality.  In one test,
-            switching to MD4 from MD5 increased overall speed of
-            model checking by 8% and actually reduced (!) the
-            number of collisions.
-
-            The hash value needs to include enough of the state
-            to ensure that interesting states are not excluded,
-            but it need not include the entire state.  For
-            example, in many cases, the structure of complex data
-            (metadata) is often much more important than the
-            contents (data), so it may be reasonable to hash only
-            the metadata.
-
-            mc_discard_dup_state may be called before or after
-            checking for consistency, but calling it first avoids
-            wasting time checking duplicate states for
-            consistency, which again can be a significant
-            performance boost.
-
-          - The mc_error function reports errors.  It may be
-            called as many times as desired to report each kind
-            of inconsistency in a state.
-
-          - The mc_add_state function adds the new state to the
-            queue.  It should be called regardless of whether an
-            error was reported, to indicate to the model checker
-            that state processing has finished.
-
-          - The mutation function should be deterministic, to
-            make it possible to reliably reproduce errors.
-
-     3. void destroy (struct mc *mc, void *data);
-
-        This function is called to discard the client-specified
-        DATA associated with a state.
-
-   Numerous options are available for configuring the model
-   checker.  The most important of these are:
-
-     - Search algorithm:
-
-       * Breadth-first search (the default): First try all the
-         operations with depth 1, then those with depth 2, then
-         those with depth 3, and so on.
-
-         This search algorithm finds the least number of
-         operations needed to trigger a given bug.
-
-       * Depth-first search: Searches downward in the tree of
-         states as fast as possible.  Good for finding bugs that
-         require long sequences of operations to trigger.
-
-       * Random-first search: Searches through the tree of
-         states in random order.
-
-       * Explicit path: Applies an explicitly specified sequence
-         of operations.
-
-     - Verbosity: By default, messages are printed only when an
-       error is encountered, but you can cause the checker to
-       print a message on every state transition.  This is most
-       useful when the errors in your code cause segfaults or
-       some other kind of sudden termination.
-
-     - Treatment of errors: By default, when an error is
-       encountered, the model checker recursively invokes itself
-       with an increased verbosity level and configured to follow
-       only the error path.  As long as the mutation function is
-       deterministic, this quickly and concisely replays the
-       error and describes the path followed to reach it in an
-       easily human-readable manner.
-
-     - Limits:
-
-       * Maximum depth: You can limit the depth of the operations
-         performed.  Most often useful with depth-first search.
-         By default, depth is unlimited.
-
-       * Maximum queue length: You can limit the number of states
-         kept in the queue at any given time.  The main reason to
-         do so is to limit memory consumption.  The default
-         limit is 10,000 states.  Several strategies are
-         available for choosing which state to drop when the
-         queue overflows.
-
-     - Stop conditions: based on maximum unique states checked,
-       maximum errors found (by default, 1), or maximum time used
-       for checking.
-
-     - Progress: by default, the checker prints a '.' on stderr
-       every .25 seconds, but you can substitute another progress
-       function or disable progress printing.
-
-   This model checker does not (yet) include two features
-   described in the papers cited above: utility scoring
-   heuristics to guide the search strategy and "choice points" to
-   explore alternative cases.  The former feature is less
-   interesting for this model checker, because the data
-   structures we are thus far using it to model are much smaller
-   than those discussed in the paper.  The latter feature we
-   should implement at some point. */
-
-#ifndef LIBPSPP_MODEL_CHECKER_H
-#define LIBPSPP_MODEL_CHECKER_H 1
-
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <sys/time.h>
-
-#include <libpspp/compiler.h>
-
-/* An active model checking run. */
-struct mc;
-
-/* Provided by each client of the model checker. */
-struct mc_class
-  {
-    void (*init) (struct mc *);
-    void (*mutate) (struct mc *, const void *);
-    void (*destroy) (const struct mc *, void *);
-  };
-
-/* Results of a model checking run. */
-struct mc_results;
-
-/* Configuration for running the model checker. */
-struct mc_options;
-
-/* Primary external interface to model checker. */
-struct mc_results *mc_run (const struct mc_class *, struct mc_options *);
-
-/* Functions for use from client-supplied "init" and "mutate"
-   functions. */
-bool mc_include_state (struct mc *);
-bool mc_discard_dup_state (struct mc *, unsigned int hash);
-void mc_name_operation (struct mc *, const char *, ...) PRINTF_FORMAT (2, 3);
-void mc_vname_operation (struct mc *, const char *, va_list)
-     PRINTF_FORMAT (2, 0);
-void mc_error (struct mc *, const char *, ...) PRINTF_FORMAT (2, 3);
-void mc_add_state (struct mc *, void *data);
-
-/* Functions for use from client-supplied "init", "mutate", and
-   "destroy" functions. */
-const struct mc_options *mc_get_options (const struct mc *);
-const struct mc_results *mc_get_results (const struct mc *);
-void *mc_get_aux (const struct mc *);
-\f
-/* A path of operations through a model to arrive at some
-   particular state. */
-struct mc_path
-  {
-    int *ops;           /* Sequence of operations. */
-    size_t length;      /* Number of operations. */
-    size_t capacity;    /* Number of operations for which room is allocated. */
-  };
-
-void mc_path_init (struct mc_path *);
-void mc_path_copy (struct mc_path *, const struct mc_path *);
-void mc_path_push (struct mc_path *, int new_state);
-int mc_path_pop (struct mc_path *);
-int mc_path_back (const struct mc_path *);
-void mc_path_destroy (struct mc_path *);
-
-int mc_path_get_operation (const struct mc_path *, size_t index);
-size_t mc_path_get_length (const struct mc_path *);
-
-struct string;
-void mc_path_to_string (const struct mc_path *, struct string *);
-\f
-struct mc_options *mc_options_create (void);
-struct mc_options *mc_options_clone (const struct mc_options *);
-void mc_options_destroy (struct mc_options *);
-
-/* Search strategy. */
-enum mc_strategy
-  {
-    MC_BROAD,           /* Breadth-first search. */
-    MC_DEEP,            /* Depth-first search. */
-    MC_RANDOM,          /* Randomly ordered search. */
-    MC_PATH             /* Follow one explicit path. */
-  };
-
-enum mc_strategy mc_options_get_strategy (const struct mc_options *);
-void mc_options_set_strategy (struct mc_options *, enum mc_strategy);
-unsigned int mc_options_get_seed (const struct mc_options *);
-void mc_options_set_seed (struct mc_options *, unsigned int seed);
-int mc_options_get_max_depth (const struct mc_options *);
-void mc_options_set_max_depth (struct mc_options *, int max_depth);
-int mc_options_get_hash_bits (const struct mc_options *);
-void mc_options_set_hash_bits (struct mc_options *, int hash_bits);
-
-const struct mc_path *mc_options_get_follow_path (const struct mc_options *);
-void mc_options_set_follow_path (struct mc_options *, const struct mc_path *);
-
-/* Strategy for dropped states from the queue when it
-   overflows. */
-enum mc_queue_limit_strategy
-  {
-    MC_DROP_NEWEST,     /* Don't enqueue the new state at all. */
-    MC_DROP_OLDEST,     /* Drop the oldest state in the queue. */
-    MC_DROP_RANDOM      /* Drop a random state from the queue. */
-  };
-
-int mc_options_get_queue_limit (const struct mc_options *);
-void mc_options_set_queue_limit (struct mc_options *, int queue_limit);
-enum mc_queue_limit_strategy mc_options_get_queue_limit_strategy (
-  const struct mc_options *);
-void mc_options_set_queue_limit_strategy (struct mc_options *,
-                                          enum mc_queue_limit_strategy);
-
-int mc_options_get_max_unique_states (const struct mc_options *);
-void mc_options_set_max_unique_states (struct mc_options *,
-                                       int max_unique_states);
-int mc_options_get_max_errors (const struct mc_options *);
-void mc_options_set_max_errors (struct mc_options *, int max_errors);
-double mc_options_get_time_limit (const struct mc_options *);
-void mc_options_set_time_limit (struct mc_options *, double time_limit);
-
-int mc_options_get_verbosity (const struct mc_options *);
-void mc_options_set_verbosity (struct mc_options *, int verbosity);
-int mc_options_get_failure_verbosity (const struct mc_options *);
-void mc_options_set_failure_verbosity (struct mc_options *,
-                                       int failure_verbosity);
-FILE *mc_options_get_output_file (const struct mc_options *);
-void mc_options_set_output_file (struct mc_options *, FILE *);
-
-typedef bool mc_progress_func (struct mc *);
-int mc_options_get_progress_usec (const struct mc_options *);
-void mc_options_set_progress_usec (struct mc_options *, int progress_usec);
-mc_progress_func *mc_options_get_progress_func (const struct mc_options *);
-void mc_options_set_progress_func (struct mc_options *, mc_progress_func *);
-
-void *mc_options_get_aux (const struct mc_options *);
-void mc_options_set_aux (struct mc_options *, void *aux);
-\f
-/* Reason that a model checking run terminated. */
-enum mc_stop_reason
-  {
-    MC_CONTINUING,              /* Run has not yet terminated. */
-    MC_SUCCESS,                 /* Queue emptied (ran out of states). */
-    MC_MAX_UNIQUE_STATES,       /* Did requested number of unique states. */
-    MC_MAX_ERROR_COUNT,         /* Too many errors. */
-    MC_END_OF_PATH,             /* Processed requested path (MC_PATH only). */
-    MC_TIMEOUT,                 /* Timeout. */
-    MC_INTERRUPTED              /* Received SIGINT (Ctrl+C). */
-  };
-
-void mc_results_destroy (struct mc_results *);
-
-enum mc_stop_reason mc_results_get_stop_reason (const struct mc_results *);
-int mc_results_get_unique_state_count (const struct mc_results *);
-int mc_results_get_error_count (const struct mc_results *);
-
-int mc_results_get_max_depth_reached (const struct mc_results *);
-double mc_results_get_mean_depth_reached (const struct mc_results *);
-
-const struct mc_path *mc_results_get_error_path (const struct mc_results *);
-
-int mc_results_get_duplicate_dropped_states (const struct mc_results *);
-int mc_results_get_off_path_dropped_states (const struct mc_results *);
-int mc_results_get_depth_dropped_states (const struct mc_results *);
-int mc_results_get_queue_dropped_states (const struct mc_results *);
-int mc_results_get_queued_unprocessed_states (const struct mc_results *);
-int mc_results_get_max_queue_length (const struct mc_results *);
-
-struct timeval mc_results_get_start (const struct mc_results *);
-struct timeval mc_results_get_end (const struct mc_results *);
-double mc_results_get_duration (const struct mc_results *);
-
-#endif /* libpspp/model-checker.h */
index eba5d8327a2f0b8e9202c8e3244d8b90ac17cd89..7af219bcb080cd0a75b8b6bf9f823d2f397618a1 100644 (file)
@@ -88,7 +88,7 @@ struct sparse_array
 /* An internal node in the radix tree. */
 struct internal_node
   {
-    int count;                  /* Number of nonnul children. */
+    int count;                  /* Number of nonnull children. */
     union pointer down[PTRS_PER_LEVEL]; /* Children. */
   };
 
index 9a7c6da8bfa8c36e50cca3cfd7b7bfe99a6cf0db..d082672060f5235d6610939221365663fb5652b8 100644 (file)
@@ -194,15 +194,18 @@ buf_copy_rpad (char *dst, size_t dst_size,
 void
 str_copy_rpad (char *dst, size_t dst_size, const char *src)
 {
-  size_t src_len = strlen (src);
-  if (src_len < dst_size - 1)
+  if (dst_size > 0) 
     {
-      memcpy (dst, src, src_len);
-      memset (&dst[src_len], ' ', dst_size - 1 - src_len);
+      size_t src_len = strlen (src);
+      if (src_len < dst_size - 1)
+        {
+          memcpy (dst, src, src_len);
+          memset (&dst[src_len], ' ', dst_size - 1 - src_len);
+        }
+      else
+        memcpy (dst, src, dst_size - 1);
+      dst[dst_size - 1] = 0;
     }
-  else
-    memcpy (dst, src, dst_size - 1);
-  dst[dst_size - 1] = 0;
 }
 
 /* Copies SRC to DST, which is in a buffer DST_SIZE bytes long.
diff --git a/src/math/ChangeLog b/src/math/ChangeLog
deleted file mode 100644 (file)
index 2462058..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * linreg.c (pspp_linreg): Accept a struct design_matrix.  Use new
-       accessor functions pspp_coeff_get_mean, pspp_coeff_get_sd.  New
-       functions pspp_linreg_get_indep_variable_mean,
-       pspp_linreg_set_indep_variable_mean,
-       pspp_linreg_get_indep_variable_sd,
-       pspp_linreg_set_indep_variable_sd. Altered pspp_linreg_get_coeff
-       to use accessor function pspp_coeff_var_to_coeff.
-
-       * coefficient.c: New functions pspp_coeff_get_mean,
-       pspp_coeff_set_mean, pspp_coeff_get_sd, pspp_coeff_set_sd,
-       pspp_coeff_var_to_coeff. Added doubles to hold mean and standard
-       deviation in struct varinfo.
-
-2008-06-14  Jason Stover  <jhs@math.gcsu.edu>
-
-       * linreg/: moved linreg.[ch] to src/math.
-
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6512.
-
-       * moments.c (calc_moments): Use gsl_finite instead of finite, as a
-       stopgap measure for portability until appropriate gnulib modules
-       are available.
-
-2008-03-10  Jason Stover  <jhs@math.gcsu.edu>
-
-       * coefficient.c (pspp_linreg_get_coeff): Removed use of
-       coefficient 0 as intercept.
-
-2008-03-01  Jason Stover  <jhs@math.gcsu.edu>
-
-       * coefficient.c (pspp_coeff_init): Ensure first arg is not a null
-       pointer.
-
-       * coefficient.c (pspp_linreg_get_coeff): Make sure we don't return
-       a result beyond the last coefficient, or start with a coefficient
-       beyond the last one if there is only one.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-
-       * automake.mk: Add new files.
-       
-       * levene.c: Adapt to new casereaders.  Abstract better.
-
-       * merge.c: New file.
-
-       * merge.h: New file.
-
-       * sort.c: Rewrite in terms of case_ordering, merger.
-
-2007-05-31  Jason Stover  <jhs@math.gcsu.edu>
-
-       * interaction.c: New file.
-       * interaction.h : New file.
-
-Mon Feb  5 15:42:14 2007  Ben Pfaff  <blp@gnu.org>
-
-       * moments.c (moments_pass_two): Reduce number of multiplications.
-
-Thu Dec  7 15:27:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * factor-stats.c factor-stats.h: Changed independent values to 
-       be pointers rather than copies.
-
-Wed Dec  6 21:14:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       * coefficient.c: (pspp_coeff_get_value) Compare variable pointers
-       instead of variable indexes.
-       (pspp_linreg_get_coeff) Ditto.
-       (design_matrix_col_to_var_index) Removed.
-       (design_matrix_col_to_var) Compare variable pointers
-       instead of variable indexes.
-       (cmp_dm_var_index) Ditto.
-       (design_matrix_var_to_column) Ditto.
-       (dm_var_to_last_column) Ditto.
-
-Sun Nov  5 08:30:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * levene.c levene.h Changed to use the new casefilter structure.
-
-2006-07-15  Jason Stover  <jhs@math.gcsu.edu>
-
-       * coefficient.c (pspp_coeff_init): Make design_matrix arg const.
-
-2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
-
-       * coefficient.c (pspp_coeff_init): Removed use of
-       pspp_linreg_cache to make the routines more generally useful.
-
-2006-05-19  Jason Stover  <jhs@math.gcsu.edu>
-
-       * coefficient.h: Renamed pspp_linreg_coeff to pspp_coeff.
-
-       * coefficient.c: Moved to src/math.
-
-       * coefficient.h: Moved to src/math.
-
-Tue May  9 21:09:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * sort.c (sort_active_file_to_casefile): Check return value of
-       multipass_procedure().
-
-Wed May  3 23:06:43 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * sort.c: (prepare_to_sort_active_file) Don't run a procedure
-       here.
-       (sort_active_file_in_place) Rewrite to run a procedure, capture
-       the output, sort the output, and set that as the source for the
-       next procedure.
-       (struct sort_to_casefile_cb_data) New structure.
-       (sort_to_casefile_callback) New function.
-       (sort_active_file_to_casefile) Rewrite to use
-       multipass_procedure().
-
-Sat Apr 29 11:09:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * removed unused variable.
-
-Sat Apr 15 18:01:22 2006  Ben Pfaff  <blp@gnu.org>
-
-       * factor-stats.c (metrics_postcalc): Add casts to fix warnings.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/math/OChangeLog b/src/math/OChangeLog
new file mode 100644 (file)
index 0000000..0025534
--- /dev/null
@@ -0,0 +1,197 @@
+2008-08-17  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * linreg.c (post_sweep_computations): New function to re-use the
+       re-usable. New function cache_init() to re-use the re-usable. 
+       pspp_linreg_with_cov() now estimates parameters via reg_sweep().
+
+2008-08-16  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * linreg.c (pspp_linreg_with_cov): New function to estimate
+       parameters directly from covariance matrix instead of using the
+       entire data set.
+
+       * linreg.c (rearrange_covariance_matrix): New function to ensure
+       the columns of the covariance matrix correspond to the variables
+       in the model.
+
+2008-07-24   John Darrington <john@darrington.wattle.id.au>
+
+       * merge.c merge.h sort.c sort.h: Removed the value_cnt associated
+       with case ordering.  This ensures that the casereader returned by
+       sort_execute now has the same dimensions as the casereader passed 
+       in.
+
+2008-07-24  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * covariance-matrix.c (covariance_pass_two): Dropped weight
+       argument. Corrected update of the entries of the covariance
+       matrix. 
+
+       * covariance-matrix.c (column_iterate): Dropped weight
+       argument. Corrected update of the entries of the covariance
+       matrix. 
+
+       * covariance-matrix.c (covariance_update_categorical_numeric):
+       Dropped weight argument. Corrected update of the entries of the
+       covariance matrix.
+
+2008-07-17  Jason H Stover  <jhs@math.gcsu.edu>
+
+       * covariance-matrix.c (covariance_update_categorical_numeric):
+       Altered to match new code in covariance_pass_two();
+
+       * covariance-matrix.h: Fix declaration of covariance_pass_two.
+
+       * covariance-matrix.c (covariance_pass_two): Moved numeric and
+       categorical scopes of V2 inside for loop. If V1 is not
+       categorical, but V2 is, recurse with the order of the variables
+       reversed to use the code in the previous "if" scope.
+
+2008-07-16  Jason Stover  <jhs@math.gcsu.edu>
+
+       * covariance-matrix.c (covariance_pass_two): Renamed
+       covariance_pass_one. Fixed update of covariance matrix when both
+       variables are categorical.
+       (column_iterate): New function.
+
+2008-07-15  Jason Stover  <jhs@math.gcsu.edu>
+
+       * covariance-matrix.c (covariance_pass_one): New file, new function.
+
+2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * linreg.c (pspp_linreg): Accept a struct design_matrix.  Use new
+       accessor functions pspp_coeff_get_mean, pspp_coeff_get_sd.  New
+       functions pspp_linreg_get_indep_variable_mean,
+       pspp_linreg_set_indep_variable_mean,
+       pspp_linreg_get_indep_variable_sd,
+       pspp_linreg_set_indep_variable_sd. Altered pspp_linreg_get_coeff
+       to use accessor function pspp_coeff_var_to_coeff.
+
+       * coefficient.c: New functions pspp_coeff_get_mean,
+       pspp_coeff_set_mean, pspp_coeff_get_sd, pspp_coeff_set_sd,
+       pspp_coeff_var_to_coeff. Added doubles to hold mean and standard
+       deviation in struct varinfo.
+
+2008-06-14  Jason Stover  <jhs@math.gcsu.edu>
+
+       * linreg/: moved linreg.[ch] to src/math.
+
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6512.
+
+       * moments.c (calc_moments): Use gsl_finite instead of finite, as a
+       stopgap measure for portability until appropriate gnulib modules
+       are available.
+
+2008-03-10  Jason Stover  <jhs@math.gcsu.edu>
+
+       * coefficient.c (pspp_linreg_get_coeff): Removed use of
+       coefficient 0 as intercept.
+
+2008-03-01  Jason Stover  <jhs@math.gcsu.edu>
+
+       * coefficient.c (pspp_coeff_init): Ensure first arg is not a null
+       pointer.
+
+       * coefficient.c (pspp_linreg_get_coeff): Make sure we don't return
+       a result beyond the last coefficient, or start with a coefficient
+       beyond the last one if there is only one.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+
+       * automake.mk: Add new files.
+       
+       * levene.c: Adapt to new casereaders.  Abstract better.
+
+       * merge.c: New file.
+
+       * merge.h: New file.
+
+       * sort.c: Rewrite in terms of case_ordering, merger.
+
+2007-05-31  Jason Stover  <jhs@math.gcsu.edu>
+
+       * interaction.c: New file.
+       * interaction.h : New file.
+
+Mon Feb  5 15:42:14 2007  Ben Pfaff  <blp@gnu.org>
+
+       * moments.c (moments_pass_two): Reduce number of multiplications.
+
+Thu Dec  7 15:27:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * factor-stats.c factor-stats.h: Changed independent values to 
+       be pointers rather than copies.
+
+Wed Dec  6 21:14:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       * coefficient.c: (pspp_coeff_get_value) Compare variable pointers
+       instead of variable indexes.
+       (pspp_linreg_get_coeff) Ditto.
+       (design_matrix_col_to_var_index) Removed.
+       (design_matrix_col_to_var) Compare variable pointers
+       instead of variable indexes.
+       (cmp_dm_var_index) Ditto.
+       (design_matrix_var_to_column) Ditto.
+       (dm_var_to_last_column) Ditto.
+
+Sun Nov  5 08:30:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * levene.c levene.h Changed to use the new casefilter structure.
+
+2006-07-15  Jason Stover  <jhs@math.gcsu.edu>
+
+       * coefficient.c (pspp_coeff_init): Make design_matrix arg const.
+
+2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
+
+       * coefficient.c (pspp_coeff_init): Removed use of
+       pspp_linreg_cache to make the routines more generally useful.
+
+2006-05-19  Jason Stover  <jhs@math.gcsu.edu>
+
+       * coefficient.h: Renamed pspp_linreg_coeff to pspp_coeff.
+
+       * coefficient.c: Moved to src/math.
+
+       * coefficient.h: Moved to src/math.
+
+Tue May  9 21:09:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * sort.c (sort_active_file_to_casefile): Check return value of
+       multipass_procedure().
+
+Wed May  3 23:06:43 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * sort.c: (prepare_to_sort_active_file) Don't run a procedure
+       here.
+       (sort_active_file_in_place) Rewrite to run a procedure, capture
+       the output, sort the output, and set that as the source for the
+       next procedure.
+       (struct sort_to_casefile_cb_data) New structure.
+       (sort_to_casefile_callback) New function.
+       (sort_active_file_to_casefile) Rewrite to use
+       multipass_procedure().
+
+Sat Apr 29 11:09:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * removed unused variable.
+
+Sat Apr 15 18:01:22 2006  Ben Pfaff  <blp@gnu.org>
+
+       * factor-stats.c (metrics_postcalc): Add casts to fix warnings.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index cff7f96032b1c55a3c3a63baccbebdc5f674e5ce..e463088779f385fa0b58ccc7edc6ba720c1bddc8 100644 (file)
@@ -2,28 +2,34 @@
 
 include $(top_srcdir)/src/math/ts/automake.mk
 
-noinst_LIBRARIES += src/math/libpspp_math.a
+noinst_LTLIBRARIES += src/math/libpspp-math.la
 
-src_math_libpspp_math_a_SOURCES = \
-       src/math/factor-stats.c \
-       src/math/factor-stats.h \
+src_math_libpspp_math_la_LIBADD = \
+       lib/linreg/liblinreg.la
+
+src_math_libpspp_math_la_SOURCES = \
        src/math/chart-geometry.c \
        src/math/chart-geometry.h \
+       src/math/box-whisker.c src/math/box-whisker.h \
        src/math/coefficient.c \
        src/math/coefficient.h \
+       src/math/covariance-matrix.c \
+       src/math/covariance-matrix.h \
+       src/math/design-matrix.c src/math/design-matrix.h \
+       src/math/extrema.c src/math/extrema.h \
        src/math/group.c  src/math/group.h \
        src/math/group-proc.h \
        src/math/histogram.c src/math/histogram.h \
-       src/math/interaction.c \
-       src/math/interaction.h \
-       src/math/levene.c \
-       src/math/levene.h \
-       src/math/linreg.c \
-       src/math/linreg.h \
-       src/math/merge.c \
-       src/math/merge.h \
+       src/math/interaction.c src/math/interaction.h \
+       src/math/levene.c src/math/levene.h \
+       src/math/linreg.c src/math/linreg.h \
+       src/math/merge.c  src/math/merge.h \
        src/math/moments.c  src/math/moments.h \
+       src/math/np.c src/math/np.h \
+       src/math/order-stats.c src/math/order-stats.h \
        src/math/percentiles.c src/math/percentiles.h \
-       src/math/design-matrix.c src/math/design-matrix.h \
        src/math/random.c src/math/random.h \
-       src/math/sort.c src/math/sort.h 
+        src/math/statistic.h \
+       src/math/sort.c src/math/sort.h \
+       src/math/trimmed-mean.c src/math/trimmed-mean.h \
+       src/math/tukey-hinges.c src/math/tukey-hinges.h 
diff --git a/src/math/box-whisker.c b/src/math/box-whisker.c
new file mode 100644 (file)
index 0000000..288fc07
--- /dev/null
@@ -0,0 +1,139 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "box-whisker.h"
+#include "order-stats.h"
+#include "tukey-hinges.h"
+#include <gl/xalloc.h>
+#include <libpspp/assertion.h>
+#include <math.h>
+#include <float.h>
+#include <data/val-type.h>
+#include <libpspp/str.h>
+#include <data/case.h>
+#include <data/variable.h>
+
+static void
+destroy (struct statistic *s)
+{
+  struct order_stats *os = (struct order_stats *) s;
+  struct box_whisker *bw = (struct box_whisker *) s;
+  struct ll *ll;
+
+  for (ll = ll_head (&bw->outliers); ll != ll_null (&bw->outliers); )
+    {
+      struct outlier *e = ll_data (ll, struct outlier, ll);
+
+      ll = ll_next (ll);
+
+      ds_destroy (&e->label);
+      free (e);
+    }
+
+  free (os->k);
+  free (s);
+};
+
+
+static void
+acc (struct statistic *s, const struct ccase *cx,
+     double c UNUSED, double cc UNUSED, double y)
+{
+  struct box_whisker *bw = (struct box_whisker *) s;
+  bool extreme;
+  struct outlier *o;
+
+  if ( y < bw->hinges[2] + bw->step)
+      bw->whiskers[1] = y;
+
+  if (bw->whiskers[0] == SYSMIS ||  bw->hinges[0] - bw->step > y)
+      bw->whiskers[0] = y;
+
+  if ( y > bw->hinges[2] + bw->step)
+    extreme = (y > bw->hinges[2] + 2 * bw->step) ;
+
+  else if (y < bw->hinges[0] - bw->step)
+    extreme = (y < bw->hinges[0] - 2 * bw->step) ;
+
+  else
+    return;
+
+  o = xzalloc (sizeof *o) ;
+  o->value = y;
+  o->extreme = extreme;
+  ds_init_empty (&o->label);
+
+  if (bw->id_var)
+    var_append_value_name (bw->id_var,
+                          case_data (cx, bw->id_var),
+                          &o->label);
+  else
+    ds_put_format (&o->label,
+                  "%ld",
+                  (casenumber) case_data_idx (cx, bw->casenumber_idx)->f);
+
+  ll_push_head (&bw->outliers, &o->ll);
+}
+
+void
+box_whisker_whiskers (const struct box_whisker *bw, double whiskers[2])
+{
+  whiskers[0] = bw->whiskers[0];
+  whiskers[1] = bw->whiskers[1];
+}
+
+void
+box_whisker_hinges (const struct box_whisker *bw, double hinges[3])
+{
+  hinges[0] = bw->hinges[0];
+  hinges[1] = bw->hinges[1];
+  hinges[2] = bw->hinges[2];
+}
+
+const struct ll_list *
+box_whisker_outliers (const struct box_whisker *bw)
+{
+  return &bw->outliers;
+}
+
+struct statistic *
+box_whisker_create (const struct tukey_hinges *th,
+                   const struct variable *id_var,  size_t casenumber_idx)
+{
+  struct box_whisker *w = xzalloc (sizeof (*w));
+  struct order_stats *os = (struct order_stats *) w;
+  struct statistic *stat = (struct statistic *) w;
+
+  os->n_k = 0;
+
+  stat->destroy = destroy;
+  stat->accumulate = acc;
+
+  tukey_hinges_calculate (th, w->hinges);
+
+  w->casenumber_idx = casenumber_idx;
+  w->id_var = id_var;
+
+  w->step = (w->hinges[2] - w->hinges[0]) * 1.5;
+
+  w->whiskers[1] = w->hinges[2];
+  w->whiskers[0] = SYSMIS;
+
+  ll_init (&w->outliers);
+
+  return stat;
+}
diff --git a/src/math/box-whisker.h b/src/math/box-whisker.h
new file mode 100644 (file)
index 0000000..5202b64
--- /dev/null
@@ -0,0 +1,65 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __MATH_BOX_WHISKER_H__
+#define __MATH_BOX_WHISKER_H__
+
+#include <stddef.h>
+#include <libpspp/ll.h>
+#include <libpspp/str.h>
+#include "order-stats.h"
+
+/* This module calculates the statistics typically displayed by box-plots.
+   However, there's no reason not to use it for other purposes too.
+ */
+struct tukey_hinges;
+
+
+struct outlier
+{
+  double value;
+  struct string label;
+  bool extreme;
+  struct ll ll;
+};
+
+
+struct box_whisker
+{
+  struct order_stats parent;
+
+  double hinges[3];
+  double whiskers[2];
+
+  struct ll_list outliers;
+
+  double step;
+
+  size_t casenumber_idx;
+  const struct variable *id_var;
+};
+
+struct statistic * box_whisker_create (const struct tukey_hinges *,
+                                        const struct variable *, size_t);
+
+void box_whisker_whiskers (const struct box_whisker *bw, double whiskers[2]);
+
+void box_whisker_hinges (const struct box_whisker *bw, double hinges[2]);
+
+const struct ll_list * box_whisker_outliers (const struct box_whisker *bw);
+
+
+#endif
index 4f987612ff07d727e60d750b3395d19a3a3e0ac2..f738c783f241fedd1137d3100a372c5664b8341b 100644 (file)
@@ -153,20 +153,28 @@ pspp_coeff_get_var (struct pspp_coeff *coef, int i)
   categorical, and has more than one coefficient, use the VAL to find
   its coefficient.
  */
-const struct pspp_coeff *
+struct pspp_coeff *
 pspp_coeff_var_to_coeff (const struct variable *v, struct pspp_coeff **coefs, 
                         size_t n_coef, const union value *val)
 {
   size_t i = 0;
   size_t j = 0;
   size_t v_idx;
+
   struct pspp_coeff *result = NULL;
 
   if (v != NULL)
     {
       v_idx = var_get_dict_index (v);
-      while (i < n_coef && var_get_dict_index (coefs[i]->v_info->v) != v_idx)
+      while (i < n_coef)
        {
+         if (coefs[i]->v_info != NULL)
+           {
+             if (var_get_dict_index (coefs[i]->v_info->v) == v_idx)
+               {
+                 break;
+               }
+           }
          i++;
        }
       result = coefs[i];
@@ -179,7 +187,7 @@ pspp_coeff_var_to_coeff (const struct variable *v, struct pspp_coeff **coefs,
            {
              j = i;
              while (j < n_coef && compare_values (pspp_coeff_get_value (coefs[j], v),
-                                                  val, var_get_width (v)) != 0)
+                                                  val, v) != 0)
                {
                  j++;
                }
index dda2ae30cf292cb5008f0bf7e14a8440daeaf76e..705c1e0e488f3927483946b62f37815c144cc599 100644 (file)
@@ -101,7 +101,7 @@ int pspp_coeff_get_n_vars (struct pspp_coeff *);
   coefficient found. Note that in this case, the result will depend on
   the order of COEFS.
  */
-const struct pspp_coeff *
+struct pspp_coeff *
 pspp_coeff_var_to_coeff (const struct variable *, struct pspp_coeff **, size_t, const union value *);
 
 /*
diff --git a/src/math/covariance-matrix.c b/src/math/covariance-matrix.c
new file mode 100644 (file)
index 0000000..fb67a64
--- /dev/null
@@ -0,0 +1,775 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+  Create and update the values in the covariance matrix.
+*/
+#include <assert.h>
+#include <config.h>
+#include <data/case.h>
+#include <data/category.h>
+#include <data/variable.h>
+#include <data/value.h>
+#include <libpspp/hash.h>
+#include <libpspp/hash-functions.h>
+#include <math/covariance-matrix.h>
+#include <math/moments.h>
+#include <string.h>
+#include <xalloc.h>
+
+/*
+  Structure used to accumulate the covariance matrix in a single data
+  pass.  Before passing the data, we do not know how many categories
+  there are in each categorical variable. Therefore we do not know the
+  size of the covariance matrix. To get around this problem, we
+  accumulate the elements of the covariance matrix in pointers to
+  COVARIANC_ACCUMULATOR. These values are then used to populate
+  the covariance matrix.
+ */
+struct covariance_accumulator
+{
+  const struct variable *v1;
+  const struct variable *v2;
+  const union value *val1;
+  const union value *val2;
+  double dot_product;
+  double sum1;
+  double sum2;
+  double ssize;
+};
+
+
+
+struct covariance_matrix
+{
+  struct design_matrix *cov;
+  struct hsh_table *ca;
+  struct moments1 **m1;
+  struct moments **m;
+  const struct variable **v_variables;
+  size_t n_variables;
+  int n_pass;
+  int missing_handling;
+  enum mv_class missing_value;
+  void (*accumulate) (struct covariance_matrix *, const struct ccase *);
+  void (*update_moments) (struct covariance_matrix *, size_t, double);
+};
+
+static struct hsh_table *covariance_hsh_create (size_t);
+static hsh_hash_func covariance_accumulator_hash;
+static unsigned int hash_numeric_alpha (const struct variable *,
+                                       const struct variable *,
+                                       const union value *, size_t);
+static hsh_compare_func covariance_accumulator_compare;
+static hsh_free_func covariance_accumulator_free;
+static void update_moments1 (struct covariance_matrix *, size_t, double);
+static void update_moments2 (struct covariance_matrix *, size_t, double);
+static struct covariance_accumulator *get_new_covariance_accumulator (const
+                                                                     struct
+                                                                     variable
+                                                                     *,
+                                                                     const
+                                                                     struct
+                                                                     variable
+                                                                     *,
+                                                                     const
+                                                                     union
+                                                                     value *,
+                                                                     const
+                                                                     union
+                                                                     value
+                                                                     *);
+static void covariance_accumulate_listwise (struct covariance_matrix *,
+                                           const struct ccase *);
+static void covariance_accumulate_pairwise (struct covariance_matrix *,
+                                           const struct ccase *);
+
+struct covariance_matrix *
+covariance_matrix_init (size_t n_variables,
+                       const struct variable *v_variables[], int n_pass,
+                       int missing_handling, enum mv_class missing_value)
+{
+  size_t i;
+  struct covariance_matrix *result = NULL;
+
+  result = xmalloc (sizeof (*result));
+  result->cov = NULL;
+  result->ca = covariance_hsh_create (n_variables);
+  result->m = NULL;
+  result->m1 = NULL;
+  result->missing_handling = missing_handling;
+  result->missing_value = missing_value;
+  result->accumulate = (result->missing_handling == LISTWISE) ?
+    covariance_accumulate_listwise : covariance_accumulate_pairwise;
+  if (n_pass == ONE_PASS)
+    {
+      result->update_moments = update_moments1;
+      result->m1 = xnmalloc (n_variables, sizeof (*result->m1));
+      for (i = 0; i < n_variables; i++)
+       {
+         result->m1[i] = moments1_create (MOMENT_MEAN);
+       }
+    }
+  else
+    {
+      result->update_moments = update_moments2;
+      result->m = xnmalloc (n_variables, sizeof (*result->m));
+      for (i = 0; i < n_variables; i++)
+       {
+         result->m[i] = moments_create (MOMENT_MEAN);
+       }
+    }
+  result->v_variables = v_variables;
+  result->n_variables = n_variables;
+  result->n_pass = n_pass;
+
+  return result;
+}
+
+/*
+  The covariances are stored in a DESIGN_MATRIX structure.
+ */
+struct design_matrix *
+covariance_matrix_create (size_t n_variables,
+                         const struct variable *v_variables[])
+{
+  return design_matrix_create (n_variables, v_variables,
+                              (size_t) n_variables);
+}
+
+static void
+update_moments1 (struct covariance_matrix *cov, size_t i, double x)
+{
+  assert (cov->m1 != NULL);
+  moments1_add (cov->m1[i], x, 1.0);
+}
+
+static void
+update_moments2 (struct covariance_matrix *cov, size_t i, double x)
+{
+  assert (cov->m != NULL);
+  moments_pass_one (cov->m[i], x, 1.0);
+}
+
+void
+covariance_matrix_destroy (struct covariance_matrix *cov)
+{
+  size_t i;
+
+  assert (cov != NULL);
+  design_matrix_destroy (cov->cov);
+  hsh_destroy (cov->ca);
+  if (cov->n_pass == ONE_PASS)
+    {
+      for (i = 0; i < cov->n_variables; i++)
+       {
+         moments1_destroy (cov->m1[i]);
+       }
+      free (cov->m1);
+    }
+  else
+    {
+      for (i = 0; i < cov->n_variables; i++)
+       {
+         moments_destroy (cov->m[i]);
+       }
+      free (cov->m);
+    }
+}
+
+/*
+  Update the covariance matrix with the new entries, assuming that ROW
+  corresponds to a categorical variable and V2 is numeric.
+ */
+static void
+covariance_update_categorical_numeric (struct design_matrix *cov, double mean,
+                                      size_t row,
+                                      const struct variable *v2, double x,
+                                      const union value *val2)
+{
+  size_t col;
+  double tmp;
+
+  assert (var_is_numeric (v2));
+
+  col = design_matrix_var_to_column (cov, v2);
+  assert (val2 != NULL);
+  tmp = gsl_matrix_get (cov->m, row, col);
+  gsl_matrix_set (cov->m, row, col, (val2->f - mean) * x + tmp);
+  gsl_matrix_set (cov->m, col, row, (val2->f - mean) * x + tmp);
+}
+static void
+column_iterate (struct design_matrix *cov, const struct variable *v,
+               double ssize, double x, const union value *val1, size_t row)
+{
+  size_t col;
+  size_t i;
+  double y;
+  double tmp;
+  const union value *tmp_val;
+
+  col = design_matrix_var_to_column (cov, v);
+  for (i = 0; i < cat_get_n_categories (v) - 1; i++)
+    {
+      col += i;
+      y = -1.0 * cat_get_category_count (i, v) / ssize;
+      tmp_val = cat_subscript_to_value (i, v);
+      if (compare_values (tmp_val, val1, v))
+       {
+         y += -1.0;
+       }
+      tmp = gsl_matrix_get (cov->m, row, col);
+      gsl_matrix_set (cov->m, row, col, x * y + tmp);
+      gsl_matrix_set (cov->m, col, row, x * y + tmp);
+    }
+}
+
+/*
+  Call this function in the second data pass. The central moments are
+  MEAN1 and MEAN2. Any categorical variables should already have their
+  values summarized in in its OBS_VALS element.
+ */
+void
+covariance_pass_two (struct design_matrix *cov, double mean1, double mean2,
+                    double ssize, const struct variable *v1,
+                    const struct variable *v2, const union value *val1,
+                    const union value *val2)
+{
+  size_t row;
+  size_t col;
+  size_t i;
+  double x;
+  const union value *tmp_val;
+
+  if (var_is_alpha (v1))
+    {
+      row = design_matrix_var_to_column (cov, v1);
+      for (i = 0; i < cat_get_n_categories (v1) - 1; i++)
+       {
+         row += i;
+         x = -1.0 * cat_get_category_count (i, v1) / ssize;
+         tmp_val = cat_subscript_to_value (i, v1);
+         if (compare_values (tmp_val, val1, v1))
+           {
+             x += 1.0;
+           }
+         if (var_is_numeric (v2))
+           {
+             covariance_update_categorical_numeric (cov, mean2, row,
+                                                    v2, x, val2);
+           }
+         else
+           {
+             column_iterate (cov, v1, ssize, x, val1, row);
+             column_iterate (cov, v2, ssize, x, val2, row);
+           }
+       }
+    }
+  else if (var_is_alpha (v2))
+    {
+      /*
+         Reverse the orders of V1, V2, etc. and put ourselves back
+         in the previous IF scope.
+       */
+      covariance_pass_two (cov, mean2, mean1, ssize, v2, v1, val2, val1);
+    }
+  else
+    {
+      /*
+         Both variables are numeric.
+       */
+      row = design_matrix_var_to_column (cov, v1);
+      col = design_matrix_var_to_column (cov, v2);
+      x = (val1->f - mean1) * (val2->f - mean2);
+      x += gsl_matrix_get (cov->m, col, row);
+      gsl_matrix_set (cov->m, row, col, x);
+      gsl_matrix_set (cov->m, col, row, x);
+    }
+}
+
+static unsigned int
+covariance_accumulator_hash (const void *h, const void *aux)
+{
+  struct covariance_accumulator *ca = (struct covariance_accumulator *) h;
+  size_t *n_vars = (size_t *) aux;
+  size_t idx_max;
+  size_t idx_min;
+  const struct variable *v_min;
+  const struct variable *v_max;
+  const union value *val_min;
+  const union value *val_max;
+
+  /*
+     Order everything by the variables' indices. This ensures we get the
+     same key regardless of the order in which the variables are stored
+     and passed around.
+   */
+  v_min =
+    (var_get_dict_index (ca->v1) <
+     var_get_dict_index (ca->v2)) ? ca->v1 : ca->v2;
+  v_max = (ca->v1 == v_min) ? ca->v2 : ca->v1;
+
+  val_min = (v_min == ca->v1) ? ca->val1 : ca->val2;
+  val_max = (ca->val1 == val_min) ? ca->val2 : ca->val1;
+
+  idx_min = var_get_dict_index (v_min);
+  idx_max = var_get_dict_index (v_max);
+
+  if (var_is_numeric (v_max) && var_is_numeric (v_min))
+    {
+      return (*n_vars * idx_max + idx_min);
+    }
+  if (var_is_numeric (v_max) && var_is_alpha (v_min))
+    {
+      return hash_numeric_alpha (v_max, v_min, val_min, *n_vars);
+    }
+  if (var_is_alpha (v_max) && var_is_numeric (v_min))
+    {
+      return (hash_numeric_alpha (v_min, v_max, val_max, *n_vars));
+    }
+  if (var_is_alpha (v_max) && var_is_alpha (v_min))
+    {
+      unsigned int tmp;
+      char *x =
+       xnmalloc (1 + var_get_width (v_max) + var_get_width (v_min),
+                 sizeof (*x));
+      strncpy (x, val_max->s, var_get_width (v_max));
+      strncat (x, val_min->s, var_get_width (v_min));
+      tmp = *n_vars * (*n_vars + 1 + idx_max) + idx_min + hsh_hash_string (x);
+      free (x);
+      return tmp;
+    }
+  return -1u;
+}
+
+/*
+  Make a hash table consisting of struct covariance_accumulators.
+  This allows the accumulation of the elements of a covariance matrix
+  in a single data pass. Call covariance_accumulate () for each case 
+  in the data.
+ */
+static struct hsh_table *
+covariance_hsh_create (size_t n_vars)
+{
+  return hsh_create (n_vars * n_vars, covariance_accumulator_compare,
+                    covariance_accumulator_hash, covariance_accumulator_free,
+                    &n_vars);
+}
+
+static void
+covariance_accumulator_free (void *c_, const void *aux UNUSED)
+{
+  struct covariance_accumulator *c = c_;
+  assert (c != NULL);
+  free (c);
+}
+
+/*
+  Hash comparison. Returns 0 for a match, or a non-zero int
+  otherwise. The sign of a non-zero return value *should* indicate the
+  position of C relative to the covariance_accumulator described by
+  the other arguments. But for now, it just returns 1 for any
+  non-match.  This should be changed when someone figures out how to
+  compute a sensible sign for the return value.
+ */
+static int
+match_nodes (const struct covariance_accumulator *c,
+            const struct variable *v1, const struct variable *v2,
+            const union value *val1, const union value *val2)
+{
+  if (var_get_dict_index (v1) == var_get_dict_index (c->v1))
+    if (var_get_dict_index (v2) == var_get_dict_index (c->v2))
+      {
+       if (var_is_numeric (v1) && var_is_numeric (v2))
+         {
+           return 0;
+         }
+       if (var_is_numeric (v1) && var_is_alpha (v2))
+         {
+           if (compare_values (val2, c->val2, v2))
+             {
+               return 0;
+             }
+         }
+       if (var_is_alpha (v1) && var_is_numeric (v2))
+         {
+           if (compare_values (val1, c->val1, v1))
+             {
+               return 0;
+             }
+         }
+       if (var_is_alpha (v1) && var_is_alpha (v2))
+         {
+           if (compare_values (val1, c->val1, v1))
+             {
+               if (compare_values (val2, c->val2, v2))
+                 {
+                   return 0;
+                 }
+             }
+         }
+      }
+  return 1;
+}
+
+/*
+  This function is meant to be used as a comparison function for
+  a struct hsh_table in src/libpspp/hash.c.
+*/
+static int
+covariance_accumulator_compare (const void *a1_, const void *a2_,
+                               const void *aux UNUSED)
+{
+  const struct covariance_accumulator *a1 = a1_;
+  const struct covariance_accumulator *a2 = a2_;
+
+  if (a1 == NULL && a2 == NULL)
+    return 0;
+
+  if (a1 == NULL || a2 == NULL)
+    return 1;
+
+  return match_nodes (a1, a2->v1, a2->v2, a2->val1, a2->val2);
+}
+
+static unsigned int
+hash_numeric_alpha (const struct variable *v1, const struct variable *v2,
+                   const union value *val, size_t n_vars)
+{
+  unsigned int result = -1u;
+  if (var_is_numeric (v1) && var_is_alpha (v2))
+    {
+      result = n_vars * ((n_vars + 1) + var_get_dict_index (v1))
+       + var_get_dict_index (v2) + hsh_hash_string (val->s);
+    }
+  else if (var_is_alpha (v1) && var_is_numeric (v2))
+    {
+      result = hash_numeric_alpha (v2, v1, val, n_vars);
+    }
+  return result;
+}
+
+
+static double
+update_product (const struct variable *v1, const struct variable *v2,
+               const union value *val1, const union value *val2)
+{
+  assert (v1 != NULL);
+  assert (v2 != NULL);
+  assert (val1 != NULL);
+  assert (val2 != NULL);
+  if (var_is_alpha (v1) && var_is_alpha (v2))
+    {
+      return 1.0;
+    }
+  if (var_is_numeric (v1) && var_is_numeric (v2))
+    {
+      return (val1->f * val2->f);
+    }
+  if (var_is_numeric (v1) && var_is_alpha (v2))
+    {
+      return (val1->f);
+    }
+  if (var_is_numeric (v2) && var_is_alpha (v1))
+    {
+      update_product (v2, v1, val2, val1);
+    }
+  return 0.0;
+}
+static double
+update_sum (const struct variable *var, const union value *val)
+{
+  assert (var != NULL);
+  assert (val != NULL);
+  if (var_is_alpha (var))
+    {
+      return 1.0;
+    }
+  return val->f;
+}
+static struct covariance_accumulator *
+get_new_covariance_accumulator (const struct variable *v1,
+                               const struct variable *v2,
+                               const union value *val1,
+                               const union value *val2)
+{
+  if ((v1 != NULL) && (v2 != NULL) && (val1 != NULL) && (val2 != NULL))
+    {
+      struct covariance_accumulator *ca;
+      ca = xmalloc (sizeof (*ca));
+      ca->v1 = v1;
+      ca->v2 = v2;
+      ca->val1 = val1;
+      ca->val2 = val2;
+      return ca;
+    }
+  return NULL;
+}
+
+static const struct variable **
+get_covariance_variables (const struct covariance_matrix *cov)
+{
+  return cov->v_variables;
+}
+
+static void
+update_hash_entry (struct hsh_table *c,
+                  const struct variable *v1,
+                  const struct variable *v2,
+                  const union value *val1, const union value *val2)
+{
+  struct covariance_accumulator *ca;
+  struct covariance_accumulator *new_entry;
+
+
+  ca = get_new_covariance_accumulator (v1, v2, val1, val2);
+  ca->dot_product = update_product (ca->v1, ca->v2, ca->val1, ca->val2);
+  ca->sum1 = update_sum (ca->v1, ca->val1);
+  ca->sum2 = update_sum (ca->v2, ca->val2);
+  ca->ssize = 1.0;
+  new_entry = hsh_insert (c, ca);
+  if (new_entry != NULL)
+    {
+      new_entry->dot_product += ca->dot_product;
+      new_entry->ssize += 1.0;
+      new_entry->sum1 += ca->sum1;
+      new_entry->sum2 += ca->sum2;
+      /*
+         If DOT_PRODUCT is null, CA was not already in the hash
+         hable, so we don't free it because it was just inserted.
+         If DOT_PRODUCT was not null, CA is already in the hash table.
+         Unnecessary now, it must be freed here.
+       */
+      free (ca);
+    }
+}
+
+/*
+  Compute the covariance matrix in a single data-pass. Cases with
+  missing values are dropped pairwise, in other words, only if one of
+  the two values necessary to accumulate the inner product is missing.
+
+  Do not call this function directly. Call it through the struct
+  covariance_matrix ACCUMULATE member function, for example,
+  cov->accumulate (cov, ccase).
+ */
+static void
+covariance_accumulate_pairwise (struct covariance_matrix *cov,
+                               const struct ccase *ccase)
+{
+  size_t i;
+  size_t j;
+  const union value *val1;
+  const union value *val2;
+  const struct variable **v_variables;
+
+  assert (cov != NULL);
+  assert (ccase != NULL);
+
+  v_variables = get_covariance_variables (cov);
+  assert (v_variables != NULL);
+
+  for (i = 0; i < cov->n_variables; ++i)
+    {
+      val1 = case_data (ccase, v_variables[i]);
+      if (!var_is_value_missing (v_variables[i], val1, cov->missing_value))
+       {
+         cat_value_update (v_variables[i], val1);
+         if (var_is_alpha (v_variables[i]))
+           cov->update_moments (cov, i, val1->f);
+
+         for (j = i; j < cov->n_variables; j++)
+           {
+             val2 = case_data (ccase, v_variables[j]);
+             if (!var_is_value_missing
+                 (v_variables[j], val2, cov->missing_value))
+               {
+                 update_hash_entry (cov->ca, v_variables[i], v_variables[j],
+                                    val1, val2);
+                 if (j != i)
+                   update_hash_entry (cov->ca, v_variables[j],
+                                      v_variables[i], val2, val1);
+               }
+           }
+       }
+    }
+}
+
+/*
+  Compute the covariance matrix in a single data-pass. Cases with
+  missing values are dropped listwise. In other words, if one of the
+  values for any variable in a case is missing, the entire case is
+  skipped. 
+
+  The caller must use a casefilter to remove the cases with missing
+  values before calling covariance_accumulate_listwise. This function
+  assumes that CCASE has already passed through this filter, and
+  contains no missing values.
+
+  Do not call this function directly. Call it through the struct
+  covariance_matrix ACCUMULATE member function, for example,
+  cov->accumulate (cov, ccase).
+ */
+static void
+covariance_accumulate_listwise (struct covariance_matrix *cov,
+                               const struct ccase *ccase)
+{
+  size_t i;
+  size_t j;
+  const union value *val1;
+  const union value *val2;
+  const struct variable **v_variables;
+
+  assert (cov != NULL);
+  assert (ccase != NULL);
+
+  v_variables = get_covariance_variables (cov);
+  assert (v_variables != NULL);
+
+  for (i = 0; i < cov->n_variables; ++i)
+    {
+      val1 = case_data (ccase, v_variables[i]);
+      cat_value_update (v_variables[i], val1);
+      if (var_is_alpha (v_variables[i]))
+       cov->update_moments (cov, i, val1->f);
+
+      for (j = i; j < cov->n_variables; j++)
+       {
+         val2 = case_data (ccase, v_variables[j]);
+         update_hash_entry (cov->ca, v_variables[i], v_variables[j],
+                            val1, val2);
+         if (j != i)
+           update_hash_entry (cov->ca, v_variables[j], v_variables[i],
+                              val2, val1);
+       }
+    }
+}
+
+/*
+  Call this function during the data pass. Each case will be added to
+  a hash containing all values of the covariance matrix. After the
+  data have been passed, call covariance_matrix_compute to put the
+  values in the struct covariance_matrix.
+ */
+void
+covariance_matrix_accumulate (struct covariance_matrix *cov,
+                             const struct ccase *ccase)
+{
+  cov->accumulate (cov, ccase);
+}
+
+static void
+covariance_matrix_insert (struct design_matrix *cov,
+                         const struct variable *v1,
+                         const struct variable *v2, const union value *val1,
+                         const union value *val2, double product)
+{
+  size_t row;
+  size_t col;
+  size_t i;
+  const union value *tmp_val;
+
+  assert (cov != NULL);
+
+  row = design_matrix_var_to_column (cov, v1);
+  if (var_is_alpha (v1))
+    {
+      i = 0;
+      tmp_val = cat_subscript_to_value (i, v1);
+      while (!compare_values (tmp_val, val1, v1))
+       {
+         i++;
+         tmp_val = cat_subscript_to_value (i, v1);
+       }
+      row += i;
+      if (var_is_numeric (v2))
+       {
+         col = design_matrix_var_to_column (cov, v2);
+       }
+      else
+       {
+         col = design_matrix_var_to_column (cov, v2);
+         i = 0;
+         tmp_val = cat_subscript_to_value (i, v1);
+         while (!compare_values (tmp_val, val1, v1))
+           {
+             i++;
+             tmp_val = cat_subscript_to_value (i, v1);
+           }
+         col += i;
+       }
+    }
+  else
+    {
+      if (var_is_numeric (v2))
+       {
+         col = design_matrix_var_to_column (cov, v2);
+       }
+      else
+       {
+         covariance_matrix_insert (cov, v2, v1, val2, val1, product);
+       }
+    }
+  gsl_matrix_set (cov->m, row, col, product);
+}
+
+static struct design_matrix *
+covariance_accumulator_to_matrix (struct covariance_matrix *cov)
+{
+  double tmp;
+  struct covariance_accumulator *entry;
+  struct design_matrix *result = NULL;
+  struct hsh_iterator iter;
+
+  result = covariance_matrix_create (cov->n_variables, cov->v_variables);
+
+  entry = hsh_first (cov->ca, &iter);
+
+  while (entry != NULL)
+    {
+      /*
+         We compute the centered, un-normalized covariance matrix.
+       */
+      tmp = entry->dot_product - entry->sum1 * entry->sum2 / entry->ssize;
+      covariance_matrix_insert (result, entry->v1, entry->v2, entry->val1,
+                               entry->val2, tmp);
+      entry = hsh_next (cov->ca, &iter);
+    }
+  return result;
+}
+
+
+/*
+  Call this function after passing the data.
+ */
+void
+covariance_matrix_compute (struct covariance_matrix *cov)
+{
+  if (cov->n_pass == ONE_PASS)
+    {
+      cov->cov = covariance_accumulator_to_matrix (cov);
+    }
+}
+
+struct design_matrix *
+covariance_to_design (const struct covariance_matrix *c)
+{
+  if (c != NULL)
+    {
+      return c->cov;
+    }
+  return NULL;
+}
diff --git a/src/math/covariance-matrix.h b/src/math/covariance-matrix.h
new file mode 100644 (file)
index 0000000..33a5d75
--- /dev/null
@@ -0,0 +1,58 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+  Create covariance matrices for procedures that need them.
+ */
+
+#ifndef COVARIANCE_MATRIX_H
+#define COVARIANCE_MATRIX_H
+
+#include <math/design-matrix.h>
+
+struct moments1;
+struct ccase;
+struct hsh_table;
+struct covariance_matrix;
+enum
+{ ONE_PASS,
+  TWO_PASS
+};
+
+/*
+  How to deal with missing values.
+ */
+enum
+{ LISTWISE,
+  PAIRWISE
+};
+struct design_matrix *covariance_matrix_create (size_t,
+                                               const struct variable *[]);
+
+void covariance_matrix_destroy (struct covariance_matrix *cov);
+void covariance_pass_two (struct design_matrix *, double,
+                         double, double, const struct variable *,
+                         const struct variable *, const union value *,
+                         const union value *);
+void covariance_matrix_compute (struct covariance_matrix *);
+struct covariance_matrix *covariance_matrix_init (size_t,
+                                                 const struct variable *[],
+                                                 int, int, enum mv_class);
+void covariance_matrix_free (struct covariance_matrix *);
+void covariance_matrix_accumulate (struct covariance_matrix *,
+                                  const struct ccase *);
+struct design_matrix *covariance_to_design (const struct covariance_matrix *);
+#endif
index 298d03357b7208e66392c0b15bec0eb9e0f0146b..df68287b36e04e8077db317fa780cfeb648553b5 100644 (file)
@@ -54,10 +54,12 @@ design_matrix_create (int n_variables,
 
   dm = xmalloc (sizeof *dm);
   dm->vars = xnmalloc (n_variables, sizeof *dm->vars);
+  dm->n_cases = xnmalloc (n_variables, sizeof (*dm->n_cases));
   dm->n_vars = n_variables;
 
   for (i = 0; i < n_variables; i++)
     {
+      dm->n_cases[i] = 0;
       v = v_variables[i];
       assert ((dm->vars + i) != NULL);
       (dm->vars + i)->v = v;   /* Allows us to look up the variable from
@@ -79,6 +81,7 @@ design_matrix_create (int n_variables,
   dm->m = gsl_matrix_calloc (n_data, n_cols);
   col = 0;
 
+  
   return dm;
 }
 
@@ -87,6 +90,7 @@ design_matrix_destroy (struct design_matrix *dm)
 {
   free (dm->vars);
   gsl_matrix_free (dm->m);
+  free (dm->n_cases);
   free (dm);
 }
 
@@ -191,3 +195,67 @@ design_matrix_set_numeric (struct design_matrix *dm, size_t row,
   assert (col != DM_COLUMN_NOT_FOUND);
   gsl_matrix_set (dm->m, row, col, val->f);
 }
+
+struct design_matrix *
+design_matrix_clone (const struct design_matrix *dm)
+{
+  struct design_matrix *result;
+  size_t i;
+  
+  assert (dm != NULL);
+  result = xmalloc (sizeof *result);
+  result->vars = xnmalloc (dm->n_vars, sizeof *dm->vars);
+  result->n_vars = dm->n_vars;
+  result->m = gsl_matrix_alloc (dm->m->size1, dm->m->size2);
+  
+  gsl_matrix_memcpy (result->m, dm->m);
+  for (i = 0; i < result->n_vars; i++)
+    {
+      result->vars[i] = dm->vars[i];
+    }
+  return result;
+}
+
+/*
+  Increment the number of cases for V.
+ */
+void 
+design_matrix_increment_case_count (struct design_matrix *dm, const struct variable *v)
+{
+  size_t i;
+  assert (dm != NULL);
+  assert (dm->n_cases != NULL);
+  assert (v != NULL);
+  i = design_matrix_var_to_column (dm, v);
+  dm->n_cases[i]++;
+}
+
+/*
+  Set the number of cases for V.
+ */
+void 
+design_matrix_set_case_count (struct design_matrix *dm, const struct variable *v, size_t n)
+{
+  size_t i;
+  assert (dm != NULL);
+  assert (dm->n_cases != NULL);
+  assert (v != NULL);
+  i = design_matrix_var_to_column (dm, v);
+  dm->n_cases[i] = n;
+}
+
+/*
+  Get the number of cases for V.
+ */
+size_t 
+design_matrix_get_case_count (const struct design_matrix *dm, const struct variable *v)
+{
+  size_t i;
+  assert (dm != NULL);
+  assert (dm->n_cases != NULL);
+  assert (v != NULL);
+  i = design_matrix_var_to_column (dm, v);
+  return dm->n_cases[i];
+}
+
+  
index ad2b82585229c3d9c52d119865f7dfe76e2d9bd3..ba7f984218261d5db40af8c41a864b51c1af886a 100644 (file)
@@ -58,6 +58,9 @@ struct design_matrix
                                           design_matrix_var
                                           structure.
                                         */
+  size_t *n_cases; /* Element i is the number of valid cases for this
+                     variable.
+                   */
   size_t n_vars;
 };
 
@@ -75,10 +78,16 @@ void design_matrix_set_numeric (struct design_matrix *, size_t,
                                    const struct variable *,
                                    const union value *);
 
+struct design_matrix *design_matrix_clone (const struct design_matrix *);
+
 size_t design_matrix_var_to_column (const struct design_matrix *,
                                    const struct variable *);
 
 const struct variable *design_matrix_col_to_var (const struct design_matrix *,
                                           size_t);
+void design_matrix_increment_case_count (struct design_matrix *, const struct variable *);
+
+void design_matrix_set_case_count (struct design_matrix *, const struct variable *, size_t);
 
+size_t design_matrix_get_case_count (const struct design_matrix *, const struct variable *);
 #endif
diff --git a/src/math/extrema.c b/src/math/extrema.c
new file mode 100644 (file)
index 0000000..617c7ac
--- /dev/null
@@ -0,0 +1,144 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "extrema.h"
+#include <xalloc.h>
+#include <data/case.h>
+#include <data/val-type.h>
+#include <libpspp/compiler.h>
+#include <libpspp/ll.h>
+#include <stdlib.h>
+
+struct extrema
+{
+  size_t capacity;
+  size_t n;
+  struct ll_list list;
+
+  ll_compare_func *cmp_func;
+};
+
+
+static int
+cmp_descending (const struct ll *a_, const struct ll *b_, void *aux UNUSED)
+{
+  const struct extremum *a = ll_data (a_, struct extremum, ll);
+  const struct extremum *b = ll_data (b_, struct extremum, ll);
+
+  if ( a->value > b->value) return -1;
+
+  return (a->value < b->value);
+}
+
+static int
+cmp_ascending (const struct ll *a_, const struct ll *b_, void *aux UNUSED)
+{
+  const struct extremum *a = ll_data (a_, struct extremum, ll);
+  const struct extremum *b = ll_data (b_, struct extremum, ll);
+
+  if ( a->value < b->value) return -1;
+
+  return (a->value > b->value);
+}
+
+
+struct extrema *
+extrema_create (size_t n, enum extreme_end end)
+{
+  struct extrema *extrema = xzalloc (sizeof *extrema);
+  extrema->capacity = n;
+
+  if ( end == EXTREME_MAXIMA )
+    extrema->cmp_func = cmp_descending;
+  else
+    extrema->cmp_func = cmp_ascending;
+
+  ll_init (&extrema->list);
+
+  return extrema;
+}
+
+void
+extrema_destroy (struct extrema *extrema)
+{
+  struct ll *ll = ll_head (&extrema->list);
+
+  while (ll != ll_null (&extrema->list))
+    {
+      struct extremum *e = ll_data (ll, struct extremum, ll);
+
+      ll = ll_next (ll);
+      free (e);
+    }
+
+  free (extrema);
+}
+
+
+void
+extrema_add (struct extrema *extrema, double val,
+            double weight,
+            casenumber location)
+{
+  struct extremum *e = xzalloc (sizeof *e) ;
+  e->value = val;
+  e->location = location;
+  e->weight = weight;
+
+  if ( val == SYSMIS)
+    {
+      free (e);
+      return;
+    }
+
+  ll_insert_ordered (ll_head (&extrema->list), ll_null (&extrema->list),
+                      &e->ll,  extrema->cmp_func, NULL);
+
+  if ( extrema->n++ > extrema->capacity)
+    {
+      struct ll *tail = ll_tail (&extrema->list);
+      struct extremum *et = ll_data (tail, struct extremum, ll);
+
+      ll_remove (tail);
+
+      free (et);
+    }
+}
+
+
+const struct ll_list *
+extrema_list (const struct extrema *ex)
+{
+  return &ex->list;
+}
+
+
+bool
+extrema_top (const struct extrema *ex, double *v)
+{
+  const struct extremum  *top;
+
+  if ( ll_is_empty (&ex->list))
+    return false;
+
+  top = (const struct extremum *)
+    ll_data (ll_head(&ex->list), struct extremum, ll);
+
+  *v = top->value;
+
+  return true;
+}
diff --git a/src/math/extrema.h b/src/math/extrema.h
new file mode 100644 (file)
index 0000000..d891c53
--- /dev/null
@@ -0,0 +1,58 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __EXTREMA_H__
+#define __EXTREMA_H__ 1
+
+#include <stddef.h>
+#include <data/case.h>
+#include <libpspp/ll.h>
+
+struct extremum
+{
+  double value;
+  casenumber location;
+  double weight;
+
+  /* Internal use only */
+  struct ll ll;
+};
+
+
+enum extreme_end
+  {
+    EXTREME_MAXIMA,
+    EXTREME_MINIMA
+  };
+
+struct extrema;
+
+struct extrema *extrema_create (size_t n, enum extreme_end);
+
+void extrema_destroy (struct extrema *extrema);
+
+void extrema_add (struct extrema *extrema, double val,
+                 double weight,
+                 casenumber location);
+
+void extrema_show (const struct extrema *extrema);
+
+const struct ll_list * extrema_list (const struct extrema *);
+
+bool extrema_top (const struct extrema *, double *);
+
+
+#endif
diff --git a/src/math/factor-stats.c b/src/math/factor-stats.c
deleted file mode 100644 (file)
index a97d7f0..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "factor-stats.h"
-#include <data/val-type.h>
-#include <data/value.h>
-#include <libpspp/hash.h>
-#include <libpspp/array.h>
-#include "moments.h"
-#include "percentiles.h"
-
-#include <stdlib.h>
-#include <math.h>
-#include <float.h>
-#include <assert.h>
-#include "histogram.h"
-
-#include "xalloc.h"
-
-void
-metrics_precalc(struct metrics *m)
-{
-  assert (m) ;
-
-  m->n_missing = 0;
-
-  m->min = DBL_MAX;
-  m->max = -DBL_MAX;
-
-  m->histogram = 0;
-
-  m->moments = moments1_create(MOMENT_KURTOSIS);
-
-  m->ordered_data = hsh_create(20,
-                               (hsh_compare_func *) compare_values,
-                               (hsh_hash_func *) hash_value,
-                               (hsh_free_func *) weighted_value_free,
-                               (void *) 0);
-}
-
-
-/* Include val in the calculation for the metrics.
-   If val is null, then treat it as MISSING
-*/
-void
-metrics_calc (struct metrics *fs, const union value *val,
-             double weight, int case_no)
-{
-  struct weighted_value **wv;
-  double x;
-
-  if ( ! val )
-    {
-      fs->n_missing += weight;
-      return ;
-    }
-
-  x = val->f;
-
-  moments1_add(fs->moments, x, weight);
-
-  if ( x < fs->min) fs->min = x;
-  if ( x > fs->max) fs->max = x;
-
-  wv = (struct weighted_value **) hsh_probe (fs->ordered_data,(void *) val );
-
-  if ( *wv  )
-    {
-      /* If this value has already been seen, then simply
-        increase its weight  and push a new case number */
-
-      struct case_node *cn;
-
-      assert( (*wv)->v.f == val->f );
-      (*wv)->w += weight;
-
-      cn = xmalloc ( sizeof *cn);
-      cn->next = (*wv)->case_nos ;
-      cn->num = case_no;
-
-      (*wv)->case_nos = cn;
-    }
-  else
-    {
-      struct case_node *cn;
-
-      *wv = weighted_value_create();
-      (*wv)->v = *val;
-      (*wv)->w = weight;
-
-      cn = xmalloc (sizeof *cn);
-      cn->next=0;
-      cn->num = case_no;
-      (*wv)->case_nos  = cn;
-
-    }
-
-}
-
-void
-metrics_postcalc(struct metrics *m)
-{
-  double cc = 0.0;
-  double tc ;
-  int k1, k2 ;
-  int i;
-  int j = 1;
-
-  moments1_calculate (m->moments, &m->n, &m->mean, &m->var,
-                     &m->skewness, &m->kurtosis);
-
-  moments1_destroy (m->moments);
-
-
-  m->stddev = sqrt(m->var);
-
-  /* FIXME: Check this is correct ???
-     Shouldn't we use the sample variance ??? */
-  m->se_mean = sqrt (m->var / m->n) ;
-
-
-
-  m->wvp = (struct weighted_value **) hsh_sort(m->ordered_data);
-  m->n_data = hsh_count(m->ordered_data);
-
-  /* Trimmed mean calculation */
-  if ( m->n_data <= 1 )
-    {
-      m->trimmed_mean = m->mean;
-      return;
-    }
-
-  m->histogram = histogram_create(10, m->min, m->max);
-
-  for ( i = 0 ; i < m->n_data ; ++i )
-    {
-      struct weighted_value **wv = (m->wvp) ;
-      gsl_histogram_accumulate(m->histogram, wv[i]->v.f, wv[i]->w);
-    }
-
-  tc = m->n * 0.05 ;
-  k1 = -1;
-  k2 = -1;
-
-  for ( i = 0 ; i < m->n_data ; ++i )
-    {
-      cc += m->wvp[i]->w;
-      m->wvp[i]->cc = cc;
-
-      m->wvp[i]->rank = j + (m->wvp[i]->w - 1) / 2.0 ;
-
-      j += m->wvp[i]->w;
-
-      if ( cc < tc )
-       k1 = i;
-    }
-
-
-
-  k2 = m->n_data;
-  for ( i = m->n_data -1  ; i >= 0; --i )
-    {
-      if ( tc > m->n - m->wvp[i]->cc)
-       k2 = i;
-    }
-
-
-  /* Calculate the percentiles */
-  ptiles (m->ptile_hash, (const struct weighted_value **) m->wvp,
-          m->n_data, m->n, m->ptile_alg);
-
-  tukey_hinges ((const struct weighted_value **) m->wvp,
-                m->n_data, m->n, m->hinge);
-
-  /* Special case here */
-  if ( k1 + 1 == k2 )
-    {
-      m->trimmed_mean = m->wvp[k2]->v.f;
-      return;
-    }
-
-  m->trimmed_mean = 0;
-  for ( i = k1 + 2 ; i <= k2 - 1 ; ++i )
-    {
-      m->trimmed_mean += m->wvp[i]->v.f * m->wvp[i]->w;
-    }
-
-
-  m->trimmed_mean += (m->n - m->wvp[k2 - 1]->cc - tc) * m->wvp[k2]->v.f ;
-  m->trimmed_mean += (m->wvp[k1 + 1]->cc - tc) * m->wvp[k1 + 1]->v.f ;
-  m->trimmed_mean /= 0.9 * m->n ;
-
-
-}
-
-
-struct weighted_value *
-weighted_value_create(void)
-{
-  struct weighted_value *wv;
-  wv = xmalloc (sizeof *wv);
-
-  wv->cc = 0;
-  wv->case_nos = 0;
-
-  return wv;
-}
-
-void
-weighted_value_free(struct weighted_value *wv)
-{
-  struct case_node *cn ;
-
-  if ( !wv )
-    return ;
-
-  cn = wv->case_nos;
-
-  while(cn)
-    {
-      struct case_node *next = cn->next;
-
-      free(cn);
-      cn = next;
-    }
-
-  free(wv);
-
-}
-
-
-
-
-
-/* Create a factor statistics object with for N dependent vars
-   and ID0 and ID1 as the values of the independent variable */
-struct factor_statistics *
-create_factor_statistics (int n,
-                         union value *id0,
-                         union value *id1)
-{
-  struct factor_statistics *f;
-
-  f = xmalloc (sizeof *f);
-
-  f->id[0] = id0;
-  f->id[1] = id1;
-  f->m = xnmalloc (n, sizeof *f->m);
-  memset (f->m, 0, sizeof(struct metrics) * n);
-  f->n_var = n;
-
-  return f;
-}
-
-void
-metrics_destroy(struct metrics *m)
-{
-  hsh_destroy(m->ordered_data);
-  hsh_destroy(m->ptile_hash);
-  if ( m-> histogram )
-    gsl_histogram_free(m->histogram);
-}
-
-void
-factor_statistics_free(struct factor_statistics *f)
-{
-
-  int i;
-  free (f->id[0]);
-  free (f->id[1]);
-  for ( i = 0 ; i < f->n_var; ++i )
-       metrics_destroy(&f->m[i]);
-  free(f->m) ;
-  free(f);
-}
-
-
-int
-factor_statistics_compare(const struct factor_statistics *f0,
-                         const struct factor_statistics *f1, int width)
-{
-
-  int cmp0;
-
-  assert(f0);
-  assert(f1);
-
-  cmp0 = compare_values(f0->id[0], f1->id[0], width);
-
-  if ( cmp0 != 0 )
-    return cmp0;
-
-
-  if ( ( f0->id[1]->f == SYSMIS ) && (f1->id[1]->f != SYSMIS) )
-    return 1;
-
-  if ( ( f0->id[1]->f != SYSMIS )  && (f1->id[1]->f == SYSMIS) )
-    return -1;
-
-  return compare_values (f0->id[1], f1->id[1], width);
-}
-
-unsigned int
-factor_statistics_hash (const struct factor_statistics *f, int width)
-{
-  unsigned int h;
-
-  h = hash_value (f->id[0], width);
-
-  if ( f->id[1]->f != SYSMIS )
-    h += hash_value(f->id[1], width);
-
-  return h;
-}
diff --git a/src/math/factor-stats.h b/src/math/factor-stats.h
deleted file mode 100644 (file)
index 3c1c7f9..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef FACTOR_STATS
-#define FACTOR_STATS
-
-
-/* FIXME: These things should probably be amalgamated with the
-   group_statistics struct */
-
-#include <libpspp/hash.h>
-#include <data/value.h>
-#include <string.h>
-#include <gsl/gsl_histogram.h>
-#include "percentiles.h"
-
-
-struct moments1;
-
-struct metrics
-{
-  double n;
-
-  double n_missing;
-
-  double min;
-
-  double max;
-
-  double mean;
-
-  double se_mean;
-
-  double var;
-
-  double stddev;
-
-  struct moments1 *moments;
-
-  gsl_histogram *histogram;
-
-  double skewness;
-  double kurtosis;
-
-  double trimmed_mean;
-
-  /* A hash of data for this factor. */
-  struct hsh_table *ordered_data;
-
-  /* A Pointer to this hash table AFTER it has been SORTED and crunched */
-  struct weighted_value **wvp;
-
-  /* The number of values in the above array
-     (if all the weights are 1, then this will
-     be the same as n) */
-  int n_data;
-
-  /* Percentile stuff */
-
-  /* A hash of struct percentiles */
-  struct hsh_table *ptile_hash;
-
-  /* Algorithm to be used for calculating percentiles */
-  enum pc_alg ptile_alg;
-
-  /* Tukey's Hinges */
-  double hinge[3];
-
-};
-
-
-struct metrics * metrics_create(void);
-
-void metrics_precalc(struct metrics *m);
-
-void metrics_calc(struct metrics *m, const union value *f, double weight,
-                 int case_no);
-
-void metrics_postcalc(struct metrics *m);
-
-void  metrics_destroy(struct metrics *m);
-
-
-
-/* Linked list of case nos */
-struct case_node
-{
-  int num;
-  struct case_node *next;
-};
-
-struct weighted_value
-{
-  union value v;
-
-  /* The weight */
-  double w;
-
-  /* The cumulative weight */
-  double cc;
-
-  /* The rank */
-  double rank;
-
-  /* Linked list of cases nos which have this value */
-  struct case_node *case_nos;
-
-};
-
-
-struct weighted_value *weighted_value_create(void);
-
-void weighted_value_free(struct weighted_value *wv);
-
-
-
-struct factor_statistics {
-
-  /* The values of the independent variables */
-  union value *id[2];
-
-  /* The an array stats for this factor, one for each dependent var */
-  struct metrics *m;
-
-  /* The number of dependent variables */
-  int n_var;
-};
-
-
-/* Create a factor statistics object with for N dependent vars
-   and ID as the value of the independent variable */
-struct factor_statistics * create_factor_statistics (int n,
-                         union value *id0,
-                         union value *id1);
-
-
-void factor_statistics_free(struct factor_statistics *f);
-
-
-/* Compare f0 and f1.
-   width is the width of the independent variable */
-int
-factor_statistics_compare(const struct factor_statistics *f0,
-                         const struct factor_statistics *f1, int width);
-
-unsigned int
-factor_statistics_hash(const struct factor_statistics *f, int width);
-
-#endif
index 29c5ab23db4b7bde28a7c7f2657dba7ede4e8533..6101c350e483457f372a6f6ca7ae3d1aec16a385 100644 (file)
 /* Return -1 if the id of a is less than b; +1 if greater than and
    0 if equal */
 int
-compare_group (const struct group_statistics *a,
-                const struct group_statistics *b,
-                int width)
+compare_group (const void *a_,
+                const void *b_,
+                const void *var)
 {
-  return compare_values(&a->id, &b->id, width);
+  const struct group_statistics *a = a_;
+  const struct group_statistics *b = b_;
+  return compare_values(&a->id, &b->id, var);
 }
 
 
 
-unsigned
-hash_group (const struct group_statistics *g, int width)
+unsigned int
+hash_group (const void *g_, const void *var)
 {
   unsigned id_hash;
+  const struct group_statistics *g = g_;;
 
-  id_hash = hash_value(&g->id, width);
+  id_hash = hash_value(&g->id, var);
 
   return id_hash;
 }
index bc82c8ab8234424853cf2672764277145a22d90b..c5470b2578f2a1948e66a1ca6e6ae220d1616ecb 100644 (file)
 #ifndef GROUP_H
 #define GROUP_H
 
-
 #include <data/value.h>
 
-
 /* Statistics for grouped data */
 struct group_statistics
   {
@@ -67,17 +65,17 @@ struct group_statistics
   };
 
 
-
+struct variable ;
 
 /* These funcs are useful for hash tables */
 
 /* Return -1 if the id of a is less than b; +1 if greater than and
    0 if equal */
-int  compare_group (const struct group_statistics *a,
-                   const struct group_statistics *b,
-                   int width);
+int  compare_group (const void *a,
+                   const void *b,
+                   const void *var);
 
-unsigned hash_group (const struct group_statistics *g, int width);
+unsigned int hash_group (const void *g, const void *var);
 
 void  free_group (struct group_statistics *v, void *aux);
 
index 7b875d4089ad211d39a636f34fa8e8108a2098de..67079398d169ec58737c6f3b94a7d243b9fc8516 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2008 Free Software Foundation, Inc.
 
    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
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
-#include <math.h>
-#include <gsl/gsl_histogram.h>
-#include <assert.h>
 #include "histogram.h"
+
+#include <gl/xalloc.h>
+#include <libpspp/assertion.h>
+
+#include <gsl/gsl_histogram.h>
 #include "chart-geometry.h"
+#include <math.h>
+
+
+void
+histogram_add (struct histogram *h, double y, double c)
+{
+  ((struct statistic *)h)->accumulate ((struct statistic *) h, NULL, c, 0, y);
+}
+
 
 
-gsl_histogram *
-histogram_create(double bins, double x_min, double x_max)
+static void
+acc (struct statistic *s, const struct ccase *cx UNUSED, double c, double cc UNUSED, double y)
 {
-  int n;
-  double bin_width ;
-  double bin_width_2 ;
+  struct histogram *hist = (struct histogram *) s;
+
+  gsl_histogram_accumulate (hist->gsl_hist, y, c);
+}
+
+
+static void
+destroy (struct statistic *s)
+{
+  struct histogram *h = (struct histogram *) s;
+  gsl_histogram_free (h->gsl_hist);
+  free (s);
+}
+
+
+struct statistic *
+histogram_create (int bins, double min, double max)
+{
+  struct histogram *h = xmalloc (sizeof *h);
+  struct statistic *stat = (struct statistic *) h;
   double upper_limit, lower_limit;
 
-  gsl_histogram *hist = gsl_histogram_alloc(bins);
+  double bin_width = chart_rounded_tick ((max - min) / (double) bins);
+  double bin_width_2 = bin_width / 2.0;
 
-  bin_width = chart_rounded_tick((x_max - x_min)/ bins);
-  bin_width_2 = bin_width / 2.0;
+  int n =  ceil (max / (bin_width_2) ) ;
+
+  assert (max > min);
 
-  n =  ceil( x_max / (bin_width_2) ) ;
   if ( ! (n % 2 ) ) n++;
   upper_limit = n * bin_width_2;
 
-  n =  floor( x_min / (bin_width_2) ) ;
+  n =  floor (min / (bin_width_2) ) ;
   if ( ! (n % 2 ) ) n--;
   lower_limit = n * bin_width_2;
 
-  gsl_histogram_set_ranges_uniform(hist, lower_limit, upper_limit);
+  h->gsl_hist = gsl_histogram_alloc (bins);
+  gsl_histogram_set_ranges_uniform (h->gsl_hist, lower_limit, upper_limit);
+
+  stat->accumulate = acc;
+  stat->destroy = destroy;
 
-  return hist;
+  return stat;
 }
 
index e4c7819f331756d97bec69d6e56e580a71ee3f0b..b2b204ee808098c2bf378ef99e8419c6d4223988 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2008 Free Software Foundation, Inc.
 
    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
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-#ifndef HISTOGRAM_H
-#define HISTOGRAM_H
+#ifndef __NEW_HISTOGRAM_H__
+#define __NEW_HISTOGRAM_H__
+
+#include <stddef.h>
+
+#include "statistic.h"
 
 #include <gsl/gsl_histogram.h>
 
-gsl_histogram * histogram_create(double bins, double x_min, double x_max);
+
+struct histogram
+{
+  struct statistic parent;
+  gsl_histogram *gsl_hist;
+};
+
+struct statistic * histogram_create (int bins, double max, double min);
+
+void histogram_add (struct histogram *h, double y, double c);
+
 
 #endif
index 8ac19a6b91945366c5d1cb0b56ec395df69907aa..48db78a82c5af8340a017f2e97da25dba1c0c6c5 100644 (file)
@@ -24,6 +24,7 @@
 #include <math/coefficient.h>
 #include <math/linreg.h>
 #include <math/coefficient.h>
+#include <math/covariance-matrix.h>
 #include <math/design-matrix.h>
 #include <src/data/category.h>
 #include <src/data/variable.h>
@@ -137,12 +138,15 @@ pspp_linreg_get_vars (const void *c_, const struct variable **v)
   independent variables.
  */
 pspp_linreg_cache *
-pspp_linreg_cache_alloc (size_t n, size_t p)
+pspp_linreg_cache_alloc (const struct variable *depvar, const struct variable **indep_vars,
+                        size_t n, size_t p)
 {
+  size_t i;
   pspp_linreg_cache *c;
 
   c = (pspp_linreg_cache *) malloc (sizeof (pspp_linreg_cache));
-  c->depvar = NULL;
+  c->depvar = depvar;
+  c->indep_vars = indep_vars;
   c->indep_means = gsl_vector_alloc (p);
   c->indep_std = gsl_vector_alloc (p);
   c->ssx = gsl_vector_alloc (p);       /* Sums of squares for the
@@ -151,9 +155,22 @@ pspp_linreg_cache_alloc (size_t n, size_t p)
   c->ss_indeps = gsl_vector_alloc (p); /* Sums of squares for the
                                           model parameters.
                                         */
-  c->cov = gsl_matrix_alloc (p + 1, p + 1);    /* Covariance matrix. */
   c->n_obs = n;
   c->n_indeps = p;
+  c->n_coeffs = 0;
+  for (i = 0; i < p; i++)
+    {
+      if (var_is_numeric (indep_vars[i]))
+       {
+         c->n_coeffs++;
+       }
+      else
+       {
+         c->n_coeffs += cat_get_n_categories (indep_vars[i]) - 1;
+       }
+    }
+
+  c->cov = gsl_matrix_alloc (c->n_coeffs + 1, c->n_coeffs + 1);
   /*
      Default settings.
    */
@@ -192,7 +209,93 @@ pspp_linreg_cache_free (void *m)
     }
   return true;
 }
+static void
+cache_init (pspp_linreg_cache *cache)
+{
+  assert (cache != NULL);
+  cache->dft = cache->n_obs - 1;
+  cache->dfm = cache->n_indeps;
+  cache->dfe = cache->dft - cache->dfm;
+  cache->intercept = 0.0;
+}
+
+static void
+post_sweep_computations (pspp_linreg_cache *cache, const struct design_matrix *dm,
+                        gsl_matrix *sw)
+{
+  gsl_matrix *xm;
+  gsl_matrix_view xtx;
+  gsl_matrix_view xmxtx;
+  double m;
+  double tmp;
+  size_t i;
+  size_t j;
+  int rc;
+  
+  assert (sw != NULL);
+  assert (cache != NULL);
 
+  cache->sse = gsl_matrix_get (sw, cache->n_indeps, cache->n_indeps);
+  cache->mse = cache->sse / cache->dfe;
+  /*
+    Get the intercept.
+  */
+  m = cache->depvar_mean;
+  for (i = 0; i < cache->n_indeps; i++)
+    {
+      tmp = gsl_matrix_get (sw, i, cache->n_indeps);
+      cache->coeff[i]->estimate = tmp;
+      m -= tmp * pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i));
+    }
+  /*
+    Get the covariance matrix of the parameter estimates.
+    Only the upper triangle is necessary.
+  */
+  
+  /*
+    The loops below do not compute the entries related
+    to the estimated intercept.
+  */
+  for (i = 0; i < cache->n_indeps; i++)
+    for (j = i; j < cache->n_indeps; j++)
+      {
+       tmp = -1.0 * cache->mse * gsl_matrix_get (sw, i, j);
+       gsl_matrix_set (cache->cov, i + 1, j + 1, tmp);
+      }
+  /*
+    Get the covariances related to the intercept.
+  */
+  xtx = gsl_matrix_submatrix (sw, 0, 0, cache->n_indeps, cache->n_indeps);
+  xmxtx = gsl_matrix_submatrix (cache->cov, 0, 1, 1, cache->n_indeps);
+  xm = gsl_matrix_calloc (1, cache->n_indeps);
+  for (i = 0; i < xm->size2; i++)
+    {
+      gsl_matrix_set (xm, 0, i, 
+                     pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i)));
+    }
+  rc = gsl_blas_dsymm (CblasRight, CblasUpper, cache->mse,
+                      &xtx.matrix, xm, 0.0, &xmxtx.matrix);
+  gsl_matrix_free (xm);
+  if (rc == GSL_SUCCESS)
+    {
+      tmp = cache->mse / cache->n_obs;
+      for (i = 1; i < 1 + cache->n_indeps; i++)
+       {
+         tmp -= gsl_matrix_get (cache->cov, 0, i)
+           * pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i - 1));
+       }
+      gsl_matrix_set (cache->cov, 0, 0, tmp);
+      
+      cache->intercept = m;
+    }
+  else
+    {
+      fprintf (stderr, "%s:%d:gsl_blas_dsymm: %s\n",
+              __FILE__, __LINE__, gsl_strerror (rc));
+      exit (rc);
+    }
+}  
+  
 /*
   Fit the linear model via least squares. All pointers passed to pspp_linreg
   are assumed to be allocated to the correct size and initialized to the
@@ -205,8 +308,6 @@ pspp_linreg (const gsl_vector * Y, const struct design_matrix *dm,
   int rc;
   gsl_matrix *design = NULL;
   gsl_matrix_view xtx;
-  gsl_matrix *xm;
-  gsl_matrix_view xmxtx;
   gsl_vector_view xty;
   gsl_vector_view xi;
   gsl_vector_view xj;
@@ -234,13 +335,8 @@ pspp_linreg (const gsl_vector * Y, const struct design_matrix *dm,
       cache->depvar_std = s;
       cache->sst = ss;
     }
-
-  cache->dft = cache->n_obs - 1;
-  cache->dfm = cache->n_indeps;
-  cache->dfe = cache->dft - cache->dfm;
+  cache_init (cache);
   cache->n_coeffs = dm->m->size2;
-  cache->intercept = 0.0;
-  
   for (i = 0; i < dm->m->size2; i++)
     {
       if (opts->get_indep_mean_std[i])
@@ -326,65 +422,7 @@ pspp_linreg (const gsl_vector * Y, const struct design_matrix *dm,
          Sweep on the matrix sw, which contains XtX, XtY and YtY.
        */
       reg_sweep (sw);
-      cache->sse = gsl_matrix_get (sw, cache->n_indeps, cache->n_indeps);
-      cache->mse = cache->sse / cache->dfe;
-      /*
-         Get the intercept.
-       */
-      m = cache->depvar_mean;
-      for (i = 0; i < cache->n_indeps; i++)
-       {
-         tmp = gsl_matrix_get (sw, i, cache->n_indeps);
-         cache->coeff[i]->estimate = tmp;
-         m -= tmp * pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i));
-       }
-      /*
-         Get the covariance matrix of the parameter estimates.
-         Only the upper triangle is necessary.
-       */
-
-      /*
-         The loops below do not compute the entries related
-         to the estimated intercept.
-       */
-      for (i = 0; i < cache->n_indeps; i++)
-       for (j = i; j < cache->n_indeps; j++)
-         {
-           tmp = -1.0 * cache->mse * gsl_matrix_get (sw, i, j);
-           gsl_matrix_set (cache->cov, i + 1, j + 1, tmp);
-         }
-      /*
-         Get the covariances related to the intercept.
-       */
-      xtx = gsl_matrix_submatrix (sw, 0, 0, cache->n_indeps, cache->n_indeps);
-      xmxtx = gsl_matrix_submatrix (cache->cov, 0, 1, 1, cache->n_indeps);
-      xm = gsl_matrix_calloc (1, cache->n_indeps);
-      for (i = 0; i < xm->size2; i++)
-       {
-         gsl_matrix_set (xm, 0, i, 
-                         pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i)));
-       }
-      rc = gsl_blas_dsymm (CblasRight, CblasUpper, cache->mse,
-                          &xtx.matrix, xm, 0.0, &xmxtx.matrix);
-      gsl_matrix_free (xm);
-      if (rc == GSL_SUCCESS)
-       {
-         tmp = cache->mse / cache->n_obs;
-         for (i = 1; i < 1 + cache->n_indeps; i++)
-           {
-             tmp -= gsl_matrix_get (cache->cov, 0, i)
-               * pspp_linreg_get_indep_variable_mean (cache, design_matrix_col_to_var (dm, i - 1));
-           }
-         gsl_matrix_set (cache->cov, 0, 0, tmp);
-
-         cache->intercept = m;
-       }
-      else
-       {
-         fprintf (stderr, "%s:%d:gsl_blas_dsymm: %s\n",
-                  __FILE__, __LINE__, gsl_strerror (rc));
-         exit (rc);
-       }
+      post_sweep_computations (cache, dm, sw);
       gsl_matrix_free (sw);
     }
   else if (cache->method == PSPP_LINREG_CONDITIONAL_INVERSE)
@@ -546,7 +584,7 @@ pspp_linreg_residual (const struct variable **predictors,
     }
   pred = pspp_linreg_predict (predictors, vals, c, n_vals);
 
-  result = gsl_isnan (pred) ? GSL_NAN : (obs->f - pred);
+  result = isnan (pred) ? GSL_NAN : (obs->f - pred);
   return result;
 }
 
@@ -554,7 +592,7 @@ pspp_linreg_residual (const struct variable **predictors,
   Which coefficient is associated with V? The VAL argument is relevant
   only to categorical variables.
  */
-const struct pspp_coeff *
+struct pspp_coeff *
 pspp_linreg_get_coeff (const pspp_linreg_cache * c,
                       const struct variable *v, const union value *val)
 {
@@ -617,3 +655,83 @@ void pspp_linreg_set_indep_variable_mean (pspp_linreg_cache *c, const struct var
       pspp_coeff_set_mean (coef, m);
     }
 }
+
+/*
+  Make sure the dependent variable is at the last column, and that
+  only variables in the model are in the covariance matrix. 
+ */
+static struct design_matrix *
+rearrange_covariance_matrix (const struct design_matrix *cov, pspp_linreg_cache *c)
+{
+  const struct variable **model_vars;
+  struct design_matrix *result;
+  size_t *permutation;
+  size_t i;
+  size_t j;
+  size_t k;
+
+  assert (cov != NULL);
+  assert (c != NULL);
+  assert (cov->m->size1 > 0);
+  assert (cov->m->size2 == cov->m->size1);
+  permutation = xnmalloc (1 + c->n_indeps, sizeof (*permutation));
+  model_vars = xnmalloc (1 + c->n_indeps, sizeof (*model_vars));
+
+  /*
+    Put the model variables in the right order in MODEL_VARS.
+   */
+  for (i = 0; i < c->n_indeps; i++)
+    {
+      model_vars[i] = c->indep_vars[i];
+    }
+  model_vars[i] = c->depvar;
+  result = covariance_matrix_create (1 + c->n_indeps, model_vars);
+  for (j = 0; j < cov->m->size2; j++)
+    {
+      k = 0;
+      while (k < result->m->size2)
+       {
+         if (design_matrix_col_to_var (cov, j) == design_matrix_col_to_var (result, k)) 
+           {
+             permutation[k] = j;
+           }
+         k++;
+       }
+    }
+  for (i = 0; i < result->m->size1; i++)
+    for (j = 0; j < result->m->size2; j++)
+      {
+       gsl_matrix_set (result->m, i, j, gsl_matrix_get (cov->m, permutation[i], permutation[j]));
+      }
+  free (permutation);
+  free (model_vars);
+  return result;
+}
+/*
+  Estimate the model parameters from the covariance matrix only. This
+  method uses less memory than PSPP_LINREG, which requires the entire
+  data set to be stored in memory.
+
+  The function assumes FULL_COV may contain columns corresponding to
+  variables that are not in the model. It fixes this in
+  REARRANG_COVARIANCE_MATRIX. This allows the caller to compute a
+  large covariance matrix once before, then pass it to this without
+  having to alter it. The problem is that this means the caller must
+  set CACHE->N_COEFFS.
+*/
+void
+pspp_linreg_with_cov (const struct design_matrix *full_cov, 
+                     pspp_linreg_cache * cache)
+{
+  struct design_matrix *cov;
+
+  assert (full_cov != NULL);
+  assert (cache != NULL);
+
+  cov = rearrange_covariance_matrix (full_cov, cache);
+  cache_init (cache);
+  reg_sweep (cov->m);
+  post_sweep_computations (cache, cov, cov->m);  
+  covariance_matrix_destroy (cov);
+}
+
index ff37a84fe815931962aaa9ff46add55e0a394353..bab3205f04c2a5857de1e237d372903871e35567 100644 (file)
@@ -96,10 +96,10 @@ struct pspp_linreg_cache_struct
                                   coefficient here. */
 
   /*
-     The variable struct is ignored during estimation. It is here so
-     the calling procedure can find the variable used in the model.
+    Pointers to the variables.
    */
   const struct variable *depvar;
+  const struct variable **indep_vars;
 
   gsl_vector *residuals;
   struct pspp_coeff **coeff;
@@ -176,7 +176,8 @@ typedef struct pspp_linreg_cache_struct pspp_linreg_cache;
   to it. n is the number of cases, p is the number of
   independent variables.
  */
-pspp_linreg_cache *pspp_linreg_cache_alloc (size_t n, size_t p);
+pspp_linreg_cache *pspp_linreg_cache_alloc (const struct variable *, const struct variable **, 
+                                           size_t, size_t);
 
 bool pspp_linreg_cache_free (void *);
 
@@ -200,7 +201,7 @@ pspp_linreg_residual (const struct variable **, const union value **,
  */
 int pspp_linreg_get_vars (const void *, const struct variable **);
 
-const struct pspp_coeff *pspp_linreg_get_coeff (const pspp_linreg_cache
+struct pspp_coeff *pspp_linreg_get_coeff (const pspp_linreg_cache
                                                       *,
                                                       const struct variable
                                                       *,
@@ -215,4 +216,9 @@ void pspp_linreg_set_indep_variable_sd (pspp_linreg_cache *, const struct variab
  */
 double pspp_linreg_get_indep_variable_mean (pspp_linreg_cache *, const struct variable *);
 void pspp_linreg_set_indep_variable_mean (pspp_linreg_cache *, const struct variable *, double);
+
+/*
+  Regression using only the covariance matrix.
+ */
+void pspp_linreg_with_cov (const struct design_matrix *, pspp_linreg_cache *);
 #endif
index d56a78c3ed4c08601e89644b2d754d5cc0ca5eb3..4fc7c8dcf21433a7c23692c275a0ed398c850789 100644 (file)
@@ -44,16 +44,18 @@ struct merge
     struct case_ordering *ordering;
     struct merge_input inputs[MAX_MERGE_ORDER];
     size_t input_cnt;
+    size_t value_cnt;
   };
 
 static void do_merge (struct merge *m);
 
 struct merge *
-merge_create (const struct case_ordering *ordering)
+merge_create (const struct case_ordering *ordering, size_t value_cnt)
 {
   struct merge *m = xmalloc (sizeof *m);
   m->ordering = case_ordering_clone (ordering);
   m->input_cnt = 0;
+  m->value_cnt = value_cnt;
   return m;
 }
 
@@ -95,8 +97,7 @@ merge_make_reader (struct merge *m)
     }
   else if (m->input_cnt == 0)
     {
-      size_t value_cnt = case_ordering_get_value_cnt (m->ordering);
-      struct casewriter *writer = mem_writer_create (value_cnt);
+      struct casewriter *writer = mem_writer_create (m->value_cnt);
       r = casewriter_make_reader (writer);
     }
   else
@@ -129,7 +130,7 @@ do_merge (struct merge *m)
 
   assert (m->input_cnt > 1);
 
-  w = tmpfile_writer_create (case_ordering_get_value_cnt (m->ordering));
+  w = tmpfile_writer_create (m->value_cnt);
   for (i = 0; i < m->input_cnt; i++)
     taint_propagate (casereader_get_taint (m->inputs[i].reader),
                      casewriter_get_taint (w));
index c9c9c486f1a65046a4b5dcaa2e43efa954962e4a..18322e84bf7f9c2a614a2f9d666412d0b467cfe5 100644 (file)
 #define MATH_MERGE_H 1
 
 #include <stdbool.h>
+#include <stddef.h>
 
 struct case_ordering;
 struct casereader;
 
-struct merge *merge_create (const struct case_ordering *);
+struct merge *merge_create (const struct case_ordering *, size_t);
 void merge_destroy (struct merge *);
 void merge_append (struct merge *, struct casereader *);
 struct casereader *merge_make_reader (struct merge *);
index 02208bca70d007d1bc9f61f07d518b9b985a621d..d129f6ab038b3eee06104e716b15fbcf432c61c5 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "moments.h"
 #include <assert.h>
-#include <gsl/gsl_math.h>
 #include <math.h>
 #include <stdlib.h>
 #include <libpspp/misc.h>
@@ -56,7 +55,7 @@ calc_moments (enum moment max_moment,
             {
               double s3 = s2 * sqrt (s2);
               double g1 = (w * d3) / ((w - 1.0) * (w - 2.0) * s3);
-              if (gsl_finite (g1))
+              if (isfinite (g1))
                 *skewness = g1;
             }
           if (max_moment >= MOMENT_KURTOSIS && kurtosis != NULL && w > 3.)
@@ -64,7 +63,7 @@ calc_moments (enum moment max_moment,
               double den = (w - 2.) * (w - 3.) * pow2 (s2);
               double g2 = (w * (w + 1) * d4 / (w - 1.) / den
                            - 3. * pow2 (d2) / den);
-              if (gsl_finite (g2))
+              if (isfinite (g2))
                 *kurtosis = g2;
             }
         }
diff --git a/src/math/np.c b/src/math/np.c
new file mode 100644 (file)
index 0000000..e189b47
--- /dev/null
@@ -0,0 +1,94 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "np.h"
+#include <math/moments.h>
+#include <gl/xalloc.h>
+#include <stdlib.h>
+#include <math.h>
+#include <gsl/gsl_cdf.h>
+#include <libpspp/compiler.h>
+#include <data/case.h>
+#include <data/casewriter.h>
+
+static void
+destroy (struct statistic *stat)
+{
+  struct order_stats *os = (struct order_stats *) stat;
+  free (os);
+}
+
+
+static void
+acc (struct statistic *s, const struct ccase *cx UNUSED,
+     double c, double cc, double y)
+{
+  struct ccase cp;
+  struct np *np = (struct np *) s;
+  double rank = np->prev_cc + (c + 1) / 2.0;
+
+  double ns = gsl_cdf_ugaussian_Pinv (rank / ( np->n + 1 ));
+
+  double z = (y - np->mean) / np->stddev;
+
+  double dns = z - ns;
+
+  maximize (&np->ns_max, ns);
+  minimize (&np->ns_min, ns);
+
+  maximize (&np->dns_max, dns);
+  minimize (&np->dns_min, dns);
+
+  maximize (&np->y_max, y);
+  minimize (&np->y_min, y);
+
+  case_create (&cp, n_NP_IDX);
+
+  case_data_rw_idx (&cp, NP_IDX_Y)->f = y;
+  case_data_rw_idx (&cp, NP_IDX_NS)->f = ns;
+  case_data_rw_idx (&cp, NP_IDX_DNS)->f = dns;
+
+  casewriter_write (np->writer, &cp);
+
+  np->prev_cc = cc;
+}
+
+struct order_stats *
+np_create (const struct moments1 *m)
+{
+  double variance;
+  struct np *np = xzalloc (sizeof (*np));
+  struct statistic *stat = (struct statistic *) np;
+  struct order_stats *os = (struct order_stats *) np;
+
+  np->prev_cc = 0;
+
+  moments1_calculate (m, &np->n, &np->mean, &variance, NULL, NULL);
+
+  np->stddev = sqrt (variance);
+
+  np->y_min = np->ns_min = np->dns_min = DBL_MAX;
+  np->y_max = np->ns_max = np->dns_max = -DBL_MAX;
+
+  np->writer = autopaging_writer_create (n_NP_IDX);
+
+  os->k = 0;
+  stat->destroy = destroy;
+  stat->accumulate = acc;
+
+  return os;
+}
diff --git a/src/math/np.h b/src/math/np.h
new file mode 100644 (file)
index 0000000..7db51f7
--- /dev/null
@@ -0,0 +1,59 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __NP_H__
+#define __NP_H__
+
+#include "order-stats.h"
+
+struct moments1;
+struct casewriter;
+
+enum
+  {
+    NP_IDX_Y = 0,
+    NP_IDX_NS,
+    NP_IDX_DNS,
+    n_NP_IDX
+  };
+
+struct np
+{
+  struct order_stats parent;
+
+  double n;
+  double mean;
+  double stddev;
+
+
+  double prev_cc;
+
+  double ns_min;
+  double ns_max;
+
+  double dns_min;
+  double dns_max;
+
+  double y_min;
+  double y_max;
+
+  struct casewriter *writer;
+};
+
+
+struct order_stats * np_create (const struct moments1 *);
+
+#endif
diff --git a/src/math/order-stats.c b/src/math/order-stats.c
new file mode 100644 (file)
index 0000000..ca4160f
--- /dev/null
@@ -0,0 +1,159 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "order-stats.h"
+#include <libpspp/assertion.h>
+#include <data/val-type.h>
+#include <gl/xalloc.h>
+#include <data/variable.h>
+#include <data/casereader.h>
+#include <string.h>
+
+#if 0
+
+#include <stdio.h>
+
+static void
+order_stats_dump_k1 (const struct order_stats *os)
+{
+  struct k *k = &os->k[0];
+  printf ("K1: tc %g; c %g cc %g ccp %g\n",
+         k->tc, k->c, k->cc, k->cc_p1);
+
+}
+
+static void
+order_stats_dump_k2 (const struct order_stats *os)
+{
+  struct k *k = &os->k[1];
+  printf ("K2: tc %g; c %g cc %g ccp %g\n",
+         k->tc, k->c, k->cc, k->cc_p1);
+}
+
+
+void
+order_stats_dump (const struct order_stats *os)
+{
+  order_stats_dump_k1 (os);
+  order_stats_dump_k2 (os);
+}
+
+#endif
+
+static void
+update_k_lower (struct k *kk,
+               double y_i, double c_i, double cc_i)
+{
+  if ( cc_i <= kk->tc )
+    {
+      kk->cc = cc_i;
+      kk->c = c_i;
+      kk->y = y_i;
+    }
+}
+
+
+static void
+update_k_upper (struct k *kk,
+               double y_i, double c_i, double cc_i)
+{
+  if ( cc_i > kk->tc && kk->c_p1 == 0)
+    {
+      kk->cc_p1 = cc_i;
+      kk->c_p1 = c_i;
+      kk->y_p1 = y_i;
+    }
+}
+
+
+static void
+update_k_values (const struct ccase *cx, double y_i, double c_i, double cc_i,
+                struct order_stats **os, size_t n_os)
+{
+  int j;
+
+  for (j = 0 ; j < n_os ; ++j)
+    {
+      int k;
+      struct order_stats *tos = os[j];
+      struct statistic  *stat = (struct statistic *) tos;
+      for (k = 0 ; k < tos->n_k; ++k)
+       {
+         struct k *myk = &tos->k[k];
+         update_k_lower (myk, y_i, c_i, cc_i);
+         update_k_upper (myk, y_i, c_i, cc_i);
+       }
+
+      if ( stat->accumulate )
+       stat->accumulate (stat, cx, c_i, cc_i, y_i);
+
+      tos->cc = cc_i;
+    }
+}
+
+
+void
+order_stats_accumulate (struct order_stats **os, size_t nos,
+                       struct casereader *reader,
+                       const struct variable *wv,
+                       const struct variable *var,
+                       enum mv_class exclude)
+{
+  struct ccase cx;
+  struct ccase prev_cx;
+  double prev_value = -DBL_MAX;
+
+  double cc_i = 0;
+  double c_i = 0;
+
+  case_nullify (&prev_cx);
+
+  for (; casereader_read (reader, &cx); case_destroy (&cx))
+    {
+      const double weight = wv ? case_data (&cx, wv)->f : 1.0;
+      const double this_value = case_data (&cx, var)->f;
+
+      /* The casereader MUST be sorted */
+      assert (this_value >= prev_value);
+
+      if ( var_is_value_missing (var, case_data (&cx, var), exclude))
+       continue;
+
+      case_destroy (&prev_cx);
+
+      if ( prev_value == -DBL_MAX || prev_value == this_value)
+       c_i += weight;
+
+      if ( prev_value > -DBL_MAX && this_value > prev_value)
+       {
+         update_k_values (&prev_cx, prev_value, c_i, cc_i, os, nos);
+         c_i = weight;
+       }
+
+      cc_i += weight;
+      prev_value = this_value;
+      case_clone (&prev_cx, &cx);
+    }
+
+  update_k_values (&prev_cx, prev_value, c_i, cc_i, os, nos);
+  case_destroy (&prev_cx);
+
+  casereader_destroy (reader);
+}
+
+
+
diff --git a/src/math/order-stats.h b/src/math/order-stats.h
new file mode 100644 (file)
index 0000000..07da284
--- /dev/null
@@ -0,0 +1,61 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2004, 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __ORDER_STATS_H__
+#define __ORDER_STATS_H__
+
+#include <stddef.h>
+#include <data/missing-values.h>
+#include <math/statistic.h>
+
+struct casereader;
+struct variable;
+
+/*
+  cc <= tc < cc_p1
+*/
+struct k
+{
+  double tc;
+  double cc;
+  double cc_p1;
+  double c;
+  double c_p1;
+  double y;
+  double y_p1;
+};
+
+
+struct order_stats
+{
+  struct statistic parent;
+  int n_k;
+  struct k *k;
+
+  double cc;
+};
+
+enum mv_class;
+
+void order_stats_dump (const struct order_stats *os);
+
+void order_stats_accumulate (struct order_stats **ptl, size_t nos,
+                            struct casereader *reader,
+                            const struct variable *wv,
+                            const struct variable *var,
+                            enum mv_class exclude);
+
+#endif
index aa7eead6c03980d9b1dc2bafca96777341678351..bf99de163ffbaafe2af8711685e9a640a0256784 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2008 Free Software Foundation, Inc.
 
    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
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
-#include <assert.h>
-#include <data/val-type.h>
-#include <libpspp/compiler.h>
-#include "factor-stats.h"
 #include "percentiles.h"
-#include <libpspp/misc.h>
+#include <math/order-stats.h>
 
-#include "minmax.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-struct ptile_params
-{
-  double g1, g1_star;
-  double g2, g2_star;
-  int k1, k2;
-};
+#include <libpspp/assertion.h>
+#include <data/val-type.h>
+#include <gl/xalloc.h>
+#include <data/variable.h>
+#include <data/casereader.h>
 
 
 const char *const ptile_alg_desc[] = {
@@ -47,380 +41,151 @@ const char *const ptile_alg_desc[] = {
 
 
 
-
-/* Individual Percentile algorithms */
-
-/* Closest observation to tc1 */
-double ptile_round(const struct weighted_value **wv,
-                  const struct ptile_params *par);
-
-
-/* Weighted average at y_tc2 */
-double ptile_haverage(const struct weighted_value **wv,
-                  const struct ptile_params *par);
-
-
-/* Weighted average at y_tc1 */
-double ptile_waverage(const struct weighted_value **wv,
-                  const struct ptile_params *par);
-
-
-/* Empirical distribution function */
-double ptile_empirical(const struct weighted_value **wv,
-                  const struct ptile_params *par);
-
-
-/* Empirical distribution function with averaging*/
-double ptile_aempirical(const struct weighted_value **wv,
-                  const struct ptile_params *par);
-
-
-
-
-/* Closest observation to tc1 */
 double
-ptile_round(const struct weighted_value **wv,
-           const struct ptile_params *par)
+percentile_calculate (const struct percentile *ptl, enum pc_alg alg)
 {
-  double x;
-  double a=0;
+  struct percentile *mutable = (struct percentile *) ptl;
+  const struct order_stats *os = &ptl->parent;
 
-  if ( par->k1 >= 0 )
-    a = wv[par->k1]->v.f;
+  assert (os->cc == ptl->w);
 
-  if ( wv[par->k1 + 1]->w >= 1 )
-    {
-      if ( par->g1_star < 0.5 )
-       x = a;
-      else
-       x = wv[par->k1 + 1]->v.f;
-    }
-  else
-    {
-      if ( par->g1 < 0.5 )
-       x = a;
-      else
-       x = wv[par->k1 + 1]->v.f;
-
-    }
-
-  return x;
-}
+  if ( ptl->g1 == SYSMIS)
+    mutable->g1 = (os->k[0].tc - os->k[0].cc) / os->k[0].c_p1;
 
-/* Weighted average at y_tc2 */
-double
-ptile_haverage(const struct weighted_value **wv,
-              const struct ptile_params *par)
-{
-
-  double a=0;
+  if ( ptl->g1_star == SYSMIS)
+    mutable->g1_star = os->k[0].tc - os->k[0].cc;
 
-  if ( par->g2_star >= 1.0 )
-      return wv[par->k2 + 1]->v.f ;
-
-  /* Special case  for k2 + 1 >= n_data
-     (actually it's not a special case, but just avoids indexing errors )
-   */
-  if ( par->g2_star == 0 )
+  if ( ptl->g2 == SYSMIS)
     {
-      assert(par->g2 == 0 );
-      return wv[par->k2]->v.f;
-    }
-
-  /* Ditto for k2 < 0 */
-  if ( par->k2 >= 0 )
-    {
-      a = wv[par->k2]->v.f;
+      if ( os->k[1].c == 0 )
+       mutable->g2 = os->k[1].tc / os->k[1].c_p1;
+      else if ( os->k[1].c_p1 == 0 )
+       mutable->g2 = 0;
+      else
+       mutable->g2 = (os->k[1].tc - os->k[1].cc) / os->k[1].c_p1;
     }
 
-  if ( wv[par->k2 + 1]->w >= 1.0 )
-    return ( (1 - par->g2_star) *  a   +
-            par->g2_star * wv[par->k2 + 1]->v.f);
-  else
-    return ( (1 - par->g2) * a +
-            par->g2 * wv[par->k2 + 1]->v.f);
-
-}
-
-
-
-/* Weighted average at y_tc1 */
-double
-ptile_waverage(const struct weighted_value **wv,
-              const struct ptile_params *par)
-{
-  double a=0;
-
-  if ( par->g1_star >= 1.0 )
-      return wv[par->k1 + 1]->v.f ;
-
-  if ( par->k1 >= 0 )
+  if ( ptl->g2_star == SYSMIS)
     {
-      a = wv[par->k1]->v.f;
+      if ( os->k[1].c == 0 )
+       mutable->g2_star = os->k[1].tc;
+      else if ( os->k[1].c_p1 == 0 )
+       mutable->g2_star = 0;
+      else
+       mutable->g2_star = os->k[1].tc - os->k[1].cc;
     }
 
-  if ( wv[par->k1 + 1]->w >= 1.0 )
-    return ( (1 - par->g1_star) * a +
-            par->g1_star * wv[par->k1 + 1]->v.f);
-  else
-    return ( (1 - par->g1) * a +
-            par->g1 * wv[par->k1 + 1]->v.f);
-}
-
-
-/* Empirical distribution function */
-double
-ptile_empirical(const struct weighted_value **wv,
-              const struct ptile_params *par)
-{
-  if ( par->g1_star > 0 )
-    return wv[par->k1 + 1]->v.f;
-  else
-    return wv[par->k1]->v.f;
-}
-
-
-
-/* Empirical distribution function with averageing */
-double
-ptile_aempirical(const struct weighted_value **wv,
-              const struct ptile_params *par)
-{
-  if ( par->g1_star > 0 )
-    return wv[par->k1 + 1]->v.f;
-  else
-    return (wv[par->k1]->v.f + wv[par->k1 + 1]->v.f ) / 2.0 ;
-}
-
-
-
-/* Compute the percentile p */
-double ptile(double p,
-            const struct weighted_value **wv,
-            int n_data,
-            double w,
-            enum pc_alg algorithm);
-
-
-
-double
-ptile(double p,
-      const struct weighted_value **wv,
-      int n_data,
-      double w,
-      enum pc_alg algorithm)
-{
-  int i;
-  double tc1, tc2;
-  double result;
-
-  struct ptile_params pp;
-
-  assert( p <= 1.0);
-
-  tc1 = w * p ;
-  tc2 = (w + 1) * p ;
-
-  pp.k1 = -1;
-  pp.k2 = -1;
-
-  for ( i = 0 ; i < n_data ; ++i )
+  switch (alg)
     {
-      if ( wv[i]->cc <= tc1 )
-       pp.k1 = i;
-
-      if ( wv[i]->cc <= tc2 )
-       pp.k2 = i;
+    case PC_WAVERAGE:
+      if ( ptl->g1_star >= 1.0)
+       return os->k[0].y_p1;
+      else
+       {
+         double a = ( os->k[0].y == SYSMIS ) ? 0 : os->k[0].y;
 
-    }
+         if (os->k[0].c_p1 >= 1.0)
+           return (1 - ptl->g1_star) * a + ptl->g1_star * os->k[0].y_p1;
+         else
+           return (1 - ptl->g1) * a + ptl->g1 * os->k[0].y_p1;
+       }
+      break;
 
+    case PC_ROUND:
+      {
+       double a = ( os->k[0].y == SYSMIS ) ? 0 : os->k[0].y;
 
-  if ( pp.k1 >= 0 )
-    {
-      pp.g1 = ( tc1 - wv[pp.k1]->cc ) / wv[pp.k1 + 1]->w;
-      pp.g1_star = tc1 -  wv[pp.k1]->cc ;
-    }
-  else
-    {
-      pp.g1 = tc1 / wv[pp.k1 + 1]->w;
-      pp.g1_star = tc1 ;
-    }
+       if (os->k[0].c_p1 >= 1.0)
+         return (ptl->g1_star < 0.5) ? a : os->k[0].y_p1;
+       else
+         return (ptl->g1 < 0.5) ? a : os->k[0].y_p1;
+      }
+      break;
 
+    case PC_EMPIRICAL:
+      if ( ptl->g1_star == 0 )
+       return os->k[0].y;
+      else
+       return os->k[0].y_p1;
+      break;
 
-  if ( pp.k2  + 1 >= n_data )
-    {
-      pp.g2 = 0 ;
-      pp.g2_star = 0;
-    }
-  else
-    {
-      if ( pp.k2 >= 0 )
+    case PC_HAVERAGE:
+      if ( ptl->g2_star >= 1.0)
        {
-         pp.g2 = ( tc2 - wv[pp.k2]->cc ) / wv[pp.k2 + 1]->w;
-         pp.g2_star = tc2 -  wv[pp.k2]->cc ;
+         return os->k[1].y_p1;
        }
       else
        {
-         pp.g2 = tc2 / wv[pp.k2 + 1]->w;
-         pp.g2_star = tc2 ;
+         double a = ( os->k[1].y == SYSMIS ) ? 0 : os->k[1].y;
+
+         if ( os->k[1].c_p1 >= 1.0)
+           {
+             if ( ptl->g2_star == 0)
+               return os->k[1].y;
+
+             return (1 - ptl->g2_star) * a + ptl->g2_star * os->k[1].y_p1;
+           }
+         else
+           {
+             return (1 - ptl->g2) * a + ptl->g2 * os->k[1].y_p1;
+           }
        }
-    }
 
-  switch ( algorithm )
-    {
-    case PC_HAVERAGE:
-      result = ptile_haverage(wv, &pp);
-      break;
-    case PC_WAVERAGE:
-      result = ptile_waverage(wv, &pp);
-      break;
-    case PC_ROUND:
-      result = ptile_round(wv, &pp);
-      break;
-    case PC_EMPIRICAL:
-      result = ptile_empirical(wv, &pp);
       break;
+
     case PC_AEMPIRICAL:
-      result = ptile_aempirical(wv, &pp);
+      if ( ptl->g1_star == 0 )
+       return (os->k[0].y + os->k[0].y_p1)/ 2.0;
+      else
+       return os->k[0].y_p1;
       break;
+
     default:
-      result = SYSMIS;
+      NOT_REACHED ();
+      break;
     }
 
-  return result;
+  NOT_REACHED ();
+
+  return SYSMIS;
 }
 
 
-/*
-   Calculate the values of the percentiles in pc_hash.
-   wv is  a sorted array of weighted values of the data set.
-*/
-void
-ptiles(struct hsh_table *pc_hash,
-       const struct weighted_value **wv,
-       int n_data,
-       double w,
-       enum pc_alg algorithm)
+static void
+destroy (struct statistic *stat)
 {
-  struct hsh_iterator hi;
-  struct percentile *p;
-
-  if ( !pc_hash )
-    return ;
-  for ( p = hsh_first(pc_hash, &hi);
-       p != 0 ;
-       p = hsh_next(pc_hash, &hi))
-    {
-      p->v = ptile(p->p/100.0 , wv, n_data, w, algorithm);
-    }
-
+  struct order_stats *os = (struct order_stats *) stat;
+  free (os->k);
+  free (os);
 }
 
 
-/* Calculate Tukey's Hinges */
-void
-tukey_hinges(const struct weighted_value **wv,
-            int n_data,
-            double w,
-            double hinge[3]
-            )
+struct order_stats *
+percentile_create (double p, double W)
 {
-  int i;
-  double c_star = DBL_MAX;
-  double d;
-  double l[3];
-  int h[3];
-  double a, a_star;
-
-  for ( i = 0 ; i < n_data ; ++i )
-    {
-      c_star = MIN(c_star, wv[i]->w);
-    }
-
-  if ( c_star > 1 ) c_star = 1;
-
-  d = floor((w/c_star + 3 ) / 2.0)/ 2.0;
-
-  l[0] = d*c_star;
-  l[1] = w/2.0 + c_star/2.0;
-  l[2] = w + c_star - d*c_star;
-
-  h[0]=-1;
-  h[1]=-1;
-  h[2]=-1;
-
-  for ( i = 0 ; i < n_data ; ++i )
-    {
-      if ( l[0] >= wv[i]->cc ) h[0] = i ;
-      if ( l[1] >= wv[i]->cc ) h[1] = i ;
-      if ( l[2] >= wv[i]->cc ) h[2] = i ;
-    }
-
-  for ( i = 0 ; i < 3 ; i++ )
-    {
-
-      if ( h[i] >= 0 )
-       a_star = l[i] - wv[h[i]]->cc ;
-      else
-       a_star = l[i];
-
-      if ( h[i] + 1 >= n_data )
-      {
-             assert( a_star < 1 ) ;
-             hinge[i] = (1 - a_star) * wv[h[i]]->v.f;
-             continue;
-      }
-      else
-      {
-             a = a_star / ( wv[h[i] + 1]->cc ) ;
-      }
-
-      if ( a_star >= 1.0 )
-       {
-         hinge[i] = wv[h[i] + 1]->v.f ;
-         continue;
-       }
-
-      if ( wv[h[i] + 1]->w >= 1)
-       {
-         hinge[i] = ( 1 - a_star) * wv[h[i]]->v.f
-           + a_star * wv[h[i] + 1]->v.f;
-
-         continue;
-       }
+  struct percentile *ptl = xzalloc (sizeof (*ptl));
+  struct order_stats *os = (struct order_stats *) ptl;
+  struct statistic *stat = (struct statistic *) ptl;
 
-      hinge[i] = (1 - a) * wv[h[i]]->v.f + a * wv[h[i] + 1]->v.f;
+  assert (p >= 0);
+  assert (p <= 1.0);
 
-    }
-
-  assert(hinge[0] <= hinge[1]);
-  assert(hinge[1] <= hinge[2]);
+  ptl->ptile = p;
+  ptl->w = W;
 
-}
+  os->n_k = 2;
+  os->k = xcalloc (sizeof (*os->k), 2);
+  os->k[0].tc = W * p;
+  os->k[1].tc = (W + 1.0) * p;
 
+  ptl->g1 = ptl->g1_star = SYSMIS;
+  ptl->g2 = ptl->g2_star = SYSMIS;
 
-int
-ptile_compare(const struct percentile *p1,
-                  const struct percentile *p2,
-                  void *aux UNUSED)
-{
-
-  int cmp;
+  os->k[1].y_p1 = os->k[1].y = SYSMIS;
+  os->k[0].y_p1 = os->k[0].y = SYSMIS;
 
-  if ( p1->p == p2->p)
-    cmp = 0 ;
-  else if (p1->p < p2->p)
-    cmp = -1 ;
-  else
-    cmp = +1;
+  stat->destroy = destroy;
 
-  return cmp;
+  return os;
 }
 
-unsigned
-ptile_hash(const struct percentile *p, void *aux UNUSED)
-{
-  return hsh_hash_double(p->p);
-}
-
-
index 9e0eb47a46f5275610a51239322c040870d48660..0dd09820945e1bafaee5a017ba3756cb4197783b 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2008 Free Software Foundation, Inc.
 
    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
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-#ifndef PERCENTILES_H
-#define PERCENTILES_H
+#ifndef __PERCENTILES_H__
+#define __PERCENTILES_H__
 
+#include <stddef.h>
 
-#include <libpspp/hash.h>
-
-struct weighted_value ;
+#include "order-stats.h"
 
 /* The algorithm used to calculate percentiles */
 enum pc_alg {
@@ -32,48 +31,33 @@ enum pc_alg {
   PC_AEMPIRICAL
 } ;
 
-
-
 extern  const char *const ptile_alg_desc[];
 
 
+struct percentile
+{
+  struct order_stats parent;
 
+  double ptile;
+  double w;
 
-struct percentile {
+  /* Mutable */
+  double g1;
+  double g1_star;
 
-  /* The break point of the percentile */
-  double p;
-
-  /* The value of the percentile */
-  double v;
+  double g2;
+  double g2_star;
 };
 
-
-/* Calculate the percentiles of the break points in pc_bp,
-   placing the values in pc_val.
-   wv is  a sorted array of weighted values of the data set.
+/* Create the Pth percentile.
+   W is the total sum of weights in the data set
 */
-void ptiles(struct hsh_table *pc_hash,
-           const struct weighted_value **wv,
-           int n_data,
-           double w,
-           enum pc_alg algorithm);
-
-
-/* Calculate Tukey's Hinges and the Whiskers for the box plot*/
-void tukey_hinges(const struct weighted_value **wv,
-                 int n_data,
-                 double w,
-                 double hinges[3]);
-
-
+struct order_stats *percentile_create (double p, double W);
 
-/* Hash utility functions */
-int ptile_compare(const struct percentile *p1,
-                  const struct percentile *p2,
-                  void *aux);
+/* Return the value of the percentile */
+double percentile_calculate (const struct percentile *ptl, enum pc_alg alg);
 
-unsigned ptile_hash(const struct percentile *p, void *aux);
+void percentile_dump (const struct percentile *ptl);
 
 
 #endif
index e03ef5744bfbd8acc0ec9479f96714ccfecc92e8..10b8a12cec59d76173a39a15532a53dbec62e306 100644 (file)
@@ -41,6 +41,7 @@ int max_buffers = INT_MAX;
 
 struct sort_writer
   {
+    size_t value_cnt;
     struct case_ordering *ordering;
     struct merge *merge;
     struct pqueue *pqueue;
@@ -52,7 +53,7 @@ struct sort_writer
 
 static struct casewriter_class sort_casewriter_class;
 
-static struct pqueue *pqueue_create (const struct case_ordering *);
+static struct pqueue *pqueue_create (const struct case_ordering *, size_t);
 static void pqueue_destroy (struct pqueue *);
 static bool pqueue_is_full (const struct pqueue *);
 static bool pqueue_is_empty (const struct pqueue *);
@@ -62,15 +63,15 @@ static void pqueue_pop (struct pqueue *, struct ccase *, casenumber *);
 static void output_record (struct sort_writer *);
 
 struct casewriter *
-sort_create_writer (struct case_ordering *ordering)
+sort_create_writer (struct case_ordering *ordering, size_t value_cnt)
 {
-  size_t value_cnt = case_ordering_get_value_cnt (ordering);
   struct sort_writer *sort;
 
   sort = xmalloc (sizeof *sort);
+  sort->value_cnt = value_cnt;
   sort->ordering = case_ordering_clone (ordering);
-  sort->merge = merge_create (ordering);
-  sort->pqueue = pqueue_create (ordering);
+  sort->merge = merge_create (ordering, value_cnt);
+  sort->pqueue = pqueue_create (ordering, value_cnt);
   sort->run = NULL;
   sort->run_id = 0;
   case_nullify (&sort->run_end);
@@ -118,8 +119,7 @@ sort_casewriter_convert_to_reader (struct casewriter *writer, void *sort_)
   if (sort->run == NULL && sort->run_id == 0)
     {
       /* In-core sort. */
-      sort->run = mem_writer_create (case_ordering_get_value_cnt (
-                                       sort->ordering));
+      sort->run = mem_writer_create (casewriter_get_value_cnt (writer));
       sort->run_id = 1;
     }
   while (!pqueue_is_empty (sort->pqueue))
@@ -151,8 +151,7 @@ output_record (struct sort_writer *sort)
     }
   if (sort->run == NULL)
     {
-      sort->run = tmpfile_writer_create (case_ordering_get_value_cnt (
-                                           sort->ordering));
+      sort->run = tmpfile_writer_create (sort->value_cnt);
       sort->run_id = min_run_id;
     }
 
@@ -176,7 +175,8 @@ static struct casewriter_class sort_casewriter_class =
 struct casereader *
 sort_execute (struct casereader *input, struct case_ordering *ordering)
 {
-  struct casewriter *output = sort_create_writer (ordering);
+  struct casewriter *output =
+    sort_create_writer (ordering, casereader_get_value_cnt (input));
   casereader_transfer (input, output);
   return casewriter_make_reader (output);
 }
@@ -201,14 +201,14 @@ static int compare_pqueue_records_minheap (const void *a, const void *b,
                                            const void *pq_);
 
 static struct pqueue *
-pqueue_create (const struct case_ordering *ordering)
+pqueue_create (const struct case_ordering *ordering, size_t value_cnt)
 {
   struct pqueue *pq;
 
   pq = xmalloc (sizeof *pq);
   pq->ordering = case_ordering_clone (ordering);
   pq->record_cap
-    = settings_get_workspace_cases (case_ordering_get_value_cnt (ordering));
+    = settings_get_workspace_cases (value_cnt);
   if (pq->record_cap > max_buffers)
     pq->record_cap = max_buffers;
   else if (pq->record_cap < min_buffers)
index 7f7b2f8f740b3c2dc69784df4432b69da22da7c3..ea2c16b2e14a8a8ed1c2fbe0f838bb92bdcd4870 100644 (file)
@@ -25,7 +25,7 @@ struct case_ordering;
 extern int min_buffers ;
 extern int max_buffers ;
 
-struct casewriter *sort_create_writer (struct case_ordering *);
+struct casewriter *sort_create_writer (struct case_ordering *, size_t value_cnt);
 struct casereader *sort_execute (struct casereader *, struct case_ordering *);
 
 #endif /* math/sort.h */
diff --git a/src/math/statistic.h b/src/math/statistic.h
new file mode 100644 (file)
index 0000000..987264b
--- /dev/null
@@ -0,0 +1,40 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __STATISTIC_H__
+#define __STATISTIC_H__
+
+#include <stddef.h>
+
+struct ccase ;
+
+struct statistic
+{
+  void (*accumulate) (struct statistic *, const struct ccase *cx, double c, double cc, double y);
+  void (*destroy) (struct statistic *);
+};
+
+static inline void statistic_destroy (struct statistic *s);
+
+
+static inline void
+statistic_destroy (struct statistic *s)
+{
+  if (s) s->destroy (s);
+}
+
+
+#endif
diff --git a/src/math/time-series/ChangeLog b/src/math/time-series/ChangeLog
deleted file mode 100644 (file)
index 07cb6f4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-2006-06-04  Jason Stover  <jhs@debs.hjklfdsss.org>
-
-       * innovations.c (get_covariance): Initial version
-
-2006-05-25  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c:  New file
-
diff --git a/src/math/trimmed-mean.c b/src/math/trimmed-mean.c
new file mode 100644 (file)
index 0000000..da3d424
--- /dev/null
@@ -0,0 +1,94 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "trimmed-mean.h"
+#include <math/order-stats.h>
+
+#include <gl/xalloc.h>
+#include <libpspp/assertion.h>
+#include <math.h>
+#include <data/val-type.h>
+
+
+static void
+acc (struct statistic *s, const struct ccase *cx UNUSED, double c, double cc, double y)
+{
+  struct trimmed_mean *tm = (struct trimmed_mean *) s;
+  struct order_stats *os = (struct order_stats *) s;
+
+  if ( cc > os->k[0].tc && cc < os->k[1].tc)
+      tm->sum += c * y;
+
+  if ( tm->cyk1p1 == SYSMIS && cc >os->k[0].tc)
+      tm->cyk1p1 = c * y;
+}
+
+static void
+destroy (struct statistic *s)
+{
+  struct order_stats *os = (struct order_stats *) s;
+  free (os->k);
+  free (s);
+}
+
+struct statistic *
+trimmed_mean_create (double W, double tail)
+{
+  struct trimmed_mean *tm = xzalloc (sizeof (*tm));
+  struct order_stats *os = (struct order_stats *) tm;
+  struct statistic *stat = (struct statistic *) tm;
+
+  os->n_k = 2;
+  os->k = xcalloc (sizeof (*os->k), 2);
+
+  assert (tail >= 0);
+  assert (tail <= 1);
+
+  os->k[0].tc = tail * W;
+  os->k[1].tc = W * (1 - tail);
+
+  stat->accumulate = acc;
+  stat->destroy = destroy;
+
+  tm->cyk1p1 = SYSMIS;
+  tm->w = W;
+  tm->tail = tail;
+
+  return stat;
+}
+
+
+double
+trimmed_mean_calculate (const struct trimmed_mean *tm)
+{
+  const struct order_stats *os = (const struct order_stats *) tm;
+
+  assert (os->cc == tm->w);
+
+  return
+    (
+     (os->k[0].cc_p1 - os->k[0].tc) * os->k[0].y_p1
+     -
+     (os->k[1].cc - os->k[1].tc) * os->k[1].y_p1
+     +
+     tm->sum
+     -
+     tm->cyk1p1
+     )
+    /
+    ( (1.0 - 2 * tm->tail) * tm->w);
+}
diff --git a/src/math/trimmed-mean.h b/src/math/trimmed-mean.h
new file mode 100644 (file)
index 0000000..9339cab
--- /dev/null
@@ -0,0 +1,42 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __TRIMMED_MEAN_H__
+#define __TRIMMED_MEAN_H__
+
+#include <stddef.h>
+
+#include "order-stats.h"
+
+
+struct trimmed_mean
+{
+  struct order_stats parent;
+
+  /* The partial sum */
+  double sum;
+
+  /* The product of c_{k_1+1} and y_{k_1 + 1} */
+  double cyk1p1;
+
+  double w;
+  double tail;
+};
+
+struct statistic * trimmed_mean_create (double W, double c_min);
+double trimmed_mean_calculate (const struct trimmed_mean *);
+
+#endif
diff --git a/src/math/ts/ChangeLog b/src/math/ts/ChangeLog
deleted file mode 100644 (file)
index a353ffc..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-2006-07-16  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (get_coef): Fixed diagonal elements and call to
-       innovations_convolve().
-       (subtract_mean): New function. Subtract the mean before computing
-       the coefficients.
-
-2006-07-15  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (get_covariance): Fixed computation of
-       covariance. Made COV[i] the lag i covariance.
-       (update_cov): New function.
-       (get_covariance): Use gsl_vector_view's to get rows of correct
-       lag.
-
-2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (innovations_struct_init): Fix initialization of
-       coefficient. 
-
-2006-07-13  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (pspp_innovations): Altered function to use struct
-       design_matrix. 
-
-2006-07-06  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (get_covariance): Fixed subscripts.
-       (innovations_update_scale): Added check for subscript.
-       
-2006-07-05  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (innovations_struct_init): New function.
-
-2006-07-03  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (init_theta): Fixed subscripts.
-       * innovations.c (innovations_update_coeff): Fixed subscripts.
-       * innovations.c (get_covarience): Fixed subscripts.
-       * innovations.c (pspp_innovations_free): New function.
-       * innovations.c (pspp_innovations_free_one): New function.
-
-2006-07-02  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (get_coef): Moved instructions to
-       innovations_update_coeff() and init_theta().
-       * innovations.c (get_coef): Fixed allocation of theta.
-       * innovations.c (innovations_update_theta): New function.
-       * innovations.c (init_theta): New function.
-       * innovations.c (innovations_convolve): Fixed upper bound of
-       subscript in sum.
-
-2006-07-01  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c: Use gsl_matrices to avoid use of casefiles by
-       backend math routine.
-
-2006-06-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (innovations_update_scale): New function.
-       * innovations.c (get_coef): Save computed coefficients in est->coeff.
-
-       * innovations.c (get_coef): Initialize and free the innovations
-       coefficients. Call innovations_update_scale ().
-
-2006-06-16  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (innovations_convolve): New function.
-       * innovations.c (get_coef): New function.
-
-2006-06-04  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c (get_covariance): Initial version
-
-2006-05-25  Jason Stover  <jhs@math.gcsu.edu>
-
-       * innovations.c:  New file
-
diff --git a/src/math/ts/OChangeLog b/src/math/ts/OChangeLog
new file mode 100644 (file)
index 0000000..a353ffc
--- /dev/null
@@ -0,0 +1,78 @@
+2006-07-16  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (get_coef): Fixed diagonal elements and call to
+       innovations_convolve().
+       (subtract_mean): New function. Subtract the mean before computing
+       the coefficients.
+
+2006-07-15  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (get_covariance): Fixed computation of
+       covariance. Made COV[i] the lag i covariance.
+       (update_cov): New function.
+       (get_covariance): Use gsl_vector_view's to get rows of correct
+       lag.
+
+2006-07-14  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (innovations_struct_init): Fix initialization of
+       coefficient. 
+
+2006-07-13  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (pspp_innovations): Altered function to use struct
+       design_matrix. 
+
+2006-07-06  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (get_covariance): Fixed subscripts.
+       (innovations_update_scale): Added check for subscript.
+       
+2006-07-05  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (innovations_struct_init): New function.
+
+2006-07-03  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (init_theta): Fixed subscripts.
+       * innovations.c (innovations_update_coeff): Fixed subscripts.
+       * innovations.c (get_covarience): Fixed subscripts.
+       * innovations.c (pspp_innovations_free): New function.
+       * innovations.c (pspp_innovations_free_one): New function.
+
+2006-07-02  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (get_coef): Moved instructions to
+       innovations_update_coeff() and init_theta().
+       * innovations.c (get_coef): Fixed allocation of theta.
+       * innovations.c (innovations_update_theta): New function.
+       * innovations.c (init_theta): New function.
+       * innovations.c (innovations_convolve): Fixed upper bound of
+       subscript in sum.
+
+2006-07-01  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c: Use gsl_matrices to avoid use of casefiles by
+       backend math routine.
+
+2006-06-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (innovations_update_scale): New function.
+       * innovations.c (get_coef): Save computed coefficients in est->coeff.
+
+       * innovations.c (get_coef): Initialize and free the innovations
+       coefficients. Call innovations_update_scale ().
+
+2006-06-16  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (innovations_convolve): New function.
+       * innovations.c (get_coef): New function.
+
+2006-06-04  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c (get_covariance): Initial version
+
+2006-05-25  Jason Stover  <jhs@math.gcsu.edu>
+
+       * innovations.c:  New file
+
index ffc7967903f62ea86b8073f20ce0dee22e0ab13d..eecc53a81f68ed388b68cd7459307f1861cbd84f 100644 (file)
@@ -1,7 +1,9 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
-noinst_LIBRARIES += src/math/ts/libpspp_ts.a
+noinst_LTLIBRARIES += src/math/ts/libpspp_ts.la
 
-src_math_ts_libpspp_ts_a_SOURCES = \
+src_math_ts_libpspp_ts_la_SOURCES = \
        src/math/ts/innovations.c \
        src/math/ts/innovations.h
+
+EXTRA_DIST += src/math/ts/OChangeLog
index 3e3be2024711a727e8a382d48841213106c8f03e..b9a7cf223442a42ce597748320647a23a0739939 100644 (file)
@@ -28,7 +28,6 @@
 #include <config.h>
 #include <gsl/gsl_matrix.h>
 #include <gsl/gsl_vector.h>
-#include <gsl/gsl_math.h>
 #include <stdlib.h>
 #include <libpspp/compiler.h>
 #include <math/coefficient.h>
@@ -56,7 +55,7 @@ get_mean (const gsl_matrix *data,
       for (n = 0; n < data->size2; n++)
        {
          tmp = gsl_matrix_get (data, i, n);
-         if (!gsl_isnan (tmp))
+         if (!isnan (tmp))
            {
              est[n]->n_obs += 1.0;
              d = (tmp - est[n]->mean) / est[n]->n_obs;
@@ -77,9 +76,9 @@ update_cov (struct innovations_estimate **est, gsl_vector_const_view x,
     {
       xj = gsl_vector_get (&x.vector, j);
       yj = gsl_vector_get (&y.vector, j);
-      if (!gsl_isnan (xj))
+      if (!isnan (xj))
        {
-         if (!gsl_isnan (yj))
+         if (!isnan (yj))
            {
              xj -= est[j]->mean;
              yj -= est[j]->mean;
@@ -161,7 +160,7 @@ innovations_update_scale (struct innovations_estimate *est, double *theta,
       for (j = 0; j < i; j++)
        {
          k = i - j - 1;
-         result -= theta[k] * theta[k] * est->scale[j];
+         result -= pow2 (theta[k]) * est->scale[j];
        }
       est->scale[i] = result;
     }
diff --git a/src/math/tukey-hinges.c b/src/math/tukey-hinges.c
new file mode 100644 (file)
index 0000000..95a79c1
--- /dev/null
@@ -0,0 +1,101 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include "tukey-hinges.h"
+#include <math/order-stats.h>
+
+#include <gl/xalloc.h>
+#include <libpspp/assertion.h>
+#include <math.h>
+
+void
+tukey_hinges_calculate (const struct tukey_hinges *th, double hinge[3])
+{
+  double a[3];
+  double a_star[3];
+  int i;
+  const struct order_stats *os = &th->parent;
+
+  for (i = 0 ; i < 3 ; ++i)
+    {
+      a_star[i] = os->k[i].tc - os->k[i].cc;
+      a[i] = a_star[i] / os->k[i].c_p1;
+
+      if (a_star[i] < 1)
+       {
+         if (os->k[i].c_p1 >= 1 )
+           {
+             hinge[i] = (1 - a_star[i]) * os->k[i].y
+               + a_star[i] * os->k[i].y_p1;
+           }
+         else
+           {
+             hinge[i] = (1 - a[i]) * os->k[i].y
+               + a[i] * os->k[i].y_p1;
+           }
+       }
+      else
+       {
+         hinge[i] = os->k[i].y_p1;
+       }
+
+    }
+}
+
+static void
+destroy (struct statistic *s)
+{
+  struct order_stats *os = (struct order_stats *) s;
+
+  free (os->k);
+  free (s);
+};
+
+struct statistic *
+tukey_hinges_create (double W, double c_min)
+{
+  double d;
+  struct tukey_hinges *th = xzalloc (sizeof (*th));
+  struct order_stats *os = (struct order_stats *) th;
+  struct statistic *stat = (struct statistic *) th;
+
+  assert (c_min >= 0);
+
+  os->n_k = 3;
+  os->k = xcalloc (sizeof (*os->k), 3);
+
+  if ( c_min >= 1.0)
+    {
+      d = floor ((W + 3) / 2.0) / 2.0;
+
+      os->k[0].tc = d;
+      os->k[1].tc = W/2.0 + 0.5;
+      os->k[2].tc = W + 1 - d;
+    }
+  else
+    {
+      d = floor ((W/c_min + 3.0)/ 2.0) / 2.0 ;
+      os->k[0].tc = d * c_min;
+      os->k[1].tc = (W + c_min) / 2.0;
+      os->k[2].tc = W + c_min * (1 - d);
+    }
+
+
+  stat->destroy = destroy;
+
+  return stat;
+}
diff --git a/src/math/tukey-hinges.h b/src/math/tukey-hinges.h
new file mode 100644 (file)
index 0000000..d87691f
--- /dev/null
@@ -0,0 +1,37 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef __TUKEY_HINGES_H__
+#define __TUKEY_HINGES_H__
+
+#include <stddef.h>
+
+#include "order-stats.h"
+
+
+struct tukey_hinges
+{
+  struct order_stats parent;
+};
+
+struct statistic * tukey_hinges_create (double W, double c_min);
+
+
+void tukey_hinges_calculate (const struct tukey_hinges *h, double hinge[3]);
+
+
+
+#endif
diff --git a/src/output/ChangeLog b/src/output/ChangeLog
deleted file mode 100644 (file)
index b1928b9..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-2008-02-08  John Darrington <john@darrington.wattle.id.au>     
-
-       * journal.c: (journal_write) flush the stream on writes.
-       Useful for discovering syntax which causes a crash.
-
-2007-09-25  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6210.  Reviewed by John Darrington.
-
-       * ascii.c: Implement ability to resize output device parameters to
-       fit terminal window size as it changes.
-       (struct ascii_driver_ext): New members `auto_width',
-       `auto_length'.
-       (ascii_open_driver): Initialize new members, call
-       update_page_size.
-       (update_page_size): New function to update device size.
-       (handle_option): Support new "auto" setting for length, width.
-       (ascii_open_page): Call update_page_size.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * output.c (TWO_CHARS macro): Removed.
-       (outp_evaluate_dimension): Changed interface, rewritten.  Updated
-       all callers.
-       (internal_get_paper_size): Removed.
-       (parse_unit): New function.
-       (parse_paper_size): New function.
-       (outp_get_paper_size): Tweaked interface, rewritten.
-       (get_standard_paper_size): New function.
-       (read_paper_conf): New function.
-       (get_default_paper_size): New function.
-
-       * postscript.c (ps_open_driver): Use system default paper size as
-       default paper, instead of hard-coding US letter.
-       (handle_option): Allow outp_evaluate_dimension to supply error
-       message instead of generating it here.
-
-2007-09-21  Ben Pfaff  <blp@gnu.org>
-
-       * ascii.c (struct ascii_driver_ext): New member reported_error.
-       (ascii_open_driver): Initialize reported_error.
-       (ascii_open_page): Initialize the rest of the ascii driver data
-       even if we fail to open the output file.  Fixes bug #21117.
-
-       * chart.c (chart_create): Initialize lp member.  Fixes crash if
-       chart initialization fails.
-
-       * html.c (html_open_driver): Don't free chart_file_name in error
-       case, since html_close_driver will do that.  Fixes crash if file
-       open fails.
-
-       * postscript.c (ps_close_driver): Don't try to write to file if
-       it's null.  Fixes crash if file open fails.
-
-2007-09-08  John Darrington <john@darrington.wattle.id.au>     
-
-       * postscript.c html.c: Remove #include "getline.h" to concurr with 
-       new gnulib arrangements.
-
-2007-08-23  Ben Pfaff  <blp@gnu.org>
-
-       Implement journaling.  Bug #17240.
-       
-       * automake.mk (output_sources): Add journal.c, journal.h.
-       
-       * journal.c: New file.
-       
-       * journal.h: New file.
-
-2007-08-16  Ben Pfaff  <blp@gnu.org>
-
-       * output.c output.h: export function outp_configure_driver_line.
-       * ascii.c: Added an "append" property.
-       
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       Add support for charts to ASCII driver.  Bug #16364.
-       Thanks to John Darrington for review.
-       
-       * ascii.c (struct ascii_driver_ext): Add chart_type,
-       chart_file_name, chart_cnt members.
-       (ascii_open_driver): Initialize new members.
-       (static array option_tab): Add new options, reorganize slightly.
-       (handle_option): Handle new options.
-       (ascii_submit): New function.
-       (ascii_chart_initialise): Implement.
-       (ascii_chart_finalise): Implement.
-
-       * chart.c (chart_init_separate): New function.
-       (chart_finalise_separate): New function.
-       
-       * dummy-chart.c (chart_init_separate): New function.
-       (chart_finalise_separate): New function.
-
-       * html.c (html_open_driver): Don't free chart_file_name.
-       (html_close_driver): Do free chart_file_name.
-       (handle_option): Only give an error for chart-files options that
-       don't contain "#".
-       (html_initialise_chart): Use new chart_init_separate.
-       (html_finalise_chart): Use new chart_finalise_separate.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Allow the user to specify an initialization string to write at the
-       beginning of an ASCII output file.
-       * ascii.c (struct ascii_driver_ext): New member `init'.
-       (ascii_open_driver): Initialize `init'.
-       (ascii_close_driver): Parse `init'.
-       (ascii_open_page): Write `init' to output file.
-
-       * output.c (get_option_token): Fix parsing of octal constants.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Make interactive output go to the terminal (bug #17213), by
-       causing the UI to flush output to the user when it prompts for a
-       command.
-
-       * ascii.c (ascii_open_driver): Move the file open into
-       ascii_open_page, so that we can re-open after a flush.
-       (ascii_close_driver): Close file using ascii_flush.
-       (ascii_open_page): Open the output file if it's not already open.
-       Use fn_open so that we can support pipes.
-       (ascii_close_page): Do nothing if output file not open.
-       (ascii_flush): New function.
-       (static var ascii_class): Add ascii_flush.
-
-       * manager.c (som_flush): New function.
-
-       * output.c (outp_flush): New function.
-
-Tue Feb 20 07:03:48 2007  Ben Pfaff  <blp@gnu.org>
-
-       * html.c: Don't need to include "getlogin_r.h" anymore, because
-       gnulib merged it into <unistd.h>.
-
-Sun Feb 18 11:20:35 2007  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: Add missing _() around message.
-
-Sun Feb 11 17:59:30 2007  Ben Pfaff  <blp@gnu.org>
-
-       * html.c (html_initialise_chart): Mark `this' parameter UNUSED to
-       account for NO_CHARTS case.
-
-Sat Feb  3 21:56:46 2007  Ben Pfaff  <blp@gnu.org>
-
-       * table.c (tab_hline): Allow t->nr as y argument, so that we can
-       draw a line below the bottom row of the table.
-
-Wed Feb  7 21:38:12 2007  Ben Pfaff  <blp@gnu.org>
-
-       * afm.c: Add #include <limits.h>.  Thanks to John McCabe-Dansted
-       <gmatht@gmail.com> for pointing out the need.
-
-Sun Oct  8 07:09:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * table.c (tab_destroy): Freed title, since this is not allocated
-       from the pool.
-
-       * html.c (html_open_driver): Freed chart_file_name.
-
-Wed Jul 12 21:03:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * table.c (tab_natural_width): Get rid of warning on empty column,
-       which tended to just trigger false positives because we handle
-       joined cells so badly.  We need a real fix, and the warning is not
-       helpful.
-
-       * table.c (tab_offset): [DEBUGGING] Let row, col arguments be as
-       big as row or column count.
-       
-Wed Jul 12 20:58:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       * output.c (outp_drivers): [DEBUGGING] Delete unused declaration.
-
-Sat Jul  1 17:20:03 2006  Ben Pfaff  <blp@gnu.org>
-
-       Make the destination for charts configurable in the HTML driver.
-       Fixes bug #15723, "HTML driver creates .png files insecurely".
-
-       * htmlP.h: (struct html_driver_ext) Add chart_file_name, chart_cnt
-       members.
-       
-       * html.c: (html_open_driver) Initialize new members.
-       (option_tab var) Add "chart-files" option.
-       (handle_option) Parse "chart-files" option.
-       (html_initialise_chart) Name file based on "chart-files" option.
-       
-Sat Jul  1 22:41:26 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #16644: Output Driver crashes in DISPLAY VARIABLES.
-       
-       * table.c (tab_create): Don't allocate t->hrh, t->wrv yet, because
-       the table size might change before we're ready to use them.
-       (tabi_table) Allocate them here instead.
-
-Fri Jun  9 14:42:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       Reform string library.
-       
-       * output.c (init_default_drivers): Update call to
-       configure_driver() to new interface.
-       (get_option_token) Use a modifiable substring in interface instead
-       of a separate position parameter.  Use ss_get_*() functions.
-       (configure_driver) Take and work with substrings.
-       (configure_driver_line) Update call to configure_driver() to new
-       interface.
-       (outp_get_paper_size) Use substrings.
-
-       * output.h (struct outp_class): Change open_driver interface to
-       use substring.  Update all implementations.
-
-       * table.c (text_format): Change to return substring.
-       (tab_title) Use xvasprintf().
-
-       * table.h (struct tab_table): Change title member to char *.
-
-Thu May 25 18:02:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * table.c: Removed redundant extern declaration.
-
-Sun May 14 14:03:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * output.c (outp_eject_page): Always make sure that a page is open
-       upon return.
-
-Sun May 14 13:54:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: (ps_chart_finalise) Fix format of %%EndDocument
-       comment, which screwed up gv's idea of where one page ended and
-       the next one began.  Thanks to John Darrington for pointing out
-       the bug.
-
-Sun Apr 16 11:48:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start reforming error message support.  In this phase, we get rid
-       of "installation errors" and change all uses of msg() in the
-       output drivers to uses of error() or error_at_line().
-
-       * Removed all inclusion of <libpspp/message.h> in this directory.
-
-       * output.c: Changed all uses of msg() to error() or
-       error_at_line().
-       (outp_read_devices) Maintain line number in int variable instead
-       of "struct file_locator".
-       (tokener) Renamed get_option_token(), rewritten, changed interface.
-       (outp_parse_options) Change `options' argument to type const
-       struct string *.  Rewritten.
-       (configure_driver) Passes a struct string * to ->open_driver()
-       instead of char *.
-       (outp_get_paper_size) Maintain line number in int variable instead
-       of "struct file_locator".  Removed stupid cache.
-
-       * output.h: (struct outp_class) Change `open_driver' function to
-       take const struct string * instead of const char *.  Updated all
-       implementations.
-
-Mon Apr  3 11:14:38 2006  Ben Pfaff  <blp@gnu.org>
-
-       Rewrite a lot of the output drivers and infrastructure.
-       Started transitioning from msg() to error().
-       Vertical rules in tables now default to putting a small gap
-       between columns, instead of no gap or rule at all.
-       See NEWS for user-visible changes.
-
-       * automake.mk: (output_sources) Add afm.c, afm.h.  Remove font.h,
-       groff-font.c.
-       
-       * afm.c, afm.h: New files.
-
-       * font.h: Removed.
-
-       * groff-font.c: Removed.
-       
-       * ascii.c: Rewrote and simplified.
-
-       * html.c: Ditto.
-
-       * postscript.c: Ditto.
-
-       * output.c: (struct outp_driver_class_list) Move here from
-       output.h.  Remove ref_count member and all references to it.
-       (outp_init) Remove epsf_class references.
-       (init_default_drivers) Use new configure_driver_line() interface.
-       (parse_options) Renamed outp_parse_options(), changed interface.
-       (configure_driver) Changed args from `const char *'s to `const
-       struct string *'s.  Rewrote.  Don't call ->open_global().  Now
-       just calls ->open_driver() instead of ->preopen_driver(),
-       ->option(), ->postopen_driver().
-       (configure_driver_line) Adapt to new configure_driver() interface.
-       (destroy_driver) Don't call ->close_global().
-       (option_cmp) Removed.
-       (outp_match_keyword) Rewrite for simplicity.
-       (outp_open_page) New function.  Changed all equivalent
-       functionality to use this function instead.
-       (outp_close_page) Ditto.
-       (outp_eject_page) Use above functions.
-       (outp_string_width) Add font argument and change all callers to
-       pass one.
-
-       * output.h: (struct rect) Removed.
-       (OUTP_L_*) Name this enumeration "enum outp_line_style".
-       (OUTP_L_SPECIAL) Removed.
-       (struct color) Removed.
-       (OUTP_F_*) Removed.
-       (struct outp_styles) Removed.
-       (OUTP_T_*) Removed.
-       (enum outp_justification) New, containing OUTP_RIGHT, OUTP_LEFT,
-       OUTP_CENTER.
-       (enum outp_font) New, containing OUTP_FIXED, OUTP_PROPORTIONAL,
-       and OUTP_EMPHASIS.
-       (struct outp_text) Replaced `options' member by `font' and
-       `justification'.  Renamed `s' to `string'.  Removed `w', `l'.
-       Updated all usages.
-       (struct outp_class) Removed `magic', `open_global',
-       `close_global', `font_sizes', `preopen_driver', `option',
-       `postopen_driver', `line_horz', `line_vert', `line_intersection',
-       `box', `polyline_begin', `polyline_point', `polyline_end',
-       `text_set_font_by_name', `text_set_font_by_position',
-       `text_set_font_family', `text_get_font_name',
-       `text_get_font_family', `text_set_Size', and `text_get_size'
-       members.  Added `open_driver', `close_driver', `line' members.
-       Changed interface of `open_page', `close_page', `text_metrics',
-       `text_draw' members.  Updated all usages.
-       (struct outp_driver) Rearranged members.  Removed `driver_open',
-       `res', `horiz', `vert', `horiz_line_spacing', `vert_line_spacing'
-       members.
-       (struct outp_option_info) Removed.
-       (struct outp_driver_class_list) Removed.
-       (outp_match_keyword) Changed interface.
-
-       * table.c: (tab_create) Now ignores reallocable argument: tables
-       can always be reallocated.  Use pool_create_container().
-       Initialize vertical rules to UCHAR_MAX.
-       (options_to_font) New function.
-       (tab_destroy) Remove futile assignment.
-       (tab_realloc) Initialize vertical rules to UCHAR_MAX.
-       (text_format) Use xvasprintf() instead of local_alloc().
-       (tab_title) Always format the argument, and drop the option
-       argument.  Change all callers to agree.
-       (tab_natural_width) Adapt to new ->text_metrics() interface.
-       (tab_natural_height) Ditto.
-       (tab_joint_text) Clear rules within the joined cell.  Now
-       necessary because of the default to put spacing between cells.
-       (tab_output_text) Use xvasprintf() instead of local_alloc().
-       Remove special cases for fixed-width font.
-       (rule_to_spacing_type) New function.
-       (tabi_driver) Calculate rule widths manually now that we don't
-       have ->trh or ->trv.  Implement new default for vertical rules.
-       (render_rows) New function.
-       (tabi_render) Rewrite in terms of render_rows() for clarity.
-       (translate_justification) New function.
-       (rule_to_draw_type) New function.
-       (get_hrule) New function.
-       (get_vrule) New function.
-       (render_horz_rule) New function.
-       (render_vert_rule) New function.
-       (render_rule_intersection) New function.
-       (strip_width) New function.
-       (strip_height) New function.
-       (render_cell) New function.
-       (render_strip) Rewrite in terms of new functions.
-
-       * table.h: (TAB_EMPH) New flag.
-       (TAB_FIX) New flag.
-       (TAL_3) Removed.
-       (TAL_GAP) Added.
-       (TAL_SPACING) Removed.
-       (struct tab_table) Members `trh', `hrv', `hr_tot', `vr_tot'
-       removed.
-       [DEBUGGING] (reallocable) Removed.
-       (TAT_FIX) Removed.  All references replaced by TAB_FIX.
-       (TAT_TITLE) Now implies TAB_EMPH.
-               
-Thu Mar 30 16:26:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       * output.c: (colon_tokenize) Removed.
-       (configure_driver_line) Rewrote to use ds_separate().  Fixed leak.
-
-Tue Mar 28 13:50:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * html.c, postscript.c, output.c:  Changed to fit the new signature 
-       of fn_interp_vars
-       
-Sun Mar  5 13:19:32 2006  Ben Pfaff  <blp@gnu.org>
-
-       * postscript.c: (postopen) Fix segfault when the active file has
-       no title.
-
-Sat Mar  4 13:48:16 2006  Ben Pfaff  <blp@gnu.org>
-
-       We didn't provide a way to define these macros, so obviously
-       there's little demand for them.
-
-       * html.c: Don't test for NO_HTML.
-
-       * postscript.c: Don't test for NO_POSTSCRIPT.
-
-       * output.c: Don't test for either of those.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/output/OChangeLog b/src/output/OChangeLog
new file mode 100644 (file)
index 0000000..b1928b9
--- /dev/null
@@ -0,0 +1,406 @@
+2008-02-08  John Darrington <john@darrington.wattle.id.au>     
+
+       * journal.c: (journal_write) flush the stream on writes.
+       Useful for discovering syntax which causes a crash.
+
+2007-09-25  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6210.  Reviewed by John Darrington.
+
+       * ascii.c: Implement ability to resize output device parameters to
+       fit terminal window size as it changes.
+       (struct ascii_driver_ext): New members `auto_width',
+       `auto_length'.
+       (ascii_open_driver): Initialize new members, call
+       update_page_size.
+       (update_page_size): New function to update device size.
+       (handle_option): Support new "auto" setting for length, width.
+       (ascii_open_page): Call update_page_size.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * output.c (TWO_CHARS macro): Removed.
+       (outp_evaluate_dimension): Changed interface, rewritten.  Updated
+       all callers.
+       (internal_get_paper_size): Removed.
+       (parse_unit): New function.
+       (parse_paper_size): New function.
+       (outp_get_paper_size): Tweaked interface, rewritten.
+       (get_standard_paper_size): New function.
+       (read_paper_conf): New function.
+       (get_default_paper_size): New function.
+
+       * postscript.c (ps_open_driver): Use system default paper size as
+       default paper, instead of hard-coding US letter.
+       (handle_option): Allow outp_evaluate_dimension to supply error
+       message instead of generating it here.
+
+2007-09-21  Ben Pfaff  <blp@gnu.org>
+
+       * ascii.c (struct ascii_driver_ext): New member reported_error.
+       (ascii_open_driver): Initialize reported_error.
+       (ascii_open_page): Initialize the rest of the ascii driver data
+       even if we fail to open the output file.  Fixes bug #21117.
+
+       * chart.c (chart_create): Initialize lp member.  Fixes crash if
+       chart initialization fails.
+
+       * html.c (html_open_driver): Don't free chart_file_name in error
+       case, since html_close_driver will do that.  Fixes crash if file
+       open fails.
+
+       * postscript.c (ps_close_driver): Don't try to write to file if
+       it's null.  Fixes crash if file open fails.
+
+2007-09-08  John Darrington <john@darrington.wattle.id.au>     
+
+       * postscript.c html.c: Remove #include "getline.h" to concurr with 
+       new gnulib arrangements.
+
+2007-08-23  Ben Pfaff  <blp@gnu.org>
+
+       Implement journaling.  Bug #17240.
+       
+       * automake.mk (output_sources): Add journal.c, journal.h.
+       
+       * journal.c: New file.
+       
+       * journal.h: New file.
+
+2007-08-16  Ben Pfaff  <blp@gnu.org>
+
+       * output.c output.h: export function outp_configure_driver_line.
+       * ascii.c: Added an "append" property.
+       
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       Add support for charts to ASCII driver.  Bug #16364.
+       Thanks to John Darrington for review.
+       
+       * ascii.c (struct ascii_driver_ext): Add chart_type,
+       chart_file_name, chart_cnt members.
+       (ascii_open_driver): Initialize new members.
+       (static array option_tab): Add new options, reorganize slightly.
+       (handle_option): Handle new options.
+       (ascii_submit): New function.
+       (ascii_chart_initialise): Implement.
+       (ascii_chart_finalise): Implement.
+
+       * chart.c (chart_init_separate): New function.
+       (chart_finalise_separate): New function.
+       
+       * dummy-chart.c (chart_init_separate): New function.
+       (chart_finalise_separate): New function.
+
+       * html.c (html_open_driver): Don't free chart_file_name.
+       (html_close_driver): Do free chart_file_name.
+       (handle_option): Only give an error for chart-files options that
+       don't contain "#".
+       (html_initialise_chart): Use new chart_init_separate.
+       (html_finalise_chart): Use new chart_finalise_separate.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Allow the user to specify an initialization string to write at the
+       beginning of an ASCII output file.
+       * ascii.c (struct ascii_driver_ext): New member `init'.
+       (ascii_open_driver): Initialize `init'.
+       (ascii_close_driver): Parse `init'.
+       (ascii_open_page): Write `init' to output file.
+
+       * output.c (get_option_token): Fix parsing of octal constants.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Make interactive output go to the terminal (bug #17213), by
+       causing the UI to flush output to the user when it prompts for a
+       command.
+
+       * ascii.c (ascii_open_driver): Move the file open into
+       ascii_open_page, so that we can re-open after a flush.
+       (ascii_close_driver): Close file using ascii_flush.
+       (ascii_open_page): Open the output file if it's not already open.
+       Use fn_open so that we can support pipes.
+       (ascii_close_page): Do nothing if output file not open.
+       (ascii_flush): New function.
+       (static var ascii_class): Add ascii_flush.
+
+       * manager.c (som_flush): New function.
+
+       * output.c (outp_flush): New function.
+
+Tue Feb 20 07:03:48 2007  Ben Pfaff  <blp@gnu.org>
+
+       * html.c: Don't need to include "getlogin_r.h" anymore, because
+       gnulib merged it into <unistd.h>.
+
+Sun Feb 18 11:20:35 2007  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: Add missing _() around message.
+
+Sun Feb 11 17:59:30 2007  Ben Pfaff  <blp@gnu.org>
+
+       * html.c (html_initialise_chart): Mark `this' parameter UNUSED to
+       account for NO_CHARTS case.
+
+Sat Feb  3 21:56:46 2007  Ben Pfaff  <blp@gnu.org>
+
+       * table.c (tab_hline): Allow t->nr as y argument, so that we can
+       draw a line below the bottom row of the table.
+
+Wed Feb  7 21:38:12 2007  Ben Pfaff  <blp@gnu.org>
+
+       * afm.c: Add #include <limits.h>.  Thanks to John McCabe-Dansted
+       <gmatht@gmail.com> for pointing out the need.
+
+Sun Oct  8 07:09:34 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * table.c (tab_destroy): Freed title, since this is not allocated
+       from the pool.
+
+       * html.c (html_open_driver): Freed chart_file_name.
+
+Wed Jul 12 21:03:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * table.c (tab_natural_width): Get rid of warning on empty column,
+       which tended to just trigger false positives because we handle
+       joined cells so badly.  We need a real fix, and the warning is not
+       helpful.
+
+       * table.c (tab_offset): [DEBUGGING] Let row, col arguments be as
+       big as row or column count.
+       
+Wed Jul 12 20:58:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       * output.c (outp_drivers): [DEBUGGING] Delete unused declaration.
+
+Sat Jul  1 17:20:03 2006  Ben Pfaff  <blp@gnu.org>
+
+       Make the destination for charts configurable in the HTML driver.
+       Fixes bug #15723, "HTML driver creates .png files insecurely".
+
+       * htmlP.h: (struct html_driver_ext) Add chart_file_name, chart_cnt
+       members.
+       
+       * html.c: (html_open_driver) Initialize new members.
+       (option_tab var) Add "chart-files" option.
+       (handle_option) Parse "chart-files" option.
+       (html_initialise_chart) Name file based on "chart-files" option.
+       
+Sat Jul  1 22:41:26 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #16644: Output Driver crashes in DISPLAY VARIABLES.
+       
+       * table.c (tab_create): Don't allocate t->hrh, t->wrv yet, because
+       the table size might change before we're ready to use them.
+       (tabi_table) Allocate them here instead.
+
+Fri Jun  9 14:42:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       Reform string library.
+       
+       * output.c (init_default_drivers): Update call to
+       configure_driver() to new interface.
+       (get_option_token) Use a modifiable substring in interface instead
+       of a separate position parameter.  Use ss_get_*() functions.
+       (configure_driver) Take and work with substrings.
+       (configure_driver_line) Update call to configure_driver() to new
+       interface.
+       (outp_get_paper_size) Use substrings.
+
+       * output.h (struct outp_class): Change open_driver interface to
+       use substring.  Update all implementations.
+
+       * table.c (text_format): Change to return substring.
+       (tab_title) Use xvasprintf().
+
+       * table.h (struct tab_table): Change title member to char *.
+
+Thu May 25 18:02:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * table.c: Removed redundant extern declaration.
+
+Sun May 14 14:03:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * output.c (outp_eject_page): Always make sure that a page is open
+       upon return.
+
+Sun May 14 13:54:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: (ps_chart_finalise) Fix format of %%EndDocument
+       comment, which screwed up gv's idea of where one page ended and
+       the next one began.  Thanks to John Darrington for pointing out
+       the bug.
+
+Sun Apr 16 11:48:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start reforming error message support.  In this phase, we get rid
+       of "installation errors" and change all uses of msg() in the
+       output drivers to uses of error() or error_at_line().
+
+       * Removed all inclusion of <libpspp/message.h> in this directory.
+
+       * output.c: Changed all uses of msg() to error() or
+       error_at_line().
+       (outp_read_devices) Maintain line number in int variable instead
+       of "struct file_locator".
+       (tokener) Renamed get_option_token(), rewritten, changed interface.
+       (outp_parse_options) Change `options' argument to type const
+       struct string *.  Rewritten.
+       (configure_driver) Passes a struct string * to ->open_driver()
+       instead of char *.
+       (outp_get_paper_size) Maintain line number in int variable instead
+       of "struct file_locator".  Removed stupid cache.
+
+       * output.h: (struct outp_class) Change `open_driver' function to
+       take const struct string * instead of const char *.  Updated all
+       implementations.
+
+Mon Apr  3 11:14:38 2006  Ben Pfaff  <blp@gnu.org>
+
+       Rewrite a lot of the output drivers and infrastructure.
+       Started transitioning from msg() to error().
+       Vertical rules in tables now default to putting a small gap
+       between columns, instead of no gap or rule at all.
+       See NEWS for user-visible changes.
+
+       * automake.mk: (output_sources) Add afm.c, afm.h.  Remove font.h,
+       groff-font.c.
+       
+       * afm.c, afm.h: New files.
+
+       * font.h: Removed.
+
+       * groff-font.c: Removed.
+       
+       * ascii.c: Rewrote and simplified.
+
+       * html.c: Ditto.
+
+       * postscript.c: Ditto.
+
+       * output.c: (struct outp_driver_class_list) Move here from
+       output.h.  Remove ref_count member and all references to it.
+       (outp_init) Remove epsf_class references.
+       (init_default_drivers) Use new configure_driver_line() interface.
+       (parse_options) Renamed outp_parse_options(), changed interface.
+       (configure_driver) Changed args from `const char *'s to `const
+       struct string *'s.  Rewrote.  Don't call ->open_global().  Now
+       just calls ->open_driver() instead of ->preopen_driver(),
+       ->option(), ->postopen_driver().
+       (configure_driver_line) Adapt to new configure_driver() interface.
+       (destroy_driver) Don't call ->close_global().
+       (option_cmp) Removed.
+       (outp_match_keyword) Rewrite for simplicity.
+       (outp_open_page) New function.  Changed all equivalent
+       functionality to use this function instead.
+       (outp_close_page) Ditto.
+       (outp_eject_page) Use above functions.
+       (outp_string_width) Add font argument and change all callers to
+       pass one.
+
+       * output.h: (struct rect) Removed.
+       (OUTP_L_*) Name this enumeration "enum outp_line_style".
+       (OUTP_L_SPECIAL) Removed.
+       (struct color) Removed.
+       (OUTP_F_*) Removed.
+       (struct outp_styles) Removed.
+       (OUTP_T_*) Removed.
+       (enum outp_justification) New, containing OUTP_RIGHT, OUTP_LEFT,
+       OUTP_CENTER.
+       (enum outp_font) New, containing OUTP_FIXED, OUTP_PROPORTIONAL,
+       and OUTP_EMPHASIS.
+       (struct outp_text) Replaced `options' member by `font' and
+       `justification'.  Renamed `s' to `string'.  Removed `w', `l'.
+       Updated all usages.
+       (struct outp_class) Removed `magic', `open_global',
+       `close_global', `font_sizes', `preopen_driver', `option',
+       `postopen_driver', `line_horz', `line_vert', `line_intersection',
+       `box', `polyline_begin', `polyline_point', `polyline_end',
+       `text_set_font_by_name', `text_set_font_by_position',
+       `text_set_font_family', `text_get_font_name',
+       `text_get_font_family', `text_set_Size', and `text_get_size'
+       members.  Added `open_driver', `close_driver', `line' members.
+       Changed interface of `open_page', `close_page', `text_metrics',
+       `text_draw' members.  Updated all usages.
+       (struct outp_driver) Rearranged members.  Removed `driver_open',
+       `res', `horiz', `vert', `horiz_line_spacing', `vert_line_spacing'
+       members.
+       (struct outp_option_info) Removed.
+       (struct outp_driver_class_list) Removed.
+       (outp_match_keyword) Changed interface.
+
+       * table.c: (tab_create) Now ignores reallocable argument: tables
+       can always be reallocated.  Use pool_create_container().
+       Initialize vertical rules to UCHAR_MAX.
+       (options_to_font) New function.
+       (tab_destroy) Remove futile assignment.
+       (tab_realloc) Initialize vertical rules to UCHAR_MAX.
+       (text_format) Use xvasprintf() instead of local_alloc().
+       (tab_title) Always format the argument, and drop the option
+       argument.  Change all callers to agree.
+       (tab_natural_width) Adapt to new ->text_metrics() interface.
+       (tab_natural_height) Ditto.
+       (tab_joint_text) Clear rules within the joined cell.  Now
+       necessary because of the default to put spacing between cells.
+       (tab_output_text) Use xvasprintf() instead of local_alloc().
+       Remove special cases for fixed-width font.
+       (rule_to_spacing_type) New function.
+       (tabi_driver) Calculate rule widths manually now that we don't
+       have ->trh or ->trv.  Implement new default for vertical rules.
+       (render_rows) New function.
+       (tabi_render) Rewrite in terms of render_rows() for clarity.
+       (translate_justification) New function.
+       (rule_to_draw_type) New function.
+       (get_hrule) New function.
+       (get_vrule) New function.
+       (render_horz_rule) New function.
+       (render_vert_rule) New function.
+       (render_rule_intersection) New function.
+       (strip_width) New function.
+       (strip_height) New function.
+       (render_cell) New function.
+       (render_strip) Rewrite in terms of new functions.
+
+       * table.h: (TAB_EMPH) New flag.
+       (TAB_FIX) New flag.
+       (TAL_3) Removed.
+       (TAL_GAP) Added.
+       (TAL_SPACING) Removed.
+       (struct tab_table) Members `trh', `hrv', `hr_tot', `vr_tot'
+       removed.
+       [DEBUGGING] (reallocable) Removed.
+       (TAT_FIX) Removed.  All references replaced by TAB_FIX.
+       (TAT_TITLE) Now implies TAB_EMPH.
+               
+Thu Mar 30 16:26:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       * output.c: (colon_tokenize) Removed.
+       (configure_driver_line) Rewrote to use ds_separate().  Fixed leak.
+
+Tue Mar 28 13:50:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * html.c, postscript.c, output.c:  Changed to fit the new signature 
+       of fn_interp_vars
+       
+Sun Mar  5 13:19:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * postscript.c: (postopen) Fix segfault when the active file has
+       no title.
+
+Sat Mar  4 13:48:16 2006  Ben Pfaff  <blp@gnu.org>
+
+       We didn't provide a way to define these macros, so obviously
+       there's little demand for them.
+
+       * html.c: Don't test for NO_HTML.
+
+       * postscript.c: Don't test for NO_POSTSCRIPT.
+
+       * output.c: Don't test for either of those.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 78898f46d41d868ce54730ab908acea38cd5cb3e..ec92c559e044723180977db31ca43708c7f637bd 100644 (file)
@@ -3,7 +3,7 @@
 
 include $(top_srcdir)/src/output/charts/automake.mk
 
-noinst_LIBRARIES += src/output/liboutput.
+noinst_LTLIBRARIES += src/output/liboutput.l
 
 output_sources = \
        src/output/afm.c \
@@ -23,13 +23,13 @@ output_sources = \
 
 
 if WITHCHARTS
-src_output_liboutput_a_SOURCES = $(output_sources) src/output/chart.c
+src_output_liboutput_la_SOURCES = $(output_sources) src/output/chart.c
 
 EXTRA_DIST += src/output/dummy-chart.c
 else
-src_output_liboutput_a_SOURCES = $(output_sources) src/output/dummy-chart.c
+src_output_liboutput_la_SOURCES = $(output_sources) src/output/dummy-chart.c
 
 EXTRA_DIST += src/output/chart.c
 endif
 
-
+EXTRA_DIST += src/output/OChangeLog
diff --git a/src/output/charts/ChangeLog b/src/output/charts/ChangeLog
deleted file mode 100644 (file)
index f735a6c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-2007-09-18  Ben Pfaff  <blp@gnu.org>
-
-       * plot-hist.c (histogram_plot): Remove incorrect assertion.  Fixes
-       bug #21101.  Reviewed by John Darrington.
-
-Sun Feb 11 19:43:39 2007  Ben Pfaff  <blp@gnu.org>
-
-       * dummy-chart.c: Apply UNUSED and include additional headers to
-       avoid complaints from GCC.  Patch #5739.
-
-Sat Mar  4 13:24:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Move definition of NO_CHARTS here from pref.h.orig.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/output/charts/OChangeLog b/src/output/charts/OChangeLog
new file mode 100644 (file)
index 0000000..f735a6c
--- /dev/null
@@ -0,0 +1,17 @@
+2007-09-18  Ben Pfaff  <blp@gnu.org>
+
+       * plot-hist.c (histogram_plot): Remove incorrect assertion.  Fixes
+       bug #21101.  Reviewed by John Darrington.
+
+Sun Feb 11 19:43:39 2007  Ben Pfaff  <blp@gnu.org>
+
+       * dummy-chart.c: Apply UNUSED and include additional headers to
+       avoid complaints from GCC.  Patch #5739.
+
+Sat Mar  4 13:24:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Move definition of NO_CHARTS here from pref.h.orig.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index f1d71264fb9e54179667d1a36e4a96a7fb8db615..ab0ff51047a4ffeb608770c3b088df8843077204 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
-noinst_LIBRARIES += src/output/charts/libcharts.a
+noinst_LTLIBRARIES += src/output/charts/libcharts.la
 
 chart_sources = \
        src/output/charts/barchart.c \
@@ -17,12 +17,12 @@ chart_sources = \
        src/output/charts/plot-hist.h
 
 if WITHCHARTS
-src_output_charts_libcharts_a_SOURCES = \
+src_output_charts_libcharts_la_SOURCES = \
        $(chart_sources)
 
 EXTRA_DIST += src/output/charts/dummy-chart.c
 else
-src_output_charts_libcharts_a_SOURCES =  \
+src_output_charts_libcharts_la_SOURCES =  \
        src/output/charts/dummy-chart.c
 
 EXTRA_DIST += $(chart_sources)
@@ -30,3 +30,5 @@ EXTRA_DIST += $(chart_sources)
 AM_CPPFLAGS += -DNO_CHARTS
 
 endif
+
+EXTRA_DIST += src/output/charts/OChangeLog
index d4a5ccab6c2fff527e70e8ed4a55cc68f120a64e..c3641580e0511d66a0a293819c8b6f065a53f96d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2008 Free Software Foundation, Inc.
 
    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
 
 #include <output/chart.h>
 #include <math/chart-geometry.h>
-#include <math/factor-stats.h>
-
-
-
+#include <math/box-whisker.h>
 
 /* Draw a box-and-whiskers plot
 */
 
-/* Draw an outlier on the plot CH
+/* Draw an OUTLIER on the plot CH
  * at CENTRELINE
- * The outlier is in (*wvp)[idx]
- * If EXTREME is non zero, then consider it to be an extreme
- * value
  */
-void
-draw_outlier(struct chart *ch, double centreline,
-            struct weighted_value **wvp,
-            int idx,
-            short extreme);
-
-
-void
-draw_outlier(struct chart *ch, double centreline,
-            struct weighted_value **wvp,
-            int idx,
-            short extreme
-            )
+static void
+draw_case (struct chart *ch, double centreline,
+          const struct outlier *outlier)
 {
-  char label[10];
 
 #define MARKER_CIRCLE 4
 #define MARKER_STAR 3
 
   pl_fmarker_r(ch->lp,
               centreline,
-              ch->data_bottom +
-              (wvp[idx]->v.f - ch->y_min ) * ch->ordinate_scale,
-              extreme?MARKER_STAR:MARKER_CIRCLE,
+              ch->data_bottom + (outlier->value - ch->y_min) * ch->ordinate_scale,
+              outlier->extreme ? MARKER_STAR : MARKER_CIRCLE,
               20);
 
   pl_moverel_r(ch->lp, 10,0);
 
-  snprintf(label, 10, "%d", wvp[idx]->case_nos->num);
-
-  pl_alabel_r(ch->lp, 'l', 'c', label);
-
+  pl_alabel_r(ch->lp, 'l', 'c', ds_cstr (&outlier->label));
 }
 
 
 void
-boxplot_draw_boxplot(struct chart *ch,
-                    double box_centre,
-                    double box_width,
-                    struct metrics *m,
-                    const char *name)
+boxplot_draw_boxplot (struct chart *ch,
+                     double box_centre,
+                     double box_width,
+                     const struct box_whisker *bw,
+                     const char *name)
 {
   double whisker[2];
-  int i;
-
-  const double *hinge = m->hinge;
-  struct weighted_value **wvp = m->wvp;
-  const int n_data = m->n_data;
-
-  const double step = (hinge[2] - hinge[0]) * 1.5;
+  double hinge[3];
+  struct ll *ll;
 
+  const struct ll_list *outliers;
 
   const double box_left = box_centre - box_width / 2.0;
 
   const double box_right = box_centre + box_width / 2.0;
 
+  double box_bottom ;
+  double box_top ;
+  double bottom_whisker ;
+  double top_whisker ;
 
-  const double box_bottom =
-    ch->data_bottom + ( hinge[0] - ch->y_min ) * ch->ordinate_scale;
-
-
-  const double box_top =
-    ch->data_bottom + ( hinge[2] - ch->y_min ) * ch->ordinate_scale;
-
-  assert(m);
+  box_whisker_whiskers (bw, whisker);
+  box_whisker_hinges (bw, hinge);
 
-  /* Can't really draw a boxplot if there's no data */
-  if ( n_data == 0 )
-         return ;
+  box_bottom = ch->data_bottom + (hinge[0] - ch->y_min ) * ch->ordinate_scale;
 
-  whisker[1] = hinge[2];
-  whisker[0] = wvp[0]->v.f;
+  box_top = ch->data_bottom + (hinge[2] - ch->y_min ) * ch->ordinate_scale;
 
-  for ( i = 0 ; i < n_data ; ++i )
-    {
-      if ( hinge[2] + step >  wvp[i]->v.f)
-       whisker[1] = wvp[i]->v.f;
-
-      if ( hinge[0] - step >  wvp[i]->v.f)
-       whisker[0] = wvp[i]->v.f;
-
-    }
-
-  {
-  const double bottom_whisker =
-    ch->data_bottom + ( whisker[0] - ch->y_min ) * ch->ordinate_scale;
-
-  const double top_whisker =
-    ch->data_bottom + ( whisker[1] - ch->y_min ) * ch->ordinate_scale;
+  bottom_whisker = ch->data_bottom + (whisker[0] - ch->y_min) *
+    ch->ordinate_scale;
 
+  top_whisker = ch->data_bottom + (whisker[1] - ch->y_min) * ch->ordinate_scale;
 
   pl_savestate_r(ch->lp);
 
-
   /* Draw the box */
-  pl_savestate_r(ch->lp);
-  pl_fillcolorname_r(ch->lp,ch->fill_colour);
-  pl_filltype_r(ch->lp,1);
-  pl_fbox_r(ch->lp,
+  pl_savestate_r (ch->lp);
+  pl_fillcolorname_r (ch->lp, ch->fill_colour);
+  pl_filltype_r (ch->lp,1);
+  pl_fbox_r (ch->lp,
            box_left,
            box_bottom,
            box_right,
            box_top);
 
-  pl_restorestate_r(ch->lp);
-
-
+  pl_restorestate_r (ch->lp);
 
   /* Draw the median */
-  pl_savestate_r(ch->lp);
-  pl_linewidth_r(ch->lp,5);
-  pl_fline_r(ch->lp,
+  pl_savestate_r (ch->lp);
+  pl_linewidth_r (ch->lp, 5);
+  pl_fline_r (ch->lp,
             box_left,
-            ch->data_bottom + ( hinge[1] - ch->y_min ) * ch->ordinate_scale,
+            ch->data_bottom + (hinge[1] - ch->y_min) * ch->ordinate_scale,
             box_right,
-            ch->data_bottom + ( hinge[1] - ch->y_min ) * ch->ordinate_scale);
-  pl_restorestate_r(ch->lp);
-
+            ch->data_bottom + (hinge[1] - ch->y_min) * ch->ordinate_scale);
+  pl_restorestate_r (ch->lp);
 
   /* Draw the bottom whisker */
-  pl_fline_r(ch->lp,
+  pl_fline_r (ch->lp,
             box_left,
             bottom_whisker,
             box_right,
             bottom_whisker);
 
   /* Draw top whisker */
-  pl_fline_r(ch->lp,
+  pl_fline_r (ch->lp,
             box_left,
             top_whisker,
             box_right,
             top_whisker);
 
 
-
   /* Draw centre line.
      (bottom half) */
-  pl_fline_r(ch->lp,
+  pl_fline_r (ch->lp,
             box_centre, bottom_whisker,
             box_centre, box_bottom);
 
   /* (top half) */
-  pl_fline_r(ch->lp,
+  pl_fline_r (ch->lp,
             box_centre, top_whisker,
             box_centre, box_top);
-  }
 
-  /* Draw outliers */
-  for ( i = 0 ; i < n_data ; ++i )
+  outliers = box_whisker_outliers (bw);
+  for (ll = ll_head (outliers);
+       ll != ll_null (outliers); ll = ll_next (ll))
     {
-      if ( wvp[i]->v.f >= hinge[2] + step )
-       draw_outlier(ch, box_centre, wvp, i,
-                    ( wvp[i]->v.f > hinge[2] + 2 * step )
-                    );
-
-      if ( wvp[i]->v.f <= hinge[0] - step )
-       draw_outlier(ch, box_centre, wvp, i,
-                    ( wvp[i]->v.f < hinge[0] - 2 * step )
-                    );
+      const struct outlier *outlier = ll_data (ll, struct outlier, ll);
+      draw_case (ch, box_centre, outlier);
     }
 
-
   /* Draw  tick  mark on x axis */
   draw_tick(ch, TICK_ABSCISSA, box_centre - ch->data_left, name);
 
   pl_restorestate_r(ch->lp);
-
 }
 
-
-
 void
-boxplot_draw_yscale(struct chart *ch , double y_max, double y_min)
+boxplot_draw_yscale (struct chart *ch, double y_max, double y_min)
 {
   double y_tick;
   double d;
@@ -223,7 +164,7 @@ boxplot_draw_yscale(struct chart *ch , double y_max, double y_min)
   ch->y_max  = y_max;
   ch->y_min  = y_min;
 
-  y_tick = chart_rounded_tick(fabs(ch->y_max - ch->y_min) / 5.0);
+  y_tick = chart_rounded_tick (fabs(ch->y_max - ch->y_min) / 5.0);
 
   ch->y_min = (ceil( ch->y_min  / y_tick ) - 1.0  ) * y_tick;
 
@@ -232,7 +173,6 @@ boxplot_draw_yscale(struct chart *ch , double y_max, double y_min)
   ch->ordinate_scale = fabs(ch->data_top - ch->data_bottom)
     / fabs(ch->y_max - ch->y_min) ;
 
-
   /* Move to data bottom-left */
   pl_move_r(ch->lp,
            ch->data_left, ch->data_bottom);
@@ -241,5 +181,4 @@ boxplot_draw_yscale(struct chart *ch , double y_max, double y_min)
     {
       draw_tick (ch, TICK_ORDINATE, (d - ch->y_min ) * ch->ordinate_scale, "%g", d);
     }
-
 }
index 656d8d49b3cb496277b0a8d49f386b1e6492d41c..7b2c4b8fdc1c2407c86cfe308a1c5ed4b72a31ba 100644 (file)
 #define BOX_WHISKER_H
 
 struct chart ;
-struct weighted_value;
-struct metrics;
+struct box_whisker;
 
-/* Draw an outlier on the plot CH
- * at CENTRELINE
- * The outlier is in (*wvp)[idx]
- * If EXTREME is non zero, then consider it to be an extreme
- * value
- */
-void  draw_outlier(struct chart *ch, double centreline,
-            struct weighted_value **wvp,
-            int idx,
-            short extreme);
+void boxplot_draw_boxplot (struct chart *ch,
+                          double box_centre,
+                          double box_width,
+                          const struct box_whisker *w,
+                          const char *name);
 
 
-void boxplot_draw_boxplot(struct chart *ch,
-                    double box_centre,
-                    double box_width,
-                    struct metrics *m,
-                    const char *name);
-
-
-void boxplot_draw_yscale(struct chart *ch , double y_max, double y_min);
+void boxplot_draw_yscale (struct chart *ch , double y_max, double y_min);
 
 #endif
index 9d4f722b2411ddb3da506459c756c5e46c18e30d..e22f958f7c8e81547c9b103d0de3b37628ce07ee 100644 (file)
 #endif
 
 void
-chart_write_title(struct chart *chart UNUSED, const char *title UNUSED, ...)
+chart_write_title (struct chart *chart UNUSED, const char *title UNUSED, ...)
 {
 }
 
 
 void
-chart_write_xscale(struct chart *ch UNUSED,
-                   double min UNUSED, double max UNUSED, int ticks UNUSED)
+chart_write_xscale (struct chart *ch UNUSED,
+                   double min UNUSED, double max UNUSED, int ticks UNUSED)
 {
 }
 
 
 void
-chart_write_yscale(struct chart *ch UNUSED UNUSED,
-                   double smin UNUSED, double smax UNUSED, int ticks UNUSED)
+chart_write_yscale (struct chart *ch UNUSED UNUSED,
+                   double smin UNUSED, double smax UNUSED, int ticks UNUSED)
 {
 }
 
 
 void
-chart_write_xlabel(struct chart *ch UNUSED, const char *label UNUSED)
+chart_write_xlabel (struct chart *ch UNUSED, const char *label UNUSED)
 {
 }
 
 void
-chart_write_ylabel(struct chart *ch UNUSED, const char *label UNUSED)
+chart_write_ylabel (struct chart *ch UNUSED, const char *label UNUSED)
 {
 }
 
 
 void
-chart_line(struct chart *ch UNUSED,
-           double slope UNUSED, double intercept UNUSED,
-          double limit1 UNUSED, double limit2 UNUSED,
-           enum CHART_DIM lim_dim UNUSED)
+chart_line (struct chart *ch UNUSED,
+           double slope UNUSED, double intercept UNUSED,
+           double limit1 UNUSED, double limit2 UNUSED,
+           enum CHART_DIM lim_dim UNUSED)
 {
 }
 
 
 void
-chart_datum(struct chart *ch UNUSED, int dataset UNUSED UNUSED,
-            double x UNUSED, double y UNUSED)
+chart_datum (struct chart *ch UNUSED, int dataset UNUSED UNUSED,
+            double x UNUSED, double y UNUSED)
 {
 }
 
-struct normal_curve;
+void
+histogram_plot (const struct histogram *hist UNUSED,
+               const char *label UNUSED,
+               const struct moments1 *m UNUSED)
+{
+}
 
 void
-histogram_plot(const gsl_histogram *hist UNUSED,
-              const char *factorname UNUSED,
-              const struct normal_curve *norm UNUSED,
-               short show_normal UNUSED)
+histogram_plot_n (const struct histogram *hist UNUSED,
+                 const char *label UNUSED,
+                 double n UNUSED, double mean UNUSED, double stddev UNUSED,
+                 bool show_normal UNUSED)
 {
 }
 
+
 void
-boxplot_draw_yscale(struct chart *ch UNUSED,
-                    double y_max UNUSED, double y_min UNUSED)
+boxplot_draw_yscale (struct chart *ch UNUSED,
+                    double y_max UNUSED, double y_min UNUSED)
 {
 }
 
 void
-boxplot_draw_boxplot(struct chart *ch UNUSED,
-                    double box_centre UNUSED,
-                    double box_width UNUSED,
-                    struct metrics *m UNUSED,
-                    const char *name UNUSED)
+boxplot_draw_boxplot (struct chart *ch UNUSED,
+                     double box_centre UNUSED,
+                     double box_width UNUSED,
+                     const struct box_whisker *w UNUSED,
+                     const char *name UNUSED)
 {
 }
 
 
 
+
 void
-piechart_plot(const char *title UNUSED,
-              const struct slice *slices UNUSED, int n_slices UNUSED)
+piechart_plot (const char *title UNUSED,
+              const struct slice *slices UNUSED, int n_slices UNUSED)
 {
 }
index 0f183208a2486ac5c4e07c4fd325b4bbf6a12d6d..4b11618a2f1a409fa3d92a9071a456131ce8485a 100644 (file)
@@ -1,10 +1,10 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright  (C) 2004 Free Software Foundation, Inc.
 
    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 3 of the License, or
-   (at your option) any later version.
+    (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
 #include <data/variable.h>
 #include <libpspp/hash.h>
 #include <output/chart.h>
+#include <math/histogram.h>
+#include <math/moments.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 /* Write the legend of the chart */
-void
-histogram_write_legend(struct chart *ch, const struct normal_curve *norm)
+static void
+histogram_write_legend (struct chart *ch, double n, double mean, double stddev)
 {
   char buf[100];
-  if ( !ch )
+
+  if (!ch)
     return ;
 
-  pl_savestate_r(ch->lp);
+  pl_savestate_r (ch->lp);
 
-  sprintf(buf,"N = %.2f",norm->N);
-  pl_move_r(ch->lp, ch->legend_left, ch->data_bottom);
-  pl_alabel_r(ch->lp,0,'b',buf);
+  sprintf (buf, "N = %.2f", n);
+  pl_move_r (ch->lp, ch->legend_left, ch->data_bottom);
+  pl_alabel_r (ch->lp, 0, 'b', buf);
 
-  sprintf(buf,"Mean = %.1f",norm->mean);
-  pl_fmove_r(ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5);
-  pl_alabel_r(ch->lp,0,'b',buf);
+  sprintf (buf, "Mean = %.1f", mean);
+  pl_fmove_r (ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5);
+  pl_alabel_r (ch->lp, 0, 'b', buf);
 
-  sprintf(buf,"Std. Dev = %.2f",norm->stddev);
-  pl_fmove_r(ch->lp,ch->legend_left,ch->data_bottom + ch->font_size * 1.5 * 2);
-  pl_alabel_r(ch->lp,0,'b',buf);
+  sprintf (buf, "Std. Dev = %.2f", stddev);
+  pl_fmove_r (ch->lp, ch->legend_left, ch->data_bottom + ch->font_size * 1.5 * 2);
+  pl_alabel_r (ch->lp, 0, 'b', buf);
 
-  pl_restorestate_r(ch->lp);
+  pl_restorestate_r (ch->lp);
 }
 
-static void hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar);
+static void hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar);
 
 
 static void
-hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar)
+hist_draw_bar (struct chart *ch, const struct histogram *hist, int bar)
 {
-  if ( !ch )
+  if (!ch)
     return ;
 
-
   {
     double upper;
     double lower;
     double height;
 
-    const size_t bins = gsl_histogram_bins(hist);
+    const size_t bins = gsl_histogram_bins (hist->gsl_hist);
     const double x_pos = (ch->data_right - ch->data_left) * bar / (double) bins ;
     const double width = (ch->data_right - ch->data_left) / (double) bins ;
 
+    assert ( 0 == gsl_histogram_get_range (hist->gsl_hist, bar, &lower, &upper));
 
-    assert ( 0 == gsl_histogram_get_range(hist, bar, &lower, &upper));
-
-    assert( upper >= lower);
+    assert ( upper >= lower);
 
-    height = gsl_histogram_get(hist, bar) *
-      (ch->data_top - ch->data_bottom) / gsl_histogram_max_val(hist);
+    height = gsl_histogram_get (hist->gsl_hist, bar) *
+     (ch->data_top - ch->data_bottom) / gsl_histogram_max_val (hist->gsl_hist);
 
-    pl_savestate_r(ch->lp);
-    pl_move_r(ch->lp,ch->data_left, ch->data_bottom);
-    pl_fillcolorname_r(ch->lp, ch->fill_colour);
-    pl_filltype_r(ch->lp,1);
+    pl_savestate_r (ch->lp);
+    pl_move_r (ch->lp,ch->data_left, ch->data_bottom);
+    pl_fillcolorname_r (ch->lp, ch->fill_colour);
+    pl_filltype_r (ch->lp,1);
 
 
-    pl_fboxrel_r(ch->lp,
+    pl_fboxrel_r (ch->lp,
                 x_pos, 0,
                 x_pos + width, height);
 
-    pl_restorestate_r(ch->lp);
+    pl_restorestate_r (ch->lp);
 
     {
       char buf[5];
-      snprintf(buf,5,"%g",(upper + lower) / 2.0);
-      draw_tick(ch, TICK_ABSCISSA,
+      snprintf (buf,5,"%g", (upper + lower) / 2.0);
+      draw_tick (ch, TICK_ABSCISSA,
                x_pos + width / 2.0, buf);
     }
   }
@@ -109,73 +110,87 @@ hist_draw_bar(struct chart *ch, const gsl_histogram *hist, int bar)
 
 
 
+void
+histogram_plot (const struct histogram *hist,
+               const char *label,
+               const struct moments1 *m)
+{
+  double mean, var, n;
+
+  moments1_calculate (m, &n, &mean, &var, NULL,  NULL);
+
+  histogram_plot_n (hist, label, n, mean, sqrt(var), m);
+}
+
 
+/* This function is deprecated.  Don't use it in new code */
 void
-histogram_plot(const gsl_histogram *hist,
-              const char *factorname,
-              const struct normal_curve *norm, short show_normal)
+histogram_plot_n (const struct histogram *hist,
+                 const char *label,
+                 double n, double mean, double stddev,
+                 bool show_normal)
 {
   int i;
   int bins;
 
-  struct chart *ch;
+  struct chart *ch = chart_create ();
 
-  ch = chart_create();
-  chart_write_title(ch, _("HISTOGRAM"));
+  chart_write_title (ch, _("HISTOGRAM"));
 
-  chart_write_ylabel(ch, _("Frequency"));
-  chart_write_xlabel(ch, factorname);
+  chart_write_ylabel (ch, _("Frequency"));
+  chart_write_xlabel (ch, label);
 
   if ( ! hist ) /* If this happens, probably all values are SYSMIS */
     {
-      chart_submit(ch);
-      return ;
+      chart_submit (ch);
+      return;
     }
   else
     {
-      bins = gsl_histogram_bins(hist);
+      bins = gsl_histogram_bins (hist->gsl_hist);
     }
 
-  chart_write_yscale(ch, 0, gsl_histogram_max_val(hist), 5);
+  chart_write_yscale (ch, 0, gsl_histogram_max_val (hist->gsl_hist), 5);
 
   for ( i = 0 ; i < bins ; ++i )
-      hist_draw_bar(ch, hist, i);
+    hist_draw_bar (ch, hist, i);
 
-  histogram_write_legend(ch, norm);
+  histogram_write_legend (ch, n, mean, stddev);
 
-  if ( show_normal  )
-  {
-    /* Draw the normal curve */
-
-    double d ;
-    double x_min, x_max, not_used ;
-    double abscissa_scale ;
-    double ordinate_scale ;
-    double range ;
-
-    gsl_histogram_get_range(hist, 0, &x_min, &not_used);
-    range = not_used - x_min;
-    gsl_histogram_get_range(hist, bins - 1, &not_used, &x_max);
-
-    abscissa_scale = (ch->data_right - ch->data_left) / (x_max - x_min);
-    ordinate_scale = (ch->data_top - ch->data_bottom) /
-      gsl_histogram_max_val(hist) ;
-
-    pl_move_r(ch->lp, ch->data_left, ch->data_bottom);
-    for( d = ch->data_left;
-        d <= ch->data_right ;
-        d += (ch->data_right - ch->data_left) / 100.0)
-      {
-       const double x = (d - ch->data_left) / abscissa_scale + x_min ;
-       const double y = norm->N * range *
-         gsl_ran_gaussian_pdf(x - norm->mean, norm->stddev);
-
-       pl_fcont_r(ch->lp,  d,  ch->data_bottom  + y * ordinate_scale);
-
-      }
-    pl_endpath_r(ch->lp);
+  if (show_normal)
+    {
+      /* Draw the normal curve */
+
+      double d ;
+      double x_min, x_max, not_used ;
+      double abscissa_scale ;
+      double ordinate_scale ;
+      double range ;
+
+      gsl_histogram_get_range (hist->gsl_hist, 0, &x_min, &not_used);
+      range = not_used - x_min;
+      gsl_histogram_get_range (hist->gsl_hist, bins - 1, &not_used, &x_max);
+
+      abscissa_scale = (ch->data_right - ch->data_left) / (x_max - x_min);
+      ordinate_scale = (ch->data_top - ch->data_bottom) /
+       gsl_histogram_max_val (hist->gsl_hist) ;
+
+      pl_move_r (ch->lp, ch->data_left, ch->data_bottom);
+      for ( d = ch->data_left;
+           d <= ch->data_right ;
+           d += (ch->data_right - ch->data_left) / 100.0)
+       {
+         const double x = (d - ch->data_left) / abscissa_scale + x_min ;
+         const double y = n * range *
+           gsl_ran_gaussian_pdf (x - mean, stddev);
+
+         pl_fcont_r (ch->lp,  d,  ch->data_bottom  + y * ordinate_scale);
+
+       }
+      pl_endpath_r (ch->lp);
+    }
 
-  }
-  chart_submit(ch);
+  chart_submit (ch);
 }
 
+
index c808cb4e57fd6fe865cad87f5e9ca573f339b038..606206d5012c47d4e7b239e0a0230bf1788cea8e 100644 (file)
 #ifndef PLOT_HIST_H
 #define PLOT_HIST_H
 
-#include <gsl/gsl_histogram.h>
+#include <stdbool.h>
 
-
-struct normal_curve
-{
-  double N ;
-  double mean ;
-  double stddev ;
-};
 struct chart;
+struct moments1;
+struct histogram;
+
+/* Plot M onto histogram HIST and label it with LABEL */
+void histogram_plot (const struct histogram *hist,
+                    const char *label,  const struct moments1 *m);
 
-/* Write the legend of the chart */
-void histogram_write_legend(struct chart *ch, const struct normal_curve *norm);
 
-void histogram_plot(const gsl_histogram *hist,
-              const char *factorname,
-              const struct normal_curve *norm, short show_normal);
+/* A wrapper aroud histogram_plot.
+   Don't use this function.  It's legacy only */
+void histogram_plot_n (const struct histogram *hist,
+                      const char *label,
+                      double n, double mean, double var,
+                      bool show_normal);
 
 
 #endif
index 6d4ff9310060800e270b9a76d41cc329169848bd..7758ad709cb1a8f3bc7ff4c9c8f221fb805eefdd 100644 (file)
@@ -38,6 +38,6 @@ chart_init_separate (struct chart *ch UNUSED, const char *type UNUSED,
 }
 
 void
-chart_finalise_separate (struct chart *ch)
+chart_finalise_separate (struct chart *ch UNUSED)
 {
 }
diff --git a/src/ui/ChangeLog b/src/ui/ChangeLog
deleted file mode 100644 (file)
index bc9c192..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6427.  Reviewed by John Darrington.
-
-       * automake.mk: Add new files.
-
-       * syntax-gen.c: New file.  Based on former
-       src/libpspp/syntax-gen.c but rewritten.
-
-       * syntax-gen.h: New file.  Based on former
-       src/libpspp/syntax-gen.h but rewritten.
-
-2007-10-10  Ben Pfaff  <blp@gnu.org>
-
-       * src/ui/debugger.c: Use debugger if HAVE_FORK is defined, not
-       HAVE_SYS_TYPES_H.  The latter is almost universal, but the former
-       is only available where it can be implemented.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-       
-       * automake.mk: Remove files.
-
-       * flexifile.c: Removed, dead code.
-       * flexifile.h: Ditto.
-
-Thu Feb  8 06:34:52 2007  Ben Pfaff  <blp@gnu.org>
-
-       * [!(HAVE_SYS_TYPES_H && HAVE_SYS_WAIT_H)] (connect_debugger) In
-       this case, we don't know how to connect to GDB, so just return.
-
-Mon Jan 15 11:06:31 2007  Ben Pfaff  <blp@gnu.org>
-
-       * flexifile.c [DEBUGGING] (dump_case_data): Use case accessor
-       functions.
-       
-Wed Dec 20 21:14:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * flexifile.c (flexifilereader_cnum) : new function
-
-Thu Nov 16 20:44:58 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * debugger.c debugger.h New files.
-
-Mon Jul 17 18:22:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * flexifile.c flexifile.h: New files. Implementations of casefiles.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/ui/OChangeLog b/src/ui/OChangeLog
new file mode 100644 (file)
index 0000000..bc9c192
--- /dev/null
@@ -0,0 +1,53 @@
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6427.  Reviewed by John Darrington.
+
+       * automake.mk: Add new files.
+
+       * syntax-gen.c: New file.  Based on former
+       src/libpspp/syntax-gen.c but rewritten.
+
+       * syntax-gen.h: New file.  Based on former
+       src/libpspp/syntax-gen.h but rewritten.
+
+2007-10-10  Ben Pfaff  <blp@gnu.org>
+
+       * src/ui/debugger.c: Use debugger if HAVE_FORK is defined, not
+       HAVE_SYS_TYPES_H.  The latter is almost universal, but the former
+       is only available where it can be implemented.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+       
+       * automake.mk: Remove files.
+
+       * flexifile.c: Removed, dead code.
+       * flexifile.h: Ditto.
+
+Thu Feb  8 06:34:52 2007  Ben Pfaff  <blp@gnu.org>
+
+       * [!(HAVE_SYS_TYPES_H && HAVE_SYS_WAIT_H)] (connect_debugger) In
+       this case, we don't know how to connect to GDB, so just return.
+
+Mon Jan 15 11:06:31 2007  Ben Pfaff  <blp@gnu.org>
+
+       * flexifile.c [DEBUGGING] (dump_case_data): Use case accessor
+       functions.
+       
+Wed Dec 20 21:14:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * flexifile.c (flexifilereader_cnum) : new function
+
+Thu Nov 16 20:44:58 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * debugger.c debugger.h New files.
+
+Mon Jul 17 18:22:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * flexifile.c flexifile.h: New files. Implementations of casefiles.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index 18b6914801fb058dae2555a6a07358e6db76ff38..c21b681d1f289f980e8bbcd274c2743726c73275 100644 (file)
@@ -6,10 +6,12 @@ include $(top_srcdir)/src/ui/gui/automake.mk
 endif
 
 
-noinst_LIBRARIES += src/ui/libuicommon.a
+noinst_LTLIBRARIES += src/ui/libuicommon.la
 
-src_ui_libuicommon_a_SOURCES = \
-       src/ui/debugger.c \
-       src/ui/debugger.h \
-       src/ui/syntax-gen.c \
-       src/ui/syntax-gen.h
+src_ui_libuicommon_la_SOURCES = \
+       src/ui/command-line.c src/ui/command-line.h \
+       src/ui/debugger.c src/ui/debugger.h \
+       src/ui/source-init-opts.c src/ui/source-init-opts.h \
+       src/ui/syntax-gen.c src/ui/syntax-gen.h
+
+EXTRA_DIST += src/ui/OChangeLog
diff --git a/src/ui/command-line.c b/src/ui/command-line.c
new file mode 100644 (file)
index 0000000..46dddd4
--- /dev/null
@@ -0,0 +1,166 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#include <config.h>
+#include "command-line.h"
+#include <argp.h>
+#include <gl/xalloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libpspp/compiler.h>
+#include <assert.h>
+
+
+struct clp_child
+{
+  void *aux;
+};
+
+struct command_line_processor
+{
+  struct argp master_parser;
+
+  struct clp_child *child_lookup_table;
+  struct argp_child *children;
+  int n_children;
+
+  const char *doc;
+  const char *args_doc;
+
+  void *aux;
+};
+
+
+/* Convenience function for use in parsing functions.
+   Returns the object for this parser */
+struct command_line_processor *
+get_subject (struct argp_state *state)
+{
+  const struct argp *root = state->root_argp;
+
+  const struct argp_child *children = root->children;
+
+  return  (struct command_line_processor *) children[0].argp;
+}
+
+
+/* Create a command line processor.
+   DOC is typically the name of the program and short description.
+   ARGS_DOC is a short description of the non option arguments.
+   AUX is an arbitrary pointer.
+ */
+struct command_line_processor *
+command_line_processor_create (const char *doc, const char *args_doc, void *aux)
+{
+  struct command_line_processor *clp = xzalloc (sizeof (*clp));
+
+  clp->children = NULL;
+  clp->child_lookup_table = NULL;
+
+  clp->doc = doc;
+  clp->args_doc = args_doc;
+  clp->aux = aux;
+
+  return clp;
+}
+
+/* Destroy a command line processor */
+void
+command_line_processor_destroy (struct command_line_processor *clp)
+{
+  free (clp->children);
+  free (clp->child_lookup_table);
+  free (clp);
+}
+
+
+/* Add a CHILD to the processor CLP, with the doc string DOC.
+   AUX is an auxilliary pointer, specific to CHILD.
+   If AUX is not known or not needed then it may be set to NULL
+*/
+void
+command_line_processor_add_options (struct command_line_processor *clp, const struct argp *child,
+                              const char *doc, void *aux)
+{
+  clp->n_children++;
+
+  clp->children = xrealloc (clp->children, (clp->n_children + 1) * sizeof (*clp->children));
+  memset (&clp->children[clp->n_children - 1], 0, sizeof (*clp->children));
+
+  clp->child_lookup_table = xrealloc (clp->child_lookup_table,
+                                     clp->n_children * sizeof (*clp->child_lookup_table));
+
+  clp->child_lookup_table [clp->n_children - 1].aux = aux;
+
+  clp->children [clp->n_children - 1].argp = child;
+  clp->children [clp->n_children - 1].header = doc;
+  clp->children [clp->n_children].argp = NULL;
+}
+
+
+/* Set the aux paramter for CHILD in CLP to AUX.
+   Any previous value will be overwritten.
+ */
+void
+command_line_processor_replace_aux (struct command_line_processor *clp, const struct argp *child, void *aux)
+{
+  int i;
+  for (i = 0 ; i < clp->n_children; ++i )
+    {
+      if (child->options == clp->children[i].argp->options)
+       {
+         clp->child_lookup_table[i].aux = aux;
+         break;
+       }
+    }
+  assert (i < clp->n_children);
+}
+
+
+static error_t
+top_level_parser (int key UNUSED, char *arg UNUSED, struct argp_state *state)
+{
+  int i;
+  struct command_line_processor *clp = state->input;
+
+  if ( key == ARGP_KEY_INIT)
+    {
+
+      for (i = 0;  i < clp->n_children ; ++i)
+       {
+         state->child_inputs[i] = clp->child_lookup_table[i].aux;
+       }
+    }
+
+  return ARGP_ERR_UNKNOWN;
+}
+
+
+/* Parse the command line specified by (ARGC, ARGV) using CLP */
+void
+command_line_processor_parse (struct command_line_processor *clp, int argc, char **argv)
+{
+  clp->master_parser.parser = top_level_parser;
+  clp->master_parser.args_doc = clp->args_doc;
+
+  clp->master_parser.doc = clp->doc;
+
+  clp->master_parser.children = clp->children;
+
+  argp_parse (&clp->master_parser, argc, argv, 0, 0, clp);
+}
+
diff --git a/src/ui/command-line.h b/src/ui/command-line.h
new file mode 100644 (file)
index 0000000..98edbea
--- /dev/null
@@ -0,0 +1,36 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SRC_UI_COMMAND_LINE_H
+#define SRC_UI_COMMAND_LINE_H
+
+#include <argp.h>
+
+struct command_line_processor;
+
+struct command_line_processor * get_subject (struct argp_state *state);
+
+struct command_line_processor *command_line_processor_create (const char *, const char *, void *);
+
+void command_line_processor_add_options (struct command_line_processor *cla, const struct argp *child, const char *doc, void *aux);
+
+void command_line_processor_replace_aux (struct command_line_processor *cla, const struct argp *child, void *aux);
+
+void command_line_processor_destroy (struct command_line_processor *);
+
+void command_line_processor_parse (struct command_line_processor *, int argc, char **argv);
+
+#endif
diff --git a/src/ui/gui/ChangeLog b/src/ui/gui/ChangeLog
deleted file mode 100644 (file)
index 88a42f1..0000000
+++ /dev/null
@@ -1,1117 +0,0 @@
-2008-05-20  John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk: Added the -no-undefined flag so that dlls can be built
-       on w32 platforms.  Abstracted the dependencies of glade-register.c
-       into a new shared library libpsppwidgets.so, which can be either
-       linked directly by psppire or by libpsppire.so
-
-       * psppire-keypad.c: Changed snprintf to g_snprintf so as not to use
-       gnulib.
-
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Rename install-data-hook to yelp-check and mark it
-       phony.  This avoids an automake warning for duplicate
-       install-data-hook commands in doc/automake.mk and this file
-       (automake does not understand double-colon rules, since they are
-       not in POSIX).
-
-2008-05-09  John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk: On make install, warn about the non-existance of yelp.
-
-2008-05-08  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6505.  Reviewed by John Darrington.
-
-       * text-data-import-dialog.c: Don't make the user wiggle the mouse
-       to be able to click on the Forward button twice in quick
-       succession.
-       (add_page_to_assistant): Mark pages in the assistant complete
-       immediately.
-       (on_prepare): No longer mark pages complete upon first visit.
-
-2008-05-08  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6505.  Reviewed by John Darrington.
-
-       * text-data-import-dialog.c: (struct assistant) New member
-       `watch_cursor'.
-       (revise_fields_preview): Change the mouse pointer to a watch to
-       indicate that a long operation is ongoing.
-       (prepare_formats_page): Ditto.
-       (on_variable_change): Ditto.
-       (push_watch_cursor): New function.
-       (pop_watch_cursor): New function.
-
-2008-05-08  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c: In popup menus, connect the Insert Variable and
-       Insert Case callbacks manually, instead of relying on
-       gtk_action_connect_proxy, as the latter connects a label with a
-       mnemonic which is inappropriate.
-
-2008-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Bug #23127.  Reviewed by John Darrington.  Tested by Jason Stover,
-       in an earlier form.
-
-       * text-data-import-dialog.c (get_tooltip_location): Prevent crash
-       when a tooltip is being prepared when the assistant is closed.
-
-2008-05-06  Ben Pfaff  <blp@gnu.org>
-
-       * text-data-import-dialog.c (text_data_import_assistant): Allocate
-       the struct import_assistant on the heap instead of the stack, to
-       make it easier for memory debuggers such as Valgrind to point out
-       use of its members after this function returns.
-
-2008-03-25  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.glade: Removed unused menuitems.
-
-       * data-editor.c data-editor.glade: Added Mnemonics to all menuitems.
-
-2008-03-16  Ben Pfaff  <blp@gnu.org>
-
-       Patch #5368.  Reviewed by John Darrington.  Tested by Jason
-       Stover.
-
-       * automake.mk: Add new files.
-
-       * data-editor.glade: Add "import delimited text data" menu item.
-
-       * data-editor.c: Connect "import delimited text data" menu item.
-
-       * text-data-import-dialog.c: New file.
-
-       * text-data-import-dialog.h: New file.
-
-       * text-data-import.glade: New file.
-
-2008-03-07  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-var-sheet.c: Initialize "may-create-vars" to TRUE by
-       default.
-
-2008-03-06  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-var-sheet.c psppire-var-sheet.h: Add "may-create-vars"
-       property to var sheet that controls whether the user can create
-       new variables in the dictionary.  Needed by upcoming patch #6358.
-       Reviewed by John Darrington.
-
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6427.  Reviewed by John Darrington.
-
-       * comments-dialog.c: Adapt to new syntax generating code in
-       ui/syntax-gen.[ch].
-
-       * data-editor.c: Ditto.
-
-       * recode-dialog.c: Ditto.
-
-       * t-test-independent-samples-dialog.c: Ditto.
-
-2008-02-29  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-data-editor.c psppire-data-editor.h: New files.  Contains functionality
-       previously scattered thoughout data-editor.c and elsewhere.
-
-       * data-editor.c data-editor.h: Abstracted the variable sheet, the data sheet and
-       their containing GtkNotebook into a new Object.
-
-       * data-sheet.c data-sheet.h: Deleted.
-
-       * var-sheet.c var-sheet.h: Deleted.  Moved to psppire-var-sheet.[ch]
-
-       * psppire-var-sheet.c psppire-var-sheet.h: New files.
-       
-       * clipboard.c clipboard.h: Deleted.  Moved to psppire-data-editor.c
-
-       * psppire-var-store.c psppire-var-store.h: Updated symbols to avoid name clashes.
-       
-       * comments-dialog.c compute-dialog.c crosstabs-dialog.c descriptives-dialog.c
-       examine-dialog.c find-dialog.c frequencies-dialog.c goto-case-dialog.c
-       oneway-anova-dialog.c rank-dialog.c recode-dialog.c select-cases-dialog.c
-       sort-cases-dialog.c split-file-dialog.c t-test-independent-samples-dialog.c
-       transpose-dialog.c variable-info-dialog.c weight-cases-dialog.c t-test-one-sample.c
-       t-test-paired-samples.c: Updated dialogs to match above changes.
-
-2008-02-27  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression-dialog.c: New file.
-
-       * regression-dialog.h: New file.
-
-       * regression.glade: New file.
-
-2008-02-19  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6426.  Reviewed by John Darrington.
-       
-       * psppire-var-store.c: Add "trailing-rows", "format-type"
-       properties to PsppireVarStore.
-
-2008-02-19  Ben Pfaff  <blp@gnu.org>
-
-       * message-dialog.c (popup_messages): Always destroy `msg' and
-       `lead' strings, avoiding a memory leak.  Thanks to John Darrington
-       for reporting the problem.
-
-2008-02-19  John Darrington <john@darrington.wattle.id.au>
-
-       * dict-display.c: Display names of variables in dialog box
-       dictionary treeviews, when the mouse hovers over the variable.
-
-2008-02-13  John Darrington <john@darrington.wattle.id.au>
-
-       * variable-info-dialog.c: Fix crash when clicking "Jump" when no 
-       variable selected.  Add a valid predicate so that this can't 
-       happen anyway.
-
-       * compute-dialog.c: Fix crash when trying to set label on non
-       existant variable.
-
-2008-02-09  Ben Pfaff  <blp@gnu.org>
-
-       Consolidate multiple messages into single message dialog.  Patch
-       #6405.  Thanks to John Darrington for review.
-
-       * automake.mk (dist_src_ui_gui_psppire_DATA): Add
-       message-dialog.glade.
-
-       * helper.c (give_help): Use GtkMessageDialog directly instead of
-       trying to reuse message-dialog code.
-
-       * message-dialog.c: Rewritten.
-
-       * message-dialog.glade: New file.
-
-2008-02-08  Jason Stover  <jhs@math.gcsu.edu>
-
-       * crosstabs-dialog.c: New file.
-
-       * crosstabs-dialog.h: New file.
-
-       * crosstabs.glade: New file.
-
-2008-02-08  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-data-store.c: Remove feature which automatically inserts
-       cases at end of data.
-
-       * datasheet.c: Make rows after the last + 1, not editable.
-
-2008-02-08  John Darrington <john@darrington.wattle.id.au>
-
-       * sort-cases-dialog.c transpose-dialog.c: Added dialog_valid
-       predicates.
-
-2008-02-04  John Darrington <john@darrington.wattle.id.au>
-
-       * checkbox-treeview.c: In toggle callback, use the treeview's 
-       current model, instead of relying on the one set at creation.
-       Use attributes instead of cell_renderer functions.
-
-2008-02-03  John Darrington <john@darrington.wattle.id.au>
-
-        * psppire-case-file.c psppire-case-file.h: Dont clone the casereader
-       before creating datasheet.  Add properties instead of direct code 
-        in _new function.
-
-        * psppire-data-store.c:  Implement proper dispose function.
-
-2008-01-29  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-var-ptr.c psppire-var-ptr.h: New files
-
-       * t-test-paired-samples.c t-test-paired-samples.h: New files
-
-        * dialog-common.c dialog-common.h (append_variable_names): Add extra 
-       argument to specify the column number containing the variables.
-
-       * psppire-selector.c psppire-selector.h:  Add auxilliary data variable
-       to SelectItemsFunc.  (is_item_in_dest) transform model value to G_TYPE_INT
-       before using.  Hence the model need not be of integer type.
-
-2008-01-22  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-dict.c (psppire_dict_rename_var): Fixed bug where
-       an assertion failure occured when renaming variables to an
-       existing name. Thanks to Ben for reporting this.
-
-2007-12-13  John Darrington <john@darrington.wattle.id.au>
-
-       * dialog-common.c dialog-common.h (numeric_only): New function.
-
-       * t-test-independent-samples-dialog.c:  Added the ability to specify 
-       groups by a threshold ("Cut Point").  Keep OK/Paste buttons insensitive,
-       until groups are properly defined.  Prevented variables treeview from
-       accepting string variables.
-
-2007-12-08  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.h data-editor.c: Added hooks for one sample t-test
-
-       * t-test-one-sample.c t-test-one-sample.h (new files): Implemented
-       a dialog box for the One Sample T Test.
-
-       * t-test-independent-samples-dialog.c: Factored out the options sub
-       dialog (see following).
-
-       * t-test-options.c t-test-options.h (new files):  New module
-        implementing the options sub-dialog for T tests.
-
-2007-12-07  John Darrington <john@darrington.wattle.id.au>
-
-       * frequencies-dialog.c: Made the options subdialog transient
-       on the parent.
-
-2007-12-01  John Darrington <john@darrington.wattle.id.au>
-
-       * descriptives-dialog.c: Moved the code dealing with checkboxes 
-       inside treeview widgets into their own files.
-
-       * checkbox-treeview.c checkbox-treeview.h: New file (see above).
-
-       * frequencies-dialog.c frequencies-dialog.h frequencies.glade: New 
-       files. Implemented FREQUENCIES dialog box.
-
-       * data-editor.c data-editor.h data-editor.glade :  Added callback
-       for frequencies dialog.
-
-
-2007-11-23  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-acr.c psppire-acr.h: Generalised the external widget
-       somewhat. It can now be anything, not necessarily a GTK_ENTRY.
-
-       * helper.c helper.h (clone_list_store): New function.
-
-       * oneway-anova-dialog.c : Used the clone_list_store function
-       instead of writing it ourselves.
-       
-       * psppire-dialog.c psppire-dialog.h: Added a tabular orientation
-       in addition to the horizontal/vertical options.
-       
-       * recode-dialog.c recode-dialog.h recode.glade (new files).
-
-       * psppire-selector.c psppire-selector.h: Added a function to
-       allow the prohibition of items based on a predicate.
-
-       * dialog-common.h dialog-common.c (homogeneous_types): New function.
-
-       * data-editor.c data-editor.glade data-editor.h: Enabled the
-       recode dialog options.
-
-
-2007-11-23  John Darrington <john@darrington.wattle.id.au>
-
-       * compute-dialog.c (generate_syntax): Append "EXECUTE." to the 
-       generated syntax.
-
-2007-10-19  John Darrington <john@darrington.wattle.id.au>
-
-        * psppire-acr.c psppire-acr.h (new files): Added this new
-       composite widget.
-
-       * data-editor.c data-editor.h: Added entries for ONEWAY command
-       dialog box.
-
-       * oneway-anova-dialog.c oneway-anova-dialog.h oneway.glade (new files)
-       
-2007-10-06  John Darrington <john@darrington.wattle.id.au>
-       
-       * psppire-dialog.c psppire-dialog.h: Added a predicate function
-       member to indicate when a dialog's state is (not) valid. Added a
-       signal "validity-changed" which gets emitted whenever this
-       predicate changes. 
-
-       * psppire-buttonbox.c: Connect to the toplevel window's
-       "validity-changed" signal (assuming it happens to be a
-       PsppireDialog) and set the OK, PASTE, GOTO and CONTINUE buttons
-       according.y. 
-
-       * descriptives-dialog.c compute-dialog.c: Add a validity predicate.
-
-2007-10-05  Ben Pfaff  <blp@gnu.org>
-
-       Add DESCRIPTIVES dialog.
-       
-       * automake.mk (dist_src_ui_gui_psppire_DATA): Add
-       descriptives-dialog.data.
-       (src_ui_gui_psppire_SOURCES): Add descriptives-dialog.c,
-       descriptives-dialog.h.
-
-       * data-editor.c (new_data_editor): Connect descriptive dialog to
-       action.
-
-       * data-editor.glade: Change menu item to invoke DESCRIPTIVES.
-
-       * descriptives-dialog.c: New file.
-       
-       * descriptives-dialog.h: New file.
-       
-       * descriptives-dialog.glade: New file.
-
-2007-10-04  John Darrington <john@darrington.wattle.id.au>
-
-       * compute-dialog.c goto-case-dialog.c main.c psppire-keypad.c: Added 
-       #include <config.h>
-
-       * psppire.glade about.c: Read GPL text from src/libpspp/copyleft.c 
-       instead of makeing another copy in psppire.glade.
-
-       * psppirebuttonbox.c psppire.c: Create a new stock item for 
-       RESET buttons.
-       
-2007-09-26  John Darrington <john@darrington.wattle.id.au>     
-       
-       * output-viewer.c output-viewer.h psppire.c: (closes patch #6210) 
-       Changed width and length parameters of output driver to
-       "auto". Changed default width and length  to be something
-       acceptable to the ascii driver.  (reload_viewer) Dynamically
-       allocate the line buffer so that it matches the width of the output.
-       
-2007-09-24  Ben Pfaff  <blp@gnu.org>
-
-       * message-dialog.c (popup_message): Refer to files that contain
-       commands as "syntax" files, not "script" files, for better user
-       familiarity.
-       Patch #6210.  Reviewed by John Darrington.
-
-2007-09-19  John Darrington <john@darrington.wattle.id.au>
-       
-       * message-dialog.c: Changed the ouput message title to be 
-       appropriate for the severity of the message.
-
-       * output-viewer.c output-viewer.h : Added a callback for the resize 
-       signal of the output viewer, and set the viewport length and
-       width accordingly.
-
-       * psppire.c: Update to new init_settings interface.
-
-2007-09-27  John Darrington <john@darrington.wattle.id.au>
-
-       Addressing bug #20821:
-       
-       * psppire-dict.c: Added a BACKEND_CHANGED signal to indicate when 
-       a PsppireDict's struct dictionary has been replaced.
-
-       * psppire-var-store.c: Added the appropriate method for 
-       get_column_count. Added a signal handler for dict:BACKEND_CHANGED, 
-       which calls the g_sheet_model_range_changed for the entire sheet.
-       
-2007-09-18  Ben Pfaff  <blp@gnu.org>
-
-       * helper.c (create_casereader_from_data_store): New function.
-       (execute_syntax): Only replace the active file data by a new
-       casereader if syntax caused the active file to be read, to avoid
-       exponential slowdown as an increasing number of snippets that do
-       not read from the active file are consecutively executed.  Bug
-       #20910.  Reviewed by and heavily influenced by John Darrington.
-
-       * psppire-data-store.c (psppire_data_store_get_value_count): New
-       function.
-
-       * psppire-dict.c (psppire_dict_get_value_cnt): New function.
-
-2007-09-13  John Darrington <john@darrington.wattle.id.au>
-
-       * find-dialog.c find-dialog.h: New files.
-
-       * data-editor.c data-editor.h data-editor.glade: Added action for
-       the find dialog.
-
-       * psppire-selector.c: Emit the (de)selected signal when the 
-       destination entry widget's text changes.
-
-2007-09-10  Ben Pfaff  <blp@gnu.org>
-
-       * var-sheet.c (psppire_variable_sheet_create): Use xstrdup to save
-       string returned by bind_textdomain_codeset.  Otherwise it can get
-       freed by a subsequent call.  Patch #6193.  Reviewed by John
-       Darrington.
-
-2007-09-06  John Darrington <john@darrington.wattle.id.au>
-       
-       * helper.c helper.h (execute_syntax): changed return type to 
-       gboolean to indicated if all the syntax executed successfully or not.
-
-       * data-editor.c syntax-editor.c: Fixed update of recent file list
-       and window title,  on data_file_open.  They now only change, if
-       the file_open was  successfull. 
-
-
-2007-08-25  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire.c : Enable journal.
-
-2007-08-18  John Darrington <john@darrington.wattle.id.au>
-
-       * clipboard.c clipboard.h data-editor.c: Added the ability to paste from 
-       the clipboard into the data sheet.
-
-2007-08-16  John Darrington <john@darrington.wattle.id.au>
-
-        * output-viewer.c output-viewer.h output-viewer.glade (new files)
-         helper.c psppire.c syntax-editor.glade window-manager.c 
-         window-manager.h : Added a basic output viewer window.
-
-2007-08-13  John Darrington <john@darrington.wattle.id.au>
-
-       * clipboard.c (clip_to_html clip_to_text): Fixed bug --- use the
-       variable count instead of the value count for the columns limit. 
-
-2007-08-12  John Darrington <john@darrington.wattle.id.au>
-           Ben Pfaff  <blp@gnu.org>
-
-       Implement Edit|Cut operation for datasheet.  Patch #6117.
-
-       * automake.mk: Add clipboard.c, clipboard.h.
-
-       * clipboard.c: New file.
-
-       * clipboard.h: New file.
-
-       * data-editor.c (new_data_editor): Connect Edit|Copy to
-       on_edit_copy function.
-       (data_var_select): Enable or disable Edit|Copy as appropriate.
-       (on_edit_copy): New function.
-
-       * data-editor.glade: Connect menu items to new operations.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-dict.c (psppire_dict_dump): Don't use
-       dict_get_compacted_dict_index_to_case_index, as that function has
-       been deleted.
-
-2007-08-13  John Darrington <john@darrington.wattle.id.au>
-
-        * psppire-case-file.c (psppire_case_file_append_case):
-       Deleted unused function.
-
-2007-08-07  John Darrington <john@darrington.wattle.id.au>
-
-       * helper.c (execute_syntax): Set the active file data to NULL at the
-       end of the procedure.  Thanks to Ben for suggesting this.
-
-       * psppire-case-file.c: Added assertions to the remaining functions
-       on inaccessible objects.
-
-       * psppire-data-store.c psppire-data-store.h: Disconnect or block
-       signals on dictionary and case_file, when make_reader has been called.
-       Reconnect or unblock them when a new datasheet has been set for the
-       data_store.
-
-2007-08-06  John Darrington <john@darrington.wattle.id.au>
-
-       * syntax-editor.glade: Changed some properties to be less annoying.
-
-2007-07-29  John Darrington <john@darrington.wattle.id.au>
-
-       * helper.c psppire.c: Enabled the output system so that the results
-       of analysis can be seen.
-
-2007-07-26  John Darrington <john@darrington.wattle.id.au>
-
-       * helper.c helper.h (execute_syntax): removed implicit EXECUTE at end
-       of commands.
-
-       * data-editor.c data-editor.glade: Added "Run Pending Transformations"
-       menuitem.
-
-2007-07-25  John Darrington <john@darrington.wattle.id.au>
-
-       * customentry.c: Redraw button in insensitive state, if the widget's
-        "editable" style is FALSE.  Don't emit the "clicked" signal if
-        "editable" is FALSE.
-
-       * var-sheet.c: If variables are long-string variables, then set the
-       "editable" properties of the entry widgets for the values and missing
-       cells to FALSE,
-
-2007-07-18  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-case-file.c psppire-case-file.h psppire-data-store.c
-       psppire-dict.c psppire-dict.h psppire-var-store.c : Added the
-       ability to resize string variables.  Fixed associated problems
-       inserting/deleting variables.
-
-       * helper.c helper.h (marshaller_VOID__INT_INT_INT): New marshaller
-       function.
-
-2007-07-16  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c: File Open dialog remembers directory.  Thanks to
-       Ben Pfaff for this suggestion.
-
-2007-07-15  John Darrington <john@darrington.wattle.id.au>
-
-       * compute-dialog.c: Only generate NUMERIC/STRING command if the
-       type-and-label dialog was used.
-
-2007-07-12  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-data-store.c: Added call to g_sheet_model_range_changed to
-       ensure that datasheet displays the current store.
-
-       * psppire-data-store.h: Formatting tidy up.
-
-2007-07-11  John Darrington <john@darrington.wattle.id.au>
-
-       * compute-dialog.c : Set type-and-label dialog to sensible state,               and made syntax generation depend upon existence of target variable.
-
-2007-07-08  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-editor.glade data-editor.h: Implemented
-       the "Insert Case" button/dialog.
-
-2007-07-08  John Darrington <john@darrington.wattle.id.au>
-
-       * goto-case-dialog.c goto-case-dialog.h (new files)
-       * automake.mk data-editor.c data-editor.glade data-editor.h
-       psppire-case-file.c psppire-case-file.h psppire-data-store.c
-       psppire-data-store.h psppire.glade :  Implemented the goto-case dialog
-
-
-2007-07-07  John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-data-store.c psppire-data-store.h: Made cases number from
-       1 instead of 0.
-
-       * psppire-data-store.c: Added a tooltip like feature to display
-       the label of variables.
-
-2007-07-03  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-sheet.c: Turned off autoscrolling, and
-       manually move to cell on column click instead.
-
-2007-06-29  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-editor.glade psppire-data-store.c
-       psppire-data-store.h: Enabled cell reference entry and datum
-       entry widgets.
-
-2007-06-29  John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-sheet.c: Moved update_cell_ref_entry from
-       data-sheet.c to data-editor.c and made it work again.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-
-       * automake.mk: Removed files.
-
-       * flexifile-factory.c: Removed, dead code.
-       * flexifile-factory.h: Ditto.
-
-       * helper.c: Adapt to new procedure and datasheet code.
-       * missing-val-dialog.c: Ditto.
-       * psppire-case-file.c: Ditto.
-       * psppire-data-store.c: Ditto.
-       * psppire.c: Ditto.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-var-store.c (psppire_var_store_item_editable): Use
-       var_is_alpha.
-
-2007-05-07 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-dialog.c psppire-dialog.h: Added "orientation" property,
-        to allow dialogs to be either vertical or horizontal.
-
-       * comments-dialog.c comments-dialog.h: New files, invoking
-       ADD DOCUMENT cmd.
-
-2007-04-30 John Darrington <john@darrington.wattle.id.au>
-
-       * var-display.c var-display.h variable-info-dialog.c
-       variable-info-dialog.h : New files.
-
-       * data-editor.c :
-
-       * psppire-buttonbox.c psppire-buttonbox.h : Added the "buttons"
-       property, and optional  GOTO and CONTINUE buttons.
-
-       * psppire-dialog.h: Added response codes for the new buttons.
-
-       * psppire-var-store.c : Moved some code to var-display.[ch]
-
-2007-04-25 John Darrington <john@darrington.wattle.id.au>
-
-       * icons/scalable/splash.c icons/splash.png : More eye candy.
-
-       * main.c psppire.h : new files.
-
-       * psppire.c : Seperated the command line parsing and other
-       environment startup from the core psppire code.
-
-2007-04-25 John Darrington <john@darrington.wattle.id.au>
-
-       * icons/scalable icons/16x16: new directories.
-       * psppire.c : Add new icons to factory.
-
-       * dict-display.c: Refactor code get model from modelfilter.
-       Added cellrenderer to display icon indicating variables' types.
-        Displayed the label of variables, if there is one.
-
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * compute-dialog.c (function_list_populate): Use new accessor
-       functions exported by language/expressions/public.h.
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * compute-dialog.c: Make #include for parse.inc work with VPATH
-       builds.
-
-2007-04-13   John Darrington <john@darrington.wattle.id.au>
-
-       * var-type-dialog.c: Added a FMT_DATETIME20 template.
-
-2007-04-04   John Darrington <john@darrington.wattle.id.au>
-
-       * compute-dialog.c compute-dialog.h: New files
-
-       * data-editor.c data-editor.h data-editor.glade : Added Transform
-       menu, and support for Compute dialog
-
-       * glade-register.c psppire-buttonbox.c psppire-buttonbox.h
-         psppire-vbottonbox.c psppire-vbuttonbox.h psppire-hbuttonbox.c
-         psppire-vbuttonbox.h : Made buttonbox an abstract base class
-         and separated it into vbuttonbox and hbuttonbox.
-
-       * psppire-selector.c : Allowed GtkTextView to be the destination
-       widget.
-
-       * psppire-keypad.c: Added an "erase" signal.  Fixed other
-        minor problems.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-           John McCabe-Dansted <gmatht@gmail.com>
-
-       * psppire-selector.c (psppire_selector_set_subjects): Add an
-       assert that may or may not trap some Windows-related bugs.
-
-2007-04-03   John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-editor.glade helper.h syntax-editor.c
-       syntax-editor.h : Implemented the File->Recently_Used_ menus.
-
-
-2007-03-31   John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-editor.glade data-editor.h dialog-common.c
-       psppire-buttonbox.c psppire-dialog.c psppire-dialog.h
-       psppire-selector.c psppire-selector.h psppire.c psppire.glade
-       sort-cases-dialog.c sort-cases-dialog.h split-file-dialog.c
-       transpose-dialog.c weight-cases-dialog.c : Fixed the Refresh
-       button on all the dialogs.
-
-2007-03-31   John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c: Added hooks for the split-file-dialog
-
-       * psppire.glade: Added the split file dialog box.
-
-       * split-file-dialog.c split-file-dialog.h: New files.
-
-       * dialog-common.c dialog-common.h: New files containing functions
-       which seem to be used a lot in dialog box implementations.
-
-       * psppire-keypad.c psppire-keypad.h: New files.  Implements keypad
-       thingumy widget.
-
-       * psppire-selector.c: Made the orientation of the arrow a property
-       of the widget, so that it can be selected from glade.
-
-2007-03-18  Ben Pfaff  <blp@gnu.org>
-
-       * syntax-editor-source.c (close): Rename do_close to avoid naming
-       conflict with POSIX function of same name.
-
-Tue Mar 13 17:20:05 CET 2007 John Darrington <john@darrington.wattle.id.au>
-       * psppire.c:  Changed gtk_init to gtk_parse_args, followed by a delayed         call to gdk_init, so that psppire --version will succeed, even if it
-       cannot connect to a display .
-
-Wed Mar  7 19:05:12 CET 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * var-sheet.c: Replaced call to nl_langinfo with locale_charset
-       from gnulib.
-
-Thu Feb 22 12:27:41 CET 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c : called new gen_quoted_string function to properly
-          quote filenames in generated syntax.
-
-       * window-manager.c : Converted name from filename encoding to UTF8
-          before displaying in title bar.
-
-Tue Jan 30 20:13:46 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-dict.c: Call all the callbacks when a new dictionary becomes current.
-
-       * data-editor.c: Clear existing file name on FILE NEW.
-
-Sat Jan 27 09:48:21 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * var-type-dialog.c: Fixed bugs closing window, apparent when compiled
-       against gtk.2.10
-
-Fri Jan 26 15:51:34 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-var-select.c psppire-var-select.h : Deleted.
-
-       * psppire-selector.c psppire-selector.h : New files.
-
-       * transpose-dialog.c transpose-dialog.h : New files.
-
-       * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel
-       interface functions.
-
-       * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented,
-       using new PsppireSelector widget.
-
-       * dict-display.c dict-display.h : New files.
-
-       * psppire-object.c psppire-object.h : Deleted.  Seemed like a good idea at the time.
-
-Tue Jan 23 21:10:01 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * helper.c helper.h: New function execute_syntax.
-
-       * syntax-editor.c syntax-editor.glade: Disabled data open/save menu
-       items.
-
-       * data-editor.c data-editor.glade data-editor.h: Enabled data
-       open/save/save_as  menu-items.
-
-       * window-manager.h window-manager.c (default_window_name) : New
-       function.
-
-Sat Jan 13 07:47:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-case-file.c psppire-data-store.c psppire-dialog.c
-       psppire-dict.c psppire-var-select.c : Replaced identifier 'signal'
-       with 'signals' to avoid conflict with sysv based systems which use
-       this identifer for something else.
-       Thanks to Daniel E WILLIAMS for reporting this problem.
-
-Wed Jan 10 07:20:39 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-case-file.c : Make sure there is always a valid flexifile
-
-       * psppire-data-store.c : assertions.
-
-       * psppire.c: Ignore replace source callbacks if the new source is
-         not of storiage_source_class
-
-       * syntax-editor.c: Close/Abort source after parsing is complete.
-
-Sun Jan  7 08:38:29 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-dict.c: Add FILTER_CHANGED and SPLIT_CHANGED signals
-       corresponding to the callbacks in src/data/dictionary.c
-
-       * data-editor.c : Connect functions to the FILTER_CHANGED and
-       SPLIT_CHANGED signals to update the status bar accordingly.
-
-Mon Jan  1 10:37:07 WST 2007 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-case-file.c psppire-case-file.h: Changed the backend
-       semantics. An object is now created without any backend.  A new function        ( psppire_case_file_replace_flexifile ) sets the backend to use.
-
-       * psppire-data-store.c : Updated callers accordingly.
-
-       * psppire-dict.c psppire-dict.h : New function
-       (psppire_dict_replace_dictionary) .
-
-       * psppire.c : Updated to use new dataset replace_{source, dictionary}
-       callbacks.
-
-       * syntax-editor.c : parses in state CMD_STATE_DATA unless there are
-       no variables in the dictionary.
-
-Mon Dec 25 12:38:24 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-editor.c data-editor.glade: Enabled deleting of variables from
-       the variable sheet.
-
-Mon Dec 25 11:28:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-dict.c psppire-dict.h: Removed explicit signal emit calls.
-       These are not required, now that src/data/dictionary.c has callbacks
-
-Mon Dec 25 08:49:57 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * var-sheet.c val-labs-dialog.c val-labs-dialog.h: Fixed bug in value
-       labels dialog box.
-
-Sun Dec 17 08:26:10 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * syntax-editor-source.c syntax-editor-source.h syntax-editor.h:
-       New files.
-
-       * message-dialog.c :  Now reports the filename and line number in
-       error messages.
-
-       * psppire.c psppire.glade syntax-editor.c: Added the ability to run
-       syntax from the syntax editor.
-
-
-Sat Dec 16 14:13:07 2006  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-data-store.c (geometry_get_justification): Don't assume
-       that ALIGN_* and GTK_JUSTIFY_* values coincide.
-
-Sat Dec 16 14:10:43 2006  Ben Pfaff  <blp@gnu.org>
-
-       * psppire-var-store.c (text_for_column): Adjust to account for new
-       values of the MEASURE_* enums.
-
-       * var-sheet.c (change_measure): Ditto.
-
-Sat Dec 16 12:24:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-variable.c psppire-variable.h: Deleted.
-
-       * psppire-dict.c psppire-dict.h: Removed the caching of the variable
-           data, which is now unecessary because src/data/vardict.h maintains
-           an association between variables and their dictionary.
-
-       * data-sheet.c menu-actions.c missing-val-dialog.c
-         missing-val-dialog.h psppire-data-store.c
-         psppire-var-store.c psppire-var-store.h
-         sort-cases-dialog.c val-labs-dialog.c val-labs-dialog.h
-         var-sheet.c var-type-dialog.c var-type-dialog.h: Dealt with the
-           consequences of deleting psppire-variable.[ch].
-
-
-Sat Dec  9 20:03:04 2006  Ben Pfaff  <blp@gnu.org>
-
-       * var-type-dialog.c (var_type_dialog_create): Use
-       fmt_dollar_template from data/format.c.
-       (dollar_format_template) Removed.
-
-Sat Dec  9 07:19:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * syntax-editor.c : New file.
-
-Tue Oct 31 19:25:31 2006  Ben Pfaff  <blp@gnu.org>
-
-       * var-type-dialog.c: Add missing "#include <config.h>".
-
-       * psppire.c: Ditto.
-
-Mon Jul 17 18:21:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * automake.mk menu-actions.c psppire-case-file.c psppire-case-file.h
-    psppire-data-store.c psppire-dict.c psppire-dict.h psppire-variable.c
-    psppire.c psppire.glade: Adjusted code to use the new flexifile object.
-
-Sat Jul 15 11:27:15 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * psppire.c psppire.glade automake.mk icons/* : Added toolbar icons where
-       there's no suitable gtk stock icon.
-
-Tue Jul  4 09:08:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * psppire.c: Fixed --help and --version options.
-
-Sat Jun 24 16:56:22 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * menu-actions.c: Added goto case and sort cases dialogs.
-
-   * psppire-case-file.c psppire-case-file.h: Added sort function.
-
-   * psppire-data-store.c psppire-variable.c psppire-variable.h:
-     Renamed  psppire_variable_get_index to psppire_variable_get_fv and
-     dealt with the consequences.  Added a psppire_variable_get_index
-     function which actually does what the name suggests.
-
-   * psppire-dict.c psppire-dict.h: Implemented GtkTreeModel interface,
-     which allows a dictionary to be displayed in a GtkTreeView.
-
-   * psppire.glade: Added dialog boxes for Goto Case and Sort Case.
-
-   * sort-cases-dialog.c sort-cases-dialog.h (new files).
-
-Mon Jun 19 18:10:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * psppire-case-file.c psppire-case-file.h (new files)
-
-   * automake.mk data-sheet.c data-sheet.h menu-actions.c
-   psppire-data-store.c psppire-data-store.h psppire-dict.c
-   psppire-dict.h psppire-var-store.c psppire.c
-
-     Replaced psppire-case-array.c  with psppire-case-file.c, so as to
-     allow an arbitrary number of cases to be represented.
-
-Sun Jun  4 15:50:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * psppire-var-store.c, psppire.c, var-sheet.c :  Unlimited the number of
-   variables that can be displayed. Minor i18n issues.
-
-Tue May 30 19:53:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * menu-actions.c menu-actions.h psppire.c: Fixed up load/new
-   interactions with startup.
-
-   * psppire-data-store.c: Fixed bad i18n call.
-
-   * pspppire-var-store.c, psppire-var-store.h: constness.
-
-   * helper.c: Implemented proper way to convert from PSPP to UTF8 encoding.
-
-
-Sat May 27 16:25:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * customentry.c data-sheet.c menu-actions.c message-dialog.c
-     missing-val-dialog.c psppire-data-store.c psppire-var-store.c
-     psppire.c psppire.glade var-sheet.c: Fixed internationalisation.
-
-Thu May 25 18:01:17 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * psppire-var-store.c: Converted strings to utf8 and returned them on the
-   heap.
-
-Sat May 20 21:08:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-   * data-sheet.c, menu-actions.c menu-actions: Fixed data sheet so that
-   active cell is never on a deleted variable.
-
-   * psppire-data-store.c psppire-data-store.h:  Added get_var_count and
-   get_case_count functions.
-
-   * psppire-dict.c: removed VARIABLE_DELETED (singular) signal.
-
-   * psppire.c: Allowed user to specify *.sav file on command line.
-
-Mon May 15 20:01:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * menu-actions.c psppire-case-array.c psppire-case-array.h
-         psppire-data-store.c  psppire-dict.c psppire-dict.h
-         psppire-variable.c:
-
-         Initialised new cases to SYSMIS/blank when inserting in data sheet.
-
-Sat May 13 08:00:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-sheet.c, helper.c, helper.h, psppire-data-store.c,
-          psppire-var-store.c:
-
-         Set free_strings flag so that the gtksheet frees the string data
-         when it's done with them.
-
-Thu May 11 22:25:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * data-sheet.c helper.c helper.h psppire-data-store.c psppire-var-store.c
-       psppire.c: Converted strings to utf8 before passing to gtksheet.
-
-       * psppire-dict.c: Changed buffer to more reasonable length
-
-       * var-sheet.c: Changed maximum string length to use macro from
-       data/values.h
-
-
-Sun May  7 10:07:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * psppire-data-store.c: Fixed buglet initialising string members.
-
-Thu May  4 18:04:04 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * message-dialog.c message-dialog.h: Added simple queuing to messages
-       reported, and ensure that dialog boxes dont appear when pointer grab
-       is active.
-
-       * psppire-data-store.c: Fix overflow on very long string variables.
-
-       * automake.mk: Fix broken dependency.
-
-
-Tue Apr 25 11:08:04 2006  Ben Pfaff  <blp@gnu.org>
-
-       Finish reforming error message support.  In this phase, move
-       message.c into libpspp.
-
-       * automake.mk: (src_ui_gui_psppire_SOURCES) Remove src/message.c.
-
-Tue Apr 25 10:56:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, drop
-       actual message printing from core code, substituting a callback,
-       and add the callback to each UI.  Also, move verbose_msg() into
-       its own module.
-
-       * automake.mk: (src_ui_gui_psppire_SOURCES) Add src/message.c.
-
-       * message-dialog.c: (message_dialog_init) New function.
-       (vmsg) Rename handle_msg(), rewrite as callback function.
-       (msg) Removed.
-       (msg_emit) Removed.
-       (msg_assert_fail) Removed.
-       (verbose_msg) Removed.
-
-       * psppire.c: (main) Call message_dialog_init().
-
-Sun Apr 23 22:07:49 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, get rid
-       of message "titles" and put the message text in `struct error'.
-       Now `struct error' encapsulates a message more properly.
-
-       * message-dialog.c: (err_vmsg) Rename err_msg().  Updated
-       interface.
-
-Sun Apr 16 20:45:35 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we
-       divide the classification of messages along "category" and
-       "severity" axes.
-
-       * message-dialog.c: (vmsg) Use severity and category in
-       straightforward fashion instead of the less obvious "class".
-       (err_vmsg) Construct class before passing along to vmsg().
-
-Sun Apr 16 16:06:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, we get
-       rid of VM() and the other msg() support for "verbosity", replacing
-       it by a new function verbose_msg().
-
-       * message-dialog.c: (verbose_msg) New function.
-       (err_cond_fail) Removed (dead code).
-       (err_failure) Removed (dead code).
-
-Sun Apr 16 11:53:25 2006  Ben Pfaff  <blp@gnu.org>
-
-       Start reforming error message support.  In this phase, we get rid
-       of "installation errors" and change all uses of msg() in the
-       output drivers to uses of error() or error_at_line().
-
-       * message-dialog.c: (vmsg) Removed IE, IS support.
-
-Mon Mar 13 16:42:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * psppire.c: Supported (sort of) the --help and --version options.
-
-    * Rename error-dialog.[ch] -> message-dialog.[ch]
-
-    * Moved code from the psppire module.
-
-Sat Jan 28 16:22:23 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-    * Separated the data out of the GtkSheet.
-
-Tue Nov  2 19:00:28 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-    * Very first incarnation.
diff --git a/src/ui/gui/OChangeLog b/src/ui/gui/OChangeLog
new file mode 100644 (file)
index 0000000..88a42f1
--- /dev/null
@@ -0,0 +1,1117 @@
+2008-05-20  John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk: Added the -no-undefined flag so that dlls can be built
+       on w32 platforms.  Abstracted the dependencies of glade-register.c
+       into a new shared library libpsppwidgets.so, which can be either
+       linked directly by psppire or by libpsppire.so
+
+       * psppire-keypad.c: Changed snprintf to g_snprintf so as not to use
+       gnulib.
+
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Rename install-data-hook to yelp-check and mark it
+       phony.  This avoids an automake warning for duplicate
+       install-data-hook commands in doc/automake.mk and this file
+       (automake does not understand double-colon rules, since they are
+       not in POSIX).
+
+2008-05-09  John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk: On make install, warn about the non-existance of yelp.
+
+2008-05-08  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6505.  Reviewed by John Darrington.
+
+       * text-data-import-dialog.c: Don't make the user wiggle the mouse
+       to be able to click on the Forward button twice in quick
+       succession.
+       (add_page_to_assistant): Mark pages in the assistant complete
+       immediately.
+       (on_prepare): No longer mark pages complete upon first visit.
+
+2008-05-08  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6505.  Reviewed by John Darrington.
+
+       * text-data-import-dialog.c: (struct assistant) New member
+       `watch_cursor'.
+       (revise_fields_preview): Change the mouse pointer to a watch to
+       indicate that a long operation is ongoing.
+       (prepare_formats_page): Ditto.
+       (on_variable_change): Ditto.
+       (push_watch_cursor): New function.
+       (pop_watch_cursor): New function.
+
+2008-05-08  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c: In popup menus, connect the Insert Variable and
+       Insert Case callbacks manually, instead of relying on
+       gtk_action_connect_proxy, as the latter connects a label with a
+       mnemonic which is inappropriate.
+
+2008-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Bug #23127.  Reviewed by John Darrington.  Tested by Jason Stover,
+       in an earlier form.
+
+       * text-data-import-dialog.c (get_tooltip_location): Prevent crash
+       when a tooltip is being prepared when the assistant is closed.
+
+2008-05-06  Ben Pfaff  <blp@gnu.org>
+
+       * text-data-import-dialog.c (text_data_import_assistant): Allocate
+       the struct import_assistant on the heap instead of the stack, to
+       make it easier for memory debuggers such as Valgrind to point out
+       use of its members after this function returns.
+
+2008-03-25  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.glade: Removed unused menuitems.
+
+       * data-editor.c data-editor.glade: Added Mnemonics to all menuitems.
+
+2008-03-16  Ben Pfaff  <blp@gnu.org>
+
+       Patch #5368.  Reviewed by John Darrington.  Tested by Jason
+       Stover.
+
+       * automake.mk: Add new files.
+
+       * data-editor.glade: Add "import delimited text data" menu item.
+
+       * data-editor.c: Connect "import delimited text data" menu item.
+
+       * text-data-import-dialog.c: New file.
+
+       * text-data-import-dialog.h: New file.
+
+       * text-data-import.glade: New file.
+
+2008-03-07  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-var-sheet.c: Initialize "may-create-vars" to TRUE by
+       default.
+
+2008-03-06  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-var-sheet.c psppire-var-sheet.h: Add "may-create-vars"
+       property to var sheet that controls whether the user can create
+       new variables in the dictionary.  Needed by upcoming patch #6358.
+       Reviewed by John Darrington.
+
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6427.  Reviewed by John Darrington.
+
+       * comments-dialog.c: Adapt to new syntax generating code in
+       ui/syntax-gen.[ch].
+
+       * data-editor.c: Ditto.
+
+       * recode-dialog.c: Ditto.
+
+       * t-test-independent-samples-dialog.c: Ditto.
+
+2008-02-29  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-data-editor.c psppire-data-editor.h: New files.  Contains functionality
+       previously scattered thoughout data-editor.c and elsewhere.
+
+       * data-editor.c data-editor.h: Abstracted the variable sheet, the data sheet and
+       their containing GtkNotebook into a new Object.
+
+       * data-sheet.c data-sheet.h: Deleted.
+
+       * var-sheet.c var-sheet.h: Deleted.  Moved to psppire-var-sheet.[ch]
+
+       * psppire-var-sheet.c psppire-var-sheet.h: New files.
+       
+       * clipboard.c clipboard.h: Deleted.  Moved to psppire-data-editor.c
+
+       * psppire-var-store.c psppire-var-store.h: Updated symbols to avoid name clashes.
+       
+       * comments-dialog.c compute-dialog.c crosstabs-dialog.c descriptives-dialog.c
+       examine-dialog.c find-dialog.c frequencies-dialog.c goto-case-dialog.c
+       oneway-anova-dialog.c rank-dialog.c recode-dialog.c select-cases-dialog.c
+       sort-cases-dialog.c split-file-dialog.c t-test-independent-samples-dialog.c
+       transpose-dialog.c variable-info-dialog.c weight-cases-dialog.c t-test-one-sample.c
+       t-test-paired-samples.c: Updated dialogs to match above changes.
+
+2008-02-27  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression-dialog.c: New file.
+
+       * regression-dialog.h: New file.
+
+       * regression.glade: New file.
+
+2008-02-19  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6426.  Reviewed by John Darrington.
+       
+       * psppire-var-store.c: Add "trailing-rows", "format-type"
+       properties to PsppireVarStore.
+
+2008-02-19  Ben Pfaff  <blp@gnu.org>
+
+       * message-dialog.c (popup_messages): Always destroy `msg' and
+       `lead' strings, avoiding a memory leak.  Thanks to John Darrington
+       for reporting the problem.
+
+2008-02-19  John Darrington <john@darrington.wattle.id.au>
+
+       * dict-display.c: Display names of variables in dialog box
+       dictionary treeviews, when the mouse hovers over the variable.
+
+2008-02-13  John Darrington <john@darrington.wattle.id.au>
+
+       * variable-info-dialog.c: Fix crash when clicking "Jump" when no 
+       variable selected.  Add a valid predicate so that this can't 
+       happen anyway.
+
+       * compute-dialog.c: Fix crash when trying to set label on non
+       existant variable.
+
+2008-02-09  Ben Pfaff  <blp@gnu.org>
+
+       Consolidate multiple messages into single message dialog.  Patch
+       #6405.  Thanks to John Darrington for review.
+
+       * automake.mk (dist_src_ui_gui_psppire_DATA): Add
+       message-dialog.glade.
+
+       * helper.c (give_help): Use GtkMessageDialog directly instead of
+       trying to reuse message-dialog code.
+
+       * message-dialog.c: Rewritten.
+
+       * message-dialog.glade: New file.
+
+2008-02-08  Jason Stover  <jhs@math.gcsu.edu>
+
+       * crosstabs-dialog.c: New file.
+
+       * crosstabs-dialog.h: New file.
+
+       * crosstabs.glade: New file.
+
+2008-02-08  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-data-store.c: Remove feature which automatically inserts
+       cases at end of data.
+
+       * datasheet.c: Make rows after the last + 1, not editable.
+
+2008-02-08  John Darrington <john@darrington.wattle.id.au>
+
+       * sort-cases-dialog.c transpose-dialog.c: Added dialog_valid
+       predicates.
+
+2008-02-04  John Darrington <john@darrington.wattle.id.au>
+
+       * checkbox-treeview.c: In toggle callback, use the treeview's 
+       current model, instead of relying on the one set at creation.
+       Use attributes instead of cell_renderer functions.
+
+2008-02-03  John Darrington <john@darrington.wattle.id.au>
+
+        * psppire-case-file.c psppire-case-file.h: Dont clone the casereader
+       before creating datasheet.  Add properties instead of direct code 
+        in _new function.
+
+        * psppire-data-store.c:  Implement proper dispose function.
+
+2008-01-29  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-var-ptr.c psppire-var-ptr.h: New files
+
+       * t-test-paired-samples.c t-test-paired-samples.h: New files
+
+        * dialog-common.c dialog-common.h (append_variable_names): Add extra 
+       argument to specify the column number containing the variables.
+
+       * psppire-selector.c psppire-selector.h:  Add auxilliary data variable
+       to SelectItemsFunc.  (is_item_in_dest) transform model value to G_TYPE_INT
+       before using.  Hence the model need not be of integer type.
+
+2008-01-22  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-dict.c (psppire_dict_rename_var): Fixed bug where
+       an assertion failure occured when renaming variables to an
+       existing name. Thanks to Ben for reporting this.
+
+2007-12-13  John Darrington <john@darrington.wattle.id.au>
+
+       * dialog-common.c dialog-common.h (numeric_only): New function.
+
+       * t-test-independent-samples-dialog.c:  Added the ability to specify 
+       groups by a threshold ("Cut Point").  Keep OK/Paste buttons insensitive,
+       until groups are properly defined.  Prevented variables treeview from
+       accepting string variables.
+
+2007-12-08  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.h data-editor.c: Added hooks for one sample t-test
+
+       * t-test-one-sample.c t-test-one-sample.h (new files): Implemented
+       a dialog box for the One Sample T Test.
+
+       * t-test-independent-samples-dialog.c: Factored out the options sub
+       dialog (see following).
+
+       * t-test-options.c t-test-options.h (new files):  New module
+        implementing the options sub-dialog for T tests.
+
+2007-12-07  John Darrington <john@darrington.wattle.id.au>
+
+       * frequencies-dialog.c: Made the options subdialog transient
+       on the parent.
+
+2007-12-01  John Darrington <john@darrington.wattle.id.au>
+
+       * descriptives-dialog.c: Moved the code dealing with checkboxes 
+       inside treeview widgets into their own files.
+
+       * checkbox-treeview.c checkbox-treeview.h: New file (see above).
+
+       * frequencies-dialog.c frequencies-dialog.h frequencies.glade: New 
+       files. Implemented FREQUENCIES dialog box.
+
+       * data-editor.c data-editor.h data-editor.glade :  Added callback
+       for frequencies dialog.
+
+
+2007-11-23  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-acr.c psppire-acr.h: Generalised the external widget
+       somewhat. It can now be anything, not necessarily a GTK_ENTRY.
+
+       * helper.c helper.h (clone_list_store): New function.
+
+       * oneway-anova-dialog.c : Used the clone_list_store function
+       instead of writing it ourselves.
+       
+       * psppire-dialog.c psppire-dialog.h: Added a tabular orientation
+       in addition to the horizontal/vertical options.
+       
+       * recode-dialog.c recode-dialog.h recode.glade (new files).
+
+       * psppire-selector.c psppire-selector.h: Added a function to
+       allow the prohibition of items based on a predicate.
+
+       * dialog-common.h dialog-common.c (homogeneous_types): New function.
+
+       * data-editor.c data-editor.glade data-editor.h: Enabled the
+       recode dialog options.
+
+
+2007-11-23  John Darrington <john@darrington.wattle.id.au>
+
+       * compute-dialog.c (generate_syntax): Append "EXECUTE." to the 
+       generated syntax.
+
+2007-10-19  John Darrington <john@darrington.wattle.id.au>
+
+        * psppire-acr.c psppire-acr.h (new files): Added this new
+       composite widget.
+
+       * data-editor.c data-editor.h: Added entries for ONEWAY command
+       dialog box.
+
+       * oneway-anova-dialog.c oneway-anova-dialog.h oneway.glade (new files)
+       
+2007-10-06  John Darrington <john@darrington.wattle.id.au>
+       
+       * psppire-dialog.c psppire-dialog.h: Added a predicate function
+       member to indicate when a dialog's state is (not) valid. Added a
+       signal "validity-changed" which gets emitted whenever this
+       predicate changes. 
+
+       * psppire-buttonbox.c: Connect to the toplevel window's
+       "validity-changed" signal (assuming it happens to be a
+       PsppireDialog) and set the OK, PASTE, GOTO and CONTINUE buttons
+       according.y. 
+
+       * descriptives-dialog.c compute-dialog.c: Add a validity predicate.
+
+2007-10-05  Ben Pfaff  <blp@gnu.org>
+
+       Add DESCRIPTIVES dialog.
+       
+       * automake.mk (dist_src_ui_gui_psppire_DATA): Add
+       descriptives-dialog.data.
+       (src_ui_gui_psppire_SOURCES): Add descriptives-dialog.c,
+       descriptives-dialog.h.
+
+       * data-editor.c (new_data_editor): Connect descriptive dialog to
+       action.
+
+       * data-editor.glade: Change menu item to invoke DESCRIPTIVES.
+
+       * descriptives-dialog.c: New file.
+       
+       * descriptives-dialog.h: New file.
+       
+       * descriptives-dialog.glade: New file.
+
+2007-10-04  John Darrington <john@darrington.wattle.id.au>
+
+       * compute-dialog.c goto-case-dialog.c main.c psppire-keypad.c: Added 
+       #include <config.h>
+
+       * psppire.glade about.c: Read GPL text from src/libpspp/copyleft.c 
+       instead of makeing another copy in psppire.glade.
+
+       * psppirebuttonbox.c psppire.c: Create a new stock item for 
+       RESET buttons.
+       
+2007-09-26  John Darrington <john@darrington.wattle.id.au>     
+       
+       * output-viewer.c output-viewer.h psppire.c: (closes patch #6210) 
+       Changed width and length parameters of output driver to
+       "auto". Changed default width and length  to be something
+       acceptable to the ascii driver.  (reload_viewer) Dynamically
+       allocate the line buffer so that it matches the width of the output.
+       
+2007-09-24  Ben Pfaff  <blp@gnu.org>
+
+       * message-dialog.c (popup_message): Refer to files that contain
+       commands as "syntax" files, not "script" files, for better user
+       familiarity.
+       Patch #6210.  Reviewed by John Darrington.
+
+2007-09-19  John Darrington <john@darrington.wattle.id.au>
+       
+       * message-dialog.c: Changed the ouput message title to be 
+       appropriate for the severity of the message.
+
+       * output-viewer.c output-viewer.h : Added a callback for the resize 
+       signal of the output viewer, and set the viewport length and
+       width accordingly.
+
+       * psppire.c: Update to new init_settings interface.
+
+2007-09-27  John Darrington <john@darrington.wattle.id.au>
+
+       Addressing bug #20821:
+       
+       * psppire-dict.c: Added a BACKEND_CHANGED signal to indicate when 
+       a PsppireDict's struct dictionary has been replaced.
+
+       * psppire-var-store.c: Added the appropriate method for 
+       get_column_count. Added a signal handler for dict:BACKEND_CHANGED, 
+       which calls the g_sheet_model_range_changed for the entire sheet.
+       
+2007-09-18  Ben Pfaff  <blp@gnu.org>
+
+       * helper.c (create_casereader_from_data_store): New function.
+       (execute_syntax): Only replace the active file data by a new
+       casereader if syntax caused the active file to be read, to avoid
+       exponential slowdown as an increasing number of snippets that do
+       not read from the active file are consecutively executed.  Bug
+       #20910.  Reviewed by and heavily influenced by John Darrington.
+
+       * psppire-data-store.c (psppire_data_store_get_value_count): New
+       function.
+
+       * psppire-dict.c (psppire_dict_get_value_cnt): New function.
+
+2007-09-13  John Darrington <john@darrington.wattle.id.au>
+
+       * find-dialog.c find-dialog.h: New files.
+
+       * data-editor.c data-editor.h data-editor.glade: Added action for
+       the find dialog.
+
+       * psppire-selector.c: Emit the (de)selected signal when the 
+       destination entry widget's text changes.
+
+2007-09-10  Ben Pfaff  <blp@gnu.org>
+
+       * var-sheet.c (psppire_variable_sheet_create): Use xstrdup to save
+       string returned by bind_textdomain_codeset.  Otherwise it can get
+       freed by a subsequent call.  Patch #6193.  Reviewed by John
+       Darrington.
+
+2007-09-06  John Darrington <john@darrington.wattle.id.au>
+       
+       * helper.c helper.h (execute_syntax): changed return type to 
+       gboolean to indicated if all the syntax executed successfully or not.
+
+       * data-editor.c syntax-editor.c: Fixed update of recent file list
+       and window title,  on data_file_open.  They now only change, if
+       the file_open was  successfull. 
+
+
+2007-08-25  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire.c : Enable journal.
+
+2007-08-18  John Darrington <john@darrington.wattle.id.au>
+
+       * clipboard.c clipboard.h data-editor.c: Added the ability to paste from 
+       the clipboard into the data sheet.
+
+2007-08-16  John Darrington <john@darrington.wattle.id.au>
+
+        * output-viewer.c output-viewer.h output-viewer.glade (new files)
+         helper.c psppire.c syntax-editor.glade window-manager.c 
+         window-manager.h : Added a basic output viewer window.
+
+2007-08-13  John Darrington <john@darrington.wattle.id.au>
+
+       * clipboard.c (clip_to_html clip_to_text): Fixed bug --- use the
+       variable count instead of the value count for the columns limit. 
+
+2007-08-12  John Darrington <john@darrington.wattle.id.au>
+           Ben Pfaff  <blp@gnu.org>
+
+       Implement Edit|Cut operation for datasheet.  Patch #6117.
+
+       * automake.mk: Add clipboard.c, clipboard.h.
+
+       * clipboard.c: New file.
+
+       * clipboard.h: New file.
+
+       * data-editor.c (new_data_editor): Connect Edit|Copy to
+       on_edit_copy function.
+       (data_var_select): Enable or disable Edit|Copy as appropriate.
+       (on_edit_copy): New function.
+
+       * data-editor.glade: Connect menu items to new operations.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-dict.c (psppire_dict_dump): Don't use
+       dict_get_compacted_dict_index_to_case_index, as that function has
+       been deleted.
+
+2007-08-13  John Darrington <john@darrington.wattle.id.au>
+
+        * psppire-case-file.c (psppire_case_file_append_case):
+       Deleted unused function.
+
+2007-08-07  John Darrington <john@darrington.wattle.id.au>
+
+       * helper.c (execute_syntax): Set the active file data to NULL at the
+       end of the procedure.  Thanks to Ben for suggesting this.
+
+       * psppire-case-file.c: Added assertions to the remaining functions
+       on inaccessible objects.
+
+       * psppire-data-store.c psppire-data-store.h: Disconnect or block
+       signals on dictionary and case_file, when make_reader has been called.
+       Reconnect or unblock them when a new datasheet has been set for the
+       data_store.
+
+2007-08-06  John Darrington <john@darrington.wattle.id.au>
+
+       * syntax-editor.glade: Changed some properties to be less annoying.
+
+2007-07-29  John Darrington <john@darrington.wattle.id.au>
+
+       * helper.c psppire.c: Enabled the output system so that the results
+       of analysis can be seen.
+
+2007-07-26  John Darrington <john@darrington.wattle.id.au>
+
+       * helper.c helper.h (execute_syntax): removed implicit EXECUTE at end
+       of commands.
+
+       * data-editor.c data-editor.glade: Added "Run Pending Transformations"
+       menuitem.
+
+2007-07-25  John Darrington <john@darrington.wattle.id.au>
+
+       * customentry.c: Redraw button in insensitive state, if the widget's
+        "editable" style is FALSE.  Don't emit the "clicked" signal if
+        "editable" is FALSE.
+
+       * var-sheet.c: If variables are long-string variables, then set the
+       "editable" properties of the entry widgets for the values and missing
+       cells to FALSE,
+
+2007-07-18  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-case-file.c psppire-case-file.h psppire-data-store.c
+       psppire-dict.c psppire-dict.h psppire-var-store.c : Added the
+       ability to resize string variables.  Fixed associated problems
+       inserting/deleting variables.
+
+       * helper.c helper.h (marshaller_VOID__INT_INT_INT): New marshaller
+       function.
+
+2007-07-16  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c: File Open dialog remembers directory.  Thanks to
+       Ben Pfaff for this suggestion.
+
+2007-07-15  John Darrington <john@darrington.wattle.id.au>
+
+       * compute-dialog.c: Only generate NUMERIC/STRING command if the
+       type-and-label dialog was used.
+
+2007-07-12  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-data-store.c: Added call to g_sheet_model_range_changed to
+       ensure that datasheet displays the current store.
+
+       * psppire-data-store.h: Formatting tidy up.
+
+2007-07-11  John Darrington <john@darrington.wattle.id.au>
+
+       * compute-dialog.c : Set type-and-label dialog to sensible state,               and made syntax generation depend upon existence of target variable.
+
+2007-07-08  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-editor.glade data-editor.h: Implemented
+       the "Insert Case" button/dialog.
+
+2007-07-08  John Darrington <john@darrington.wattle.id.au>
+
+       * goto-case-dialog.c goto-case-dialog.h (new files)
+       * automake.mk data-editor.c data-editor.glade data-editor.h
+       psppire-case-file.c psppire-case-file.h psppire-data-store.c
+       psppire-data-store.h psppire.glade :  Implemented the goto-case dialog
+
+
+2007-07-07  John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-data-store.c psppire-data-store.h: Made cases number from
+       1 instead of 0.
+
+       * psppire-data-store.c: Added a tooltip like feature to display
+       the label of variables.
+
+2007-07-03  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-sheet.c: Turned off autoscrolling, and
+       manually move to cell on column click instead.
+
+2007-06-29  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-editor.glade psppire-data-store.c
+       psppire-data-store.h: Enabled cell reference entry and datum
+       entry widgets.
+
+2007-06-29  John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-sheet.c: Moved update_cell_ref_entry from
+       data-sheet.c to data-editor.c and made it work again.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+
+       * automake.mk: Removed files.
+
+       * flexifile-factory.c: Removed, dead code.
+       * flexifile-factory.h: Ditto.
+
+       * helper.c: Adapt to new procedure and datasheet code.
+       * missing-val-dialog.c: Ditto.
+       * psppire-case-file.c: Ditto.
+       * psppire-data-store.c: Ditto.
+       * psppire.c: Ditto.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-var-store.c (psppire_var_store_item_editable): Use
+       var_is_alpha.
+
+2007-05-07 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-dialog.c psppire-dialog.h: Added "orientation" property,
+        to allow dialogs to be either vertical or horizontal.
+
+       * comments-dialog.c comments-dialog.h: New files, invoking
+       ADD DOCUMENT cmd.
+
+2007-04-30 John Darrington <john@darrington.wattle.id.au>
+
+       * var-display.c var-display.h variable-info-dialog.c
+       variable-info-dialog.h : New files.
+
+       * data-editor.c :
+
+       * psppire-buttonbox.c psppire-buttonbox.h : Added the "buttons"
+       property, and optional  GOTO and CONTINUE buttons.
+
+       * psppire-dialog.h: Added response codes for the new buttons.
+
+       * psppire-var-store.c : Moved some code to var-display.[ch]
+
+2007-04-25 John Darrington <john@darrington.wattle.id.au>
+
+       * icons/scalable/splash.c icons/splash.png : More eye candy.
+
+       * main.c psppire.h : new files.
+
+       * psppire.c : Seperated the command line parsing and other
+       environment startup from the core psppire code.
+
+2007-04-25 John Darrington <john@darrington.wattle.id.au>
+
+       * icons/scalable icons/16x16: new directories.
+       * psppire.c : Add new icons to factory.
+
+       * dict-display.c: Refactor code get model from modelfilter.
+       Added cellrenderer to display icon indicating variables' types.
+        Displayed the label of variables, if there is one.
+
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * compute-dialog.c (function_list_populate): Use new accessor
+       functions exported by language/expressions/public.h.
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * compute-dialog.c: Make #include for parse.inc work with VPATH
+       builds.
+
+2007-04-13   John Darrington <john@darrington.wattle.id.au>
+
+       * var-type-dialog.c: Added a FMT_DATETIME20 template.
+
+2007-04-04   John Darrington <john@darrington.wattle.id.au>
+
+       * compute-dialog.c compute-dialog.h: New files
+
+       * data-editor.c data-editor.h data-editor.glade : Added Transform
+       menu, and support for Compute dialog
+
+       * glade-register.c psppire-buttonbox.c psppire-buttonbox.h
+         psppire-vbottonbox.c psppire-vbuttonbox.h psppire-hbuttonbox.c
+         psppire-vbuttonbox.h : Made buttonbox an abstract base class
+         and separated it into vbuttonbox and hbuttonbox.
+
+       * psppire-selector.c : Allowed GtkTextView to be the destination
+       widget.
+
+       * psppire-keypad.c: Added an "erase" signal.  Fixed other
+        minor problems.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+           John McCabe-Dansted <gmatht@gmail.com>
+
+       * psppire-selector.c (psppire_selector_set_subjects): Add an
+       assert that may or may not trap some Windows-related bugs.
+
+2007-04-03   John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-editor.glade helper.h syntax-editor.c
+       syntax-editor.h : Implemented the File->Recently_Used_ menus.
+
+
+2007-03-31   John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-editor.glade data-editor.h dialog-common.c
+       psppire-buttonbox.c psppire-dialog.c psppire-dialog.h
+       psppire-selector.c psppire-selector.h psppire.c psppire.glade
+       sort-cases-dialog.c sort-cases-dialog.h split-file-dialog.c
+       transpose-dialog.c weight-cases-dialog.c : Fixed the Refresh
+       button on all the dialogs.
+
+2007-03-31   John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c: Added hooks for the split-file-dialog
+
+       * psppire.glade: Added the split file dialog box.
+
+       * split-file-dialog.c split-file-dialog.h: New files.
+
+       * dialog-common.c dialog-common.h: New files containing functions
+       which seem to be used a lot in dialog box implementations.
+
+       * psppire-keypad.c psppire-keypad.h: New files.  Implements keypad
+       thingumy widget.
+
+       * psppire-selector.c: Made the orientation of the arrow a property
+       of the widget, so that it can be selected from glade.
+
+2007-03-18  Ben Pfaff  <blp@gnu.org>
+
+       * syntax-editor-source.c (close): Rename do_close to avoid naming
+       conflict with POSIX function of same name.
+
+Tue Mar 13 17:20:05 CET 2007 John Darrington <john@darrington.wattle.id.au>
+       * psppire.c:  Changed gtk_init to gtk_parse_args, followed by a delayed         call to gdk_init, so that psppire --version will succeed, even if it
+       cannot connect to a display .
+
+Wed Mar  7 19:05:12 CET 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * var-sheet.c: Replaced call to nl_langinfo with locale_charset
+       from gnulib.
+
+Thu Feb 22 12:27:41 CET 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c : called new gen_quoted_string function to properly
+          quote filenames in generated syntax.
+
+       * window-manager.c : Converted name from filename encoding to UTF8
+          before displaying in title bar.
+
+Tue Jan 30 20:13:46 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-dict.c: Call all the callbacks when a new dictionary becomes current.
+
+       * data-editor.c: Clear existing file name on FILE NEW.
+
+Sat Jan 27 09:48:21 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * var-type-dialog.c: Fixed bugs closing window, apparent when compiled
+       against gtk.2.10
+
+Fri Jan 26 15:51:34 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-var-select.c psppire-var-select.h : Deleted.
+
+       * psppire-selector.c psppire-selector.h : New files.
+
+       * transpose-dialog.c transpose-dialog.h : New files.
+
+       * psppire-dict.c psppire-dict.h : Added missing GtkTreeModel
+       interface functions.
+
+       * weight-cases-dialog.c weight-cases-dialog.h : Re-implemented,
+       using new PsppireSelector widget.
+
+       * dict-display.c dict-display.h : New files.
+
+       * psppire-object.c psppire-object.h : Deleted.  Seemed like a good idea at the time.
+
+Tue Jan 23 21:10:01 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * helper.c helper.h: New function execute_syntax.
+
+       * syntax-editor.c syntax-editor.glade: Disabled data open/save menu
+       items.
+
+       * data-editor.c data-editor.glade data-editor.h: Enabled data
+       open/save/save_as  menu-items.
+
+       * window-manager.h window-manager.c (default_window_name) : New
+       function.
+
+Sat Jan 13 07:47:26 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-case-file.c psppire-data-store.c psppire-dialog.c
+       psppire-dict.c psppire-var-select.c : Replaced identifier 'signal'
+       with 'signals' to avoid conflict with sysv based systems which use
+       this identifer for something else.
+       Thanks to Daniel E WILLIAMS for reporting this problem.
+
+Wed Jan 10 07:20:39 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-case-file.c : Make sure there is always a valid flexifile
+
+       * psppire-data-store.c : assertions.
+
+       * psppire.c: Ignore replace source callbacks if the new source is
+         not of storiage_source_class
+
+       * syntax-editor.c: Close/Abort source after parsing is complete.
+
+Sun Jan  7 08:38:29 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-dict.c: Add FILTER_CHANGED and SPLIT_CHANGED signals
+       corresponding to the callbacks in src/data/dictionary.c
+
+       * data-editor.c : Connect functions to the FILTER_CHANGED and
+       SPLIT_CHANGED signals to update the status bar accordingly.
+
+Mon Jan  1 10:37:07 WST 2007 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-case-file.c psppire-case-file.h: Changed the backend
+       semantics. An object is now created without any backend.  A new function        ( psppire_case_file_replace_flexifile ) sets the backend to use.
+
+       * psppire-data-store.c : Updated callers accordingly.
+
+       * psppire-dict.c psppire-dict.h : New function
+       (psppire_dict_replace_dictionary) .
+
+       * psppire.c : Updated to use new dataset replace_{source, dictionary}
+       callbacks.
+
+       * syntax-editor.c : parses in state CMD_STATE_DATA unless there are
+       no variables in the dictionary.
+
+Mon Dec 25 12:38:24 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-editor.c data-editor.glade: Enabled deleting of variables from
+       the variable sheet.
+
+Mon Dec 25 11:28:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-dict.c psppire-dict.h: Removed explicit signal emit calls.
+       These are not required, now that src/data/dictionary.c has callbacks
+
+Mon Dec 25 08:49:57 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * var-sheet.c val-labs-dialog.c val-labs-dialog.h: Fixed bug in value
+       labels dialog box.
+
+Sun Dec 17 08:26:10 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * syntax-editor-source.c syntax-editor-source.h syntax-editor.h:
+       New files.
+
+       * message-dialog.c :  Now reports the filename and line number in
+       error messages.
+
+       * psppire.c psppire.glade syntax-editor.c: Added the ability to run
+       syntax from the syntax editor.
+
+
+Sat Dec 16 14:13:07 2006  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-data-store.c (geometry_get_justification): Don't assume
+       that ALIGN_* and GTK_JUSTIFY_* values coincide.
+
+Sat Dec 16 14:10:43 2006  Ben Pfaff  <blp@gnu.org>
+
+       * psppire-var-store.c (text_for_column): Adjust to account for new
+       values of the MEASURE_* enums.
+
+       * var-sheet.c (change_measure): Ditto.
+
+Sat Dec 16 12:24:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-variable.c psppire-variable.h: Deleted.
+
+       * psppire-dict.c psppire-dict.h: Removed the caching of the variable
+           data, which is now unecessary because src/data/vardict.h maintains
+           an association between variables and their dictionary.
+
+       * data-sheet.c menu-actions.c missing-val-dialog.c
+         missing-val-dialog.h psppire-data-store.c
+         psppire-var-store.c psppire-var-store.h
+         sort-cases-dialog.c val-labs-dialog.c val-labs-dialog.h
+         var-sheet.c var-type-dialog.c var-type-dialog.h: Dealt with the
+           consequences of deleting psppire-variable.[ch].
+
+
+Sat Dec  9 20:03:04 2006  Ben Pfaff  <blp@gnu.org>
+
+       * var-type-dialog.c (var_type_dialog_create): Use
+       fmt_dollar_template from data/format.c.
+       (dollar_format_template) Removed.
+
+Sat Dec  9 07:19:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * syntax-editor.c : New file.
+
+Tue Oct 31 19:25:31 2006  Ben Pfaff  <blp@gnu.org>
+
+       * var-type-dialog.c: Add missing "#include <config.h>".
+
+       * psppire.c: Ditto.
+
+Mon Jul 17 18:21:29 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * automake.mk menu-actions.c psppire-case-file.c psppire-case-file.h
+    psppire-data-store.c psppire-dict.c psppire-dict.h psppire-variable.c
+    psppire.c psppire.glade: Adjusted code to use the new flexifile object.
+
+Sat Jul 15 11:27:15 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire.c psppire.glade automake.mk icons/* : Added toolbar icons where
+       there's no suitable gtk stock icon.
+
+Tue Jul  4 09:08:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire.c: Fixed --help and --version options.
+
+Sat Jun 24 16:56:22 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * menu-actions.c: Added goto case and sort cases dialogs.
+
+   * psppire-case-file.c psppire-case-file.h: Added sort function.
+
+   * psppire-data-store.c psppire-variable.c psppire-variable.h:
+     Renamed  psppire_variable_get_index to psppire_variable_get_fv and
+     dealt with the consequences.  Added a psppire_variable_get_index
+     function which actually does what the name suggests.
+
+   * psppire-dict.c psppire-dict.h: Implemented GtkTreeModel interface,
+     which allows a dictionary to be displayed in a GtkTreeView.
+
+   * psppire.glade: Added dialog boxes for Goto Case and Sort Case.
+
+   * sort-cases-dialog.c sort-cases-dialog.h (new files).
+
+Mon Jun 19 18:10:53 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire-case-file.c psppire-case-file.h (new files)
+
+   * automake.mk data-sheet.c data-sheet.h menu-actions.c
+   psppire-data-store.c psppire-data-store.h psppire-dict.c
+   psppire-dict.h psppire-var-store.c psppire.c
+
+     Replaced psppire-case-array.c  with psppire-case-file.c, so as to
+     allow an arbitrary number of cases to be represented.
+
+Sun Jun  4 15:50:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire-var-store.c, psppire.c, var-sheet.c :  Unlimited the number of
+   variables that can be displayed. Minor i18n issues.
+
+Tue May 30 19:53:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * menu-actions.c menu-actions.h psppire.c: Fixed up load/new
+   interactions with startup.
+
+   * psppire-data-store.c: Fixed bad i18n call.
+
+   * pspppire-var-store.c, psppire-var-store.h: constness.
+
+   * helper.c: Implemented proper way to convert from PSPP to UTF8 encoding.
+
+
+Sat May 27 16:25:38 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * customentry.c data-sheet.c menu-actions.c message-dialog.c
+     missing-val-dialog.c psppire-data-store.c psppire-var-store.c
+     psppire.c psppire.glade var-sheet.c: Fixed internationalisation.
+
+Thu May 25 18:01:17 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * psppire-var-store.c: Converted strings to utf8 and returned them on the
+   heap.
+
+Sat May 20 21:08:18 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+   * data-sheet.c, menu-actions.c menu-actions: Fixed data sheet so that
+   active cell is never on a deleted variable.
+
+   * psppire-data-store.c psppire-data-store.h:  Added get_var_count and
+   get_case_count functions.
+
+   * psppire-dict.c: removed VARIABLE_DELETED (singular) signal.
+
+   * psppire.c: Allowed user to specify *.sav file on command line.
+
+Mon May 15 20:01:25 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * menu-actions.c psppire-case-array.c psppire-case-array.h
+         psppire-data-store.c  psppire-dict.c psppire-dict.h
+         psppire-variable.c:
+
+         Initialised new cases to SYSMIS/blank when inserting in data sheet.
+
+Sat May 13 08:00:50 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-sheet.c, helper.c, helper.h, psppire-data-store.c,
+          psppire-var-store.c:
+
+         Set free_strings flag so that the gtksheet frees the string data
+         when it's done with them.
+
+Thu May 11 22:25:49 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * data-sheet.c helper.c helper.h psppire-data-store.c psppire-var-store.c
+       psppire.c: Converted strings to utf8 before passing to gtksheet.
+
+       * psppire-dict.c: Changed buffer to more reasonable length
+
+       * var-sheet.c: Changed maximum string length to use macro from
+       data/values.h
+
+
+Sun May  7 10:07:28 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * psppire-data-store.c: Fixed buglet initialising string members.
+
+Thu May  4 18:04:04 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * message-dialog.c message-dialog.h: Added simple queuing to messages
+       reported, and ensure that dialog boxes dont appear when pointer grab
+       is active.
+
+       * psppire-data-store.c: Fix overflow on very long string variables.
+
+       * automake.mk: Fix broken dependency.
+
+
+Tue Apr 25 11:08:04 2006  Ben Pfaff  <blp@gnu.org>
+
+       Finish reforming error message support.  In this phase, move
+       message.c into libpspp.
+
+       * automake.mk: (src_ui_gui_psppire_SOURCES) Remove src/message.c.
+
+Tue Apr 25 10:56:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk: (src_ui_gui_psppire_SOURCES) Add src/message.c.
+
+       * message-dialog.c: (message_dialog_init) New function.
+       (vmsg) Rename handle_msg(), rewrite as callback function.
+       (msg) Removed.
+       (msg_emit) Removed.
+       (msg_assert_fail) Removed.
+       (verbose_msg) Removed.
+
+       * psppire.c: (main) Call message_dialog_init().
+
+Sun Apr 23 22:07:49 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, get rid
+       of message "titles" and put the message text in `struct error'.
+       Now `struct error' encapsulates a message more properly.
+
+       * message-dialog.c: (err_vmsg) Rename err_msg().  Updated
+       interface.
+
+Sun Apr 16 20:45:35 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we
+       divide the classification of messages along "category" and
+       "severity" axes.
+
+       * message-dialog.c: (vmsg) Use severity and category in
+       straightforward fashion instead of the less obvious "class".
+       (err_vmsg) Construct class before passing along to vmsg().
+
+Sun Apr 16 16:06:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, we get
+       rid of VM() and the other msg() support for "verbosity", replacing
+       it by a new function verbose_msg().
+
+       * message-dialog.c: (verbose_msg) New function.
+       (err_cond_fail) Removed (dead code).
+       (err_failure) Removed (dead code).
+
+Sun Apr 16 11:53:25 2006  Ben Pfaff  <blp@gnu.org>
+
+       Start reforming error message support.  In this phase, we get rid
+       of "installation errors" and change all uses of msg() in the
+       output drivers to uses of error() or error_at_line().
+
+       * message-dialog.c: (vmsg) Removed IE, IS support.
+
+Mon Mar 13 16:42:44 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * psppire.c: Supported (sort of) the --help and --version options.
+
+    * Rename error-dialog.[ch] -> message-dialog.[ch]
+
+    * Moved code from the psppire module.
+
+Sat Jan 28 16:22:23 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+    * Separated the data out of the GtkSheet.
+
+Tue Nov  2 19:00:28 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+    * Very first incarnation.
index 8130f5cf42087876484d05662fb19c8ed38b4f42..f77f88c7935134c94beea5f30abb14a9f6dc6471 100644 (file)
@@ -53,20 +53,12 @@ src_ui_gui_psppire_LDADD = \
        -dlopen src/ui/gui/libpsppire.la \
        src/ui/gui/libpsppwidgets.la \
        lib/gtksheet/libgtksheet.a \
-       src/language/liblanguage.a \
-       src/ui/libuicommon.a \
-       src/output/charts/libcharts.a \
-       src/output/liboutput.a \
-       src/math/libpspp_math.a  \
-       lib/linreg/liblinreg.a  \
-       lib/gsl-extras/libgsl-extras.a  \
-       src/data/libdata.a \
-       src/libpspp/libpspp.a \
+       src/ui/libuicommon.la \
+       src/libpspp.la \
+       src/libpspp-core.la \
        $(GTK_LIBS) \
        $(GLADE_LIBS) \
-       $(PG_LIBS) \
-       gl/libgl.la \
-       @LIBINTL@ @LIBREADLINE@
+       @LIBINTL@
 
 src_ui_gui_psppiredir = $(pkgdatadir)
 
@@ -219,4 +211,6 @@ yelp-check:
                echo '    Yelp is available from the GNOME project.  ftp://ftp.gnome.org/pub/gnome/sources/yelp' ; \
                echo ; \
        fi
-.PHONY: yelp-check
+PHONY += yelp-check
+
+EXTRA_DIST += src/ui/gui/OChangeLog
index df70e89ced6cfd2f44d4492d9b87438f912c24b4..d4cbae1e6716640ea5d2f85c878c91422c410e9f 100644 (file)
@@ -1402,6 +1402,11 @@ data_save_as_dialog (GtkAction *action, struct data_editor *de)
        de->save_as_portable =
          ! gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_sys));
 
+       if ( de->save_as_portable)
+         append_filename_suffix (de, ".por");
+       else
+         append_filename_suffix (de, ".sav");
+
        save_file (de);
 
        window_set_name_from_filename (e, de->file_name);
index 5d98b4ac91ccc0f22a783643825cc2a66bc444e4..7764d04a9633b2cac6aed1decddbd858e45bd830 100644 (file)
@@ -464,7 +464,7 @@ value_compare (const struct comparator *cmptr,
               const union value *v)
 {
   const struct value_comparator *vc = (const struct value_comparator *) cmptr;
-  return 0 == compare_values (v, vc->pattern, var_get_width (cmptr->var));
+  return 0 == compare_values (v, vc->pattern, cmptr->var);
 }
 
 
index 3b9f03703ea7c85b367b057f47fa63757f4dc218..1a620908309c3f93450dd4b90178ec1ca0001785 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "relocatable.h"
 
+#include <data/format.h>
 #include <data/value.h>
 
 #include <gtk/gtk.h>
index a3d394618c5e4662113863915fb47e6db16eb090..a36e9410a345557f6c7e9a8ece90b0a15b5aec3d 100644 (file)
 #include "psppire.h"
 #include "progname.h"
 #include <stdlib.h>
-#include <getopt.h>
+#include <argp.h>
+#include <gl/relocatable.h>
+#include <ui/command-line.h>
+#include <ui/source-init-opts.h>
 
 #include <libpspp/version.h>
 #include <libpspp/copyleft.h>
 
-static gboolean parse_command_line (int *argc, char ***argv, gchar **filename,
-                                   gboolean *show_splash, GError **err);
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
 
+const char *argp_program_version = version;
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
 
+\f
+/* Arguments to be interpreted before the X server gets initialised */
+
+static const struct argp_option startup_options [] =
+  {
+    {"no-splash",  'q',  0,  0,  N_("Don't show the splash screen"), 0 },
+    { 0, 0, 0, 0, 0, 0 }
+  };
+
+static error_t
+parse_startup_opts (int key, char *arg, struct argp_state *state)
+{
+  gboolean *showsplash = state->input;
+
+  switch (key)
+    {
+    case 'q':
+      *showsplash = FALSE;
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+static const struct argp startup_argp = {startup_options, parse_startup_opts, 0, 0, 0, 0, 0};
+
+\f
 
 static GtkWidget *
 create_splash_window (void)
@@ -45,7 +79,7 @@ create_splash_window (void)
   gtk_window_set_type_hint (GTK_WINDOW (splash),
                            GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
 
-  image = gtk_image_new_from_file (PKGDATADIR "/splash.png");
+  image = gtk_image_new_from_file (relocate (PKGDATADIR "/splash.png"));
 
   gtk_container_add (GTK_CONTAINER (splash), image);
 
@@ -71,13 +105,22 @@ quit_one_loop (gpointer data)
   return FALSE;
 }
 
+struct initialisation_parameters
+{
+  int argc;
+  char **argv;
+  GtkWidget *splash_window;
+  struct command_line_processor *clp;
+};
+
 
 static gboolean
 run_inner_loop (gpointer data)
 {
-  initialize ();
+  struct initialisation_parameters *ip = data;
+  initialize (ip->clp, ip->argc, ip->argv);
 
-  g_timeout_add (500, hide_splash_window, data);
+  g_timeout_add (500, hide_splash_window, ip->splash_window);
 
   gtk_main ();
 
@@ -91,10 +134,10 @@ run_inner_loop (gpointer data)
 int
 main (int argc, char *argv[])
 {
-  GtkWidget *splash_window;
-  gchar *filename = 0;
+  struct command_line_processor *clp ;
+  struct initialisation_parameters init_p;
   gboolean show_splash = TRUE;
-  GError *err = 0;
+
   const gchar *vers;
 
   set_program_name (argv[0]);
@@ -109,78 +152,32 @@ main (int argc, char *argv[])
                                 GTK_MINOR_VERSION,
                                 GTK_MICRO_VERSION)) )
     {
-      g_critical (vers);
+      g_warning (vers);
     }
 
-  /* Deal with options like --version, --help etc */
-  if ( ! parse_command_line (&argc, &argv, &filename, &show_splash, &err) )
-    {
-      g_clear_error (&err);
-      return 0;
-    }
+  clp = command_line_processor_create (_("PSPPIRE --- A user interface for PSPP"), "[ DATA-FILE ]", 0);
+
+  command_line_processor_add_options (clp, &startup_argp, _("Miscellaneous options:"),  &show_splash);
+  command_line_processor_add_options (clp, &post_init_argp,
+                                     _("Options affecting syntax and behavior:"),  NULL);
+  command_line_processor_add_options (clp, &non_option_argp, NULL, NULL);
+
+  command_line_processor_parse (clp, argc, argv);
 
   gdk_init (&argc, &argv);
 
-  splash_window = create_splash_window ();
+  init_p.splash_window = create_splash_window ();
+  init_p.argc = argc;
+  init_p.argv = argv;
+  init_p.clp = clp;
+
   if ( show_splash )
-    gtk_widget_show (splash_window);
+    gtk_widget_show (init_p.splash_window);
 
   g_idle_add (quit_one_loop, 0);
 
-  gtk_quit_add (0, run_inner_loop, splash_window);
+  gtk_quit_add (0, run_inner_loop, &init_p);
   gtk_main ();
 
-
   return 0;
 }
-
-
-/* Parses the command line specified by ARGC and ARGV as received by
-   main ().  Returns true if normal execution should proceed,
-   false if the command-line indicates that PSPP should exit. */
-static gboolean
-parse_command_line (int *argc, char ***argv, gchar **filename,
-                   gboolean *show_splash, GError **err)
-{
-
-  static struct option long_options[] =
-    {
-      {"help", no_argument, NULL, 'h'},
-      {"version", no_argument, NULL, 'V'},
-      {"no-splash", no_argument, NULL, 'q'},
-      {0, 0, 0, 0},
-    };
-
-  int c;
-
-  for (;;)
-    {
-      c = getopt_long (*argc, *argv, "hVq", long_options, NULL);
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-       case 'h':
-         g_print ("Usage: psppire {|--help|--version|--no-splash}\n");
-          return FALSE;
-       case 'V':
-         g_print (version);
-         g_print ("\n");
-         g_print (legal);
-         return FALSE;
-       case 'q':
-         *show_splash = FALSE;
-         break;
-       default:
-         return FALSE;
-       }
-    }
-
-  if ( optind < *argc)
-    {
-      *filename = (*argv)[optind];
-    }
-
-  return TRUE;
-}
index 0372e14cf9325df0a7a62604229b329784ca073a..bf647e9051199eda18135237e6f477aab4249814 100644 (file)
@@ -198,33 +198,72 @@ void
 reload_viewer (struct output_viewer *ov)
 {
   GtkTextIter end_iter;
-  static char *line = NULL;
   GtkTextMark *mark ;
-  gboolean chars_inserted = FALSE;
 
+  static char *line = NULL;
 
-  if ( ov->fp == NULL)
-    {
-      ov->fp = fopen (OUTPUT_FILE_NAME, "r");
-      if ( ov->fp == NULL)
-       {
-         g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
-         return;
-       }
-    }
+  gboolean chars_inserted = FALSE;
+
+  gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
 
   line = xrealloc (line, sizeof (char) * (viewer_width + 1));
 
-  gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
 
   mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE);
 
-  /* Read in the next lot of text */
-  while (fgets (line, viewer_width + 1, ov->fp) != NULL)
-    {
-      chars_inserted = TRUE;
-      gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
-    }
+#ifdef __CYGWIN__
+  /*
+    Apparently Windoze is not capabale of writing to a file whilst
+    another (or the same) process is reading from it.   Therefore, we
+    must close the file after reading it, and clear the entire buffer
+    before writing to it.
+    This will be slower for large buffers, but should work
+    (in so far as anything ever works on windows).
+  */
+  {
+    GtkTextIter start_iter;
+    FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
+    if ( !fp)
+      {
+       g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
+       return;
+      }
+
+    /* Delete all the entire buffer */
+    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
+    gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
+
+
+    gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
+    /* Read in the next lot of text */
+    while (fgets (line, viewer_width + 1, fp) != NULL)
+      {
+       chars_inserted = TRUE;
+       gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
+      }
+
+    fclose (fp);
+  }
+#else
+  {
+    if ( ov->fp == NULL)
+      {
+       ov->fp = fopen (OUTPUT_FILE_NAME, "r");
+       if ( ov->fp == NULL)
+         {
+           g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
+           return;
+         }
+      }
+
+    /* Read in the next lot of text */
+    while (fgets (line, viewer_width + 1, ov->fp) != NULL)
+      {
+       chars_inserted = TRUE;
+       gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
+      }
+  }
+#endif
 
   /* Scroll to where the start of this lot of text begins */
   gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview),
index 239d153e4b0d5ca3454f2080f7c21946181cb2af..d36a802cb0e828a9a9d7c46c81aa312d8e5958d2 100644 (file)
 #include <assert.h>
 #include <libintl.h>
 #include <gsl/gsl_errno.h>
+#include <signal.h>
 
+#include <argp.h>
+#include <ui/command-line.h>
 #include "relocatable.h"
 
 #include "data-editor.h"
 #include "psppire.h"
 
+#include <libpspp/getl.h>
 #include <unistd.h>
 #include <data/casereader.h>
 #include <data/datasheet.h>
@@ -38,6 +42,7 @@
 #include <libpspp/version.h>
 #include <output/output.h>
 #include <output/journal.h>
+#include <language/syntax-string-source.h>
 
 #include <gtk/gtk.h>
 #include <glade/glade.h>
 #include "psppire-data-store.h"
 #include "helper.h"
 #include "message-dialog.h"
+#include <ui/syntax-gen.h>
 
 #include "output-viewer.h"
 
+#include <data/sys-file-reader.h>
+#include <data/por-file-reader.h>
+
+#include <ui/source-init-opts.h>
+
 PsppireDataStore *the_data_store = 0;
 PsppireVarStore *the_var_store = 0;
 
@@ -69,9 +80,8 @@ replace_casereader (struct casereader *s)
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-
 void
-initialize (void)
+initialize (struct command_line_processor *clp, int argc, char **argv)
 {
   PsppireDict *dictionary = 0;
 
@@ -109,6 +119,8 @@ initialize (void)
   the_data_store = psppire_data_store_new (dictionary);
   replace_casereader (NULL);
 
+
+
   create_icon_factory ();
 
   outp_configure_driver_line (
@@ -122,7 +134,17 @@ initialize (void)
   journal_enable ();
   textdomain (PACKAGE);
 
+  /* Ignore alarm clock signals */
+  signal (SIGALRM, SIG_IGN);
+
+  command_line_processor_replace_aux (clp, &post_init_argp, the_source_stream);
+  command_line_processor_replace_aux (clp, &non_option_argp, the_source_stream);
+
+  command_line_processor_parse (clp, argc, argv);
+
   new_data_window (NULL, NULL);
+
+  execute_syntax (create_syntax_string_source (""));
 }
 
 
@@ -197,11 +219,11 @@ create_icon_factory (void)
 
 
     gtk_stock_add (items, 2);
-    gtk_icon_factory_add (factory, "pspp-stock-reset", 
+    gtk_icon_factory_add (factory, "pspp-stock-reset",
                          gtk_icon_factory_lookup_default (GTK_STOCK_REFRESH)
                          );
 
-    gtk_icon_factory_add (factory, "pspp-stock-select", 
+    gtk_icon_factory_add (factory, "pspp-stock-select",
                          gtk_icon_factory_lookup_default (GTK_STOCK_INDEX)
                          );
   }
@@ -209,3 +231,64 @@ create_icon_factory (void)
   gtk_icon_factory_add_default (factory);
 }
 
+\f
+
+static error_t
+parse_non_options (int key, char *arg, struct argp_state *state)
+{
+  struct source_stream *ss = state->input;
+
+  if ( NULL == ss )
+    return 0;
+
+  switch (key)
+    {
+    case ARGP_KEY_ARG:
+      {
+       struct string syntax;
+       FILE *fp = fopen (arg, "r");
+       if (NULL == fp)
+         {
+           const int errnum = errno;
+           fprintf (state->err_stream, _("Cannot open %s: %s.\n"),
+                    arg, strerror (errnum));
+           return 0;
+         }
+       if ( sfm_detect (fp))
+         {
+           ds_init_cstr (&syntax, "GET FILE=");
+           goto close;
+         }
+       rewind (fp);
+       if (pfm_detect (fp))
+         {
+           ds_init_cstr (&syntax, "IMPORT FILE=");
+           goto close;
+         }
+
+       fclose (fp);
+       msg (ME, _("%s is neither a system nor portable file"), arg);
+       break;
+
+      close:
+       fclose (fp);
+
+       syntax_gen_string (&syntax, ss_cstr (arg));
+       ds_put_cstr (&syntax, ".");
+
+       getl_append_source (ss,
+                           create_syntax_string_source (ds_cstr (&syntax)),
+                           GETL_BATCH,
+                           ERRMODE_CONTINUE);
+
+       ds_destroy (&syntax);
+       break;
+      }
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+const struct argp non_option_argp = {NULL, parse_non_options, 0, 0, 0, 0, 0};
index 9c99af02ea98cca2588660d6c5c0e8aa04cb9fd2..92cd13571ca15bebd63e50adc87eddc385145048 100644 (file)
 #ifndef PSPPIRE_H
 #define PSPPIRE_H
 
+#include <argp.h>
 
-void initialize (void);
+struct command_line_processor ;
+extern const struct argp non_option_argp ;
+
+
+void initialize (struct command_line_processor *, int argc, char **argv);
 void de_initialize (void);
 
 #endif /* PSPPIRE_H */
diff --git a/src/ui/source-init-opts.c b/src/ui/source-init-opts.c
new file mode 100644 (file)
index 0000000..43ae5c6
--- /dev/null
@@ -0,0 +1,136 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <argp.h>
+#include "source-init-opts.h"
+#include <stdbool.h>
+#include <xalloc.h>
+#include <string.h>
+#include <output/output.h>
+#include <data/file-name.h>
+#include <libpspp/getl.h>
+#include <language/syntax-file.h>
+#include <stdlib.h>
+#include <libpspp/llx.h>
+#include <data/por-file-reader.h>
+#include <data/sys-file-reader.h>
+#include <libpspp/message.h>
+#include <ui/syntax-gen.h>
+#include <language/syntax-string-source.h>
+#include <data/file-name.h>
+#include <data/settings.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+static const struct argp_option post_init_options [] = {
+  {"algorithm", 'a', "{compatible|enhanced}", 0, N_("set to `compatible' if you want output calculated from broken algorithms"), 0},
+  {"include", 'I', "DIR", 0, N_("Append DIR to include path"), 0},
+  {"no-include", 'I', 0, 0, N_("Clear include path"), 0},
+  {"no-statrc", 'r', 0, 0, N_("Disable execution of .pspp/rc at startup"), 0},
+  {"config-dir", 'B', "DIR", 0, N_("Set configuration directory to DIR"), 0},
+  {"safer", 's', 0, 0,  N_("Don't allow some unsafe operations"), 0},
+  {"syntax", 'x', "{compatible|enhanced}", 0, N_("Set to `compatible' if you want only to accept SPSS compatible syntax"), 0},
+  { 0, 0, 0, 0, 0, 0 }
+};
+
+static error_t
+parse_post_init_opts (int key, char *arg, struct argp_state *state)
+{
+  struct source_init
+  {
+    bool process_statrc;
+  };
+
+  struct source_init *sip = state->hook;
+
+  struct source_stream *ss = state->input;
+
+  if ( state->input == NULL)
+    return 0;
+
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->hook = sip = xzalloc (sizeof (struct source_init));
+      sip->process_statrc = true;
+      break;
+    case ARGP_KEY_FINI:
+      free (sip);
+      break;
+    case  'a':
+      if ( 0 == strcmp (arg, "compatible") )
+       settings_set_algorithm (COMPATIBLE);
+      else if ( 0 == strcmp (arg, "enhanced"))
+       settings_set_algorithm (ENHANCED);
+      else
+       {
+         argp_failure (state, 1, 0, _("Algorithm must be either \"compatible\" or \"enhanced\"."));
+       }
+      break;
+    case 'B':
+      config_path = arg;
+      break;
+    case 'I':
+      if (arg == NULL || !strcmp (arg, "-"))
+       getl_clear_include_path (ss);
+      else
+       getl_add_include_dir (ss, arg);
+      break;
+    case 'r':
+      sip->process_statrc = false;
+      break;
+    case ARGP_KEY_SUCCESS:
+      if (sip->process_statrc)
+       {
+         char *pspprc_fn = fn_search_path ("rc", config_path);
+         if (pspprc_fn != NULL)
+           {
+             getl_append_source (ss,
+                                 create_syntax_file_source (pspprc_fn),
+                                 GETL_BATCH,
+                                 ERRMODE_CONTINUE
+                                 );
+
+             free (pspprc_fn);
+           }
+       }
+      break;
+    case 's':
+      settings_set_safer_mode ();
+      break;
+    case 'x':
+      if ( 0 == strcmp (arg, "compatible") )
+       settings_set_syntax (COMPATIBLE);
+      else if ( 0 == strcmp (arg, "enhanced"))
+       settings_set_syntax (ENHANCED);
+      else
+       {
+         argp_failure (state, 1, 0, _("Syntax must be either \"compatible\" or \"enhanced\"."));
+       }
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+const struct argp post_init_argp =
+  {post_init_options, parse_post_init_opts, 0, 0, 0, 0, 0};
+
diff --git a/src/ui/source-init-opts.h b/src/ui/source-init-opts.h
new file mode 100644 (file)
index 0000000..8749353
--- /dev/null
@@ -0,0 +1,24 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef SOURCE_INIT_OPTS
+#define SOURCE_INIT_OPTS
+
+extern const struct argp post_init_argp;
+
+#endif
+
index 501f1f37ffb2b2a61a919cd140ee9d23361cfca9..244e528b0748cd349c1481d3856aff5990c98e8a 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <libpspp/compiler.h>
+#include <libpspp/str.h>
 
 struct fmt_spec;
 struct substring;
diff --git a/src/ui/terminal/ChangeLog b/src/ui/terminal/ChangeLog
deleted file mode 100644 (file)
index a5ad36d..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-2008-05-15  Ben Pfaff  <blp@gnu.org>
-
-       * Use unilbrk.h instead of linebreak.h and ulc_width_linebreaks
-       instead of mbs_width_linebreaks for compatibility with latest
-       gnulib.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * main.c (main): Use at_fatal_signal instead of calling signal
-       directly.
-       (interrupt_handler) Removed.
-       (terminate) Rename clean_up.  Don't call exit directly.
-
-2007-09-25  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6210: implement ability to resize output device parameters
-       to fit terminal window size as it changes.  Reviewed by John
-       Darrington.
-       
-       * automake.mk (src_ui_terminal_libui_a_SOURCES): Add new files.
-
-       * terminal.c: New file.
-
-       * terminal.h: New file.
-
-       * main.c (main): No need to set up SIGWINCH handler any longer.
-       But we do need to call terminal_init.
-       (set_fallback_viewport): Move to terminal.c.
-       [HAVE_LIBNCURSES] (get_termcap_viewport): Ditto.
-       [!HAVE_LIBNCURSES] (get_termcap_viewport): Ditto.
-
-       * read-line.c (readln_read): After the first line of a command,
-       call terminal_check_size to allow it to re-detect the terminal
-       size.
-
-2007-09-24  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6210.  Reviewed by John Darrington.
-       * main.c (set_fallback_viewport): Make code easier to understand.
-       (get_termcap_viewport): Ditto.
-
-       * command-line.c (parse_command_line): Don't call force_long_view,
-       as that function is no longer necessary.
-
-       * msg-ui.c (handle_msg): Only wrap message output to the message
-       file to the width of the terminal if the message file is a tty.
-
-2007-09-19  John Darrington <john@darrington.wattle.id.au>
-
-       * main.c: Moved get_termcap_viewport from src/data/settings.c 
-       Added a handler for SIGWINCH to call this function.  Adjusted
-       init_settings to suit new interface. 
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * main.c (i18_init): Set up LC_PAPER locale, if available.  Don't
-       bother with LC_MONETARY locale, since we don't use it anywhere.
-
-2007-08-26  Ben Pfaff  <blp@gnu.org>
-
-       Bug #17238.  Thanks to John Darrington for review.
-
-       * main.c (main): When testing mode is enabled, use a built-in
-       output driver configuration instead of reading it from the
-       configuration file.
-
-       * msg-ui.c (handle_msg): Send error message to non-screen output
-       devices also, if routing to listing files is enabled.
-
-2007-08-23  Ben Pfaff  <blp@gnu.org>
-
-       Implement journaling.  Bug #17240.
-       
-       * msg-ui.c (handle_msg): Send message to write_journal function
-       as well as msg_file.
-       (dump_message): Change interface so that it takes a function
-       pointer instead of a FILE.
-       (write_stream): New function.
-       (write_journal): New function.
-       
-       * read-line.c (welcome): Call journal_enable, so that the journal
-       is enabled by default.
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Make interactive output go to the terminal (bug #17213), by
-       causing the UI to flush output to the user when it prompts for a
-       command.
-
-       * command-line.c (parse_command_line): Configure interactive
-       output devices if appropriate.
-
-       * read-line.c (readln_read): Flush output if this is a prompt for
-       the first line of a command.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       Adapt case sources, sinks, and clients of procedure code to the
-       new infrastructure.
-       
-       * main.c: No need for fastfile_factory any more.
-
-2007-02-25  Ben Pfaff  <blp@gnu.org>
-
-       Thanks to Jason Stover for verifying that this patch helps under
-       NetBSD.
-
-       * main.c [HAVE_IEEE_FP]: Include <ieeefp.h>.
-       (fpu_init) [HAVE_IEEE_FP]: Use setfpmask to mask floating-point
-       exceptions.
-
-Sun Feb 18 13:28:26 2007  Ben Pfaff  <blp@gnu.org>
-
-       * msg-ui.c: Don't include exit.h, because gnulib fixes up stdlib.h
-       as necessary.  Do include stdlib.h, because exit.h did so for us
-       and we need it.
-
-Thu Feb  8 15:07:04 2007  Ben Pfaff  <blp@gnu.org>
-
-       * read-line.c (readln_initialize): Instead of only supporting
-       history in unix, always support history, and only support a
-       history file when $HOME is defined.
-       (readln_uninitialize): Ditto.
-       (welcome) Call readln_initialize instead of duplicating code.
-
-Sun Dec 10 11:13:53 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command-line.c (pre_syntax_message): Use term "syntax" instead
-       of "script".
-
-Sat Dec  9 07:21:02 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * msg-ui.c (msg_ui_done): call msg_locator_done.
-
-Sun Dec  3 11:57:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       * read-line.c (read_interactive): Always read GETL_INTERACTIVE
-       lines.
-       
-Thu Nov 16 20:46:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * main.c: Connect debugger on errors.
-
-Tue Nov  7 20:54:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * command-line.c msg-ui.c msg-ui.h main.c: Added an -e
-       option to set the file for error messages.
-
-Sat Nov  4 15:48:04 2006  Ben Pfaff  <blp@gnu.org>
-
-       * msg-ui.c (handle_msg): Only write message to terminal if
-       get_error_routing_to_terminal() returns true.
-
-Fri Jul  7 20:03:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * main.c: (main) Register SIGABRT with bug_handler also.
-       (bug_handler) Handle SIGABRT also.
-
-Tue Jun 27 22:44:56 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix regression in command name completion reported by John
-       Darrington.  Now completion is again state-dependent and occurs
-       only on the first line of a command.
-       
-       * main.c (main): Reading of first token in command moved into
-       cmd_parse.
-       (execute_command) Removed.
-
-       * read-line.c: [HAVE_READLINE] (readln_initialize) Postpone
-       setting rl_attempted_completion_function until readln_read.
-       [HAVE_READLINE] (readln_read) Change param from const char * to
-       enum getl_prompt_style.  Set rl_attempted_completion_function
-       based on style.
-       [HAVE_READLINE] (complete_command_name) New function.
-       [HAVE_READLINE] (dont_complete) New function.
-       [HAVE_READLINE] (command_generator) New function.
-
-Tue Jun 27 08:23:07 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (src_ui_terminal_pspp_LDADD): Add $(LIBICONV).
-       Thanks to Jason Stover for reporting the omission.
-
-Thu May  4 21:50:59 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, move
-       procedure.c and procedure.h from src to src/data.  Update
-       makefiles and #includes accordingly.
-
-       * automake.mk: (src_ui_terminal_pspp_SOURCES) Remove
-       src/procedure.c and src/procedure.h.
-       (src_ui_terminal_pspp_LDADD) Move libexpressions.a later in list
-       to make the link work.
-
-Wed May  3 23:09:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming procedure execution.  In this phase, get rid of
-       many global variables, consolidating procedure execution in
-       procedure.c.  Encapsulate transformations in new "struct
-       trns_chain".  Also, change implementation of N OF CASES, FILTER,
-       and PROCESS IF from special cases to transformations.
-        
-       * main.c: (main) Use proc_init().
-       (terminate) Use proc_done().
-
-Wed Apr 26 13:34:54 2006  Ben Pfaff  <blp@gnu.org>
-
-       Improve command name completion in readline.
-       
-       * read-line.c (readln_initialize): Set up readline to only break
-       words for completion at new-line.  That way we can complete a
-       whole command name.  Also, set rl_attempted_completion_function
-       instead of rl_completion_entry_function so we can disable
-       completing on file names, which is usually not what we want in
-       PSPP.
-
-Wed Apr 26 13:31:00 2006  Ben Pfaff  <blp@gnu.org>
-
-       Improve the way we handle the various parsing "states".  Until now
-       we've hard-coded the state transitions in the command definition
-       file, but that's error-prone and, worse, it's redundant--we can
-       figure out what state we're in anyhow.  We can cleanly handle
-       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
-       
-       * automake.mk (src_ui_terminal_pspp_LDADD): Move libui earlier to
-       avoid link errors.
-
-       * main.c (main): Handle new CMD_* results.
-       (execute_command) Move most per-command actions into cmd_parse().
-       (handle_error) Removed.  cmd_parse() handles command failure.
-
-Tue Apr 25 11:08:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       Finish reforming error message support.  In this phase, move
-       message.c into libpspp.
-       
-       * automake.mk: Remove message.c from sources.
-
-Tue Apr 25 10:58:19 2006  Ben Pfaff  <blp@gnu.org>
-
-       Continue reforming error message support.  In this phase, drop
-       actual message printing from core code, substituting a callback,
-       and add the callback to each UI.  Also, move verbose_msg() into
-       its own module.
-
-       * automake.mk (src_ui_terminal_libui_a_SOURCES): Add msg-ui.c,
-       msg-ui.h.
-
-       * command-line.c: (parse_command_line) Call
-       verbose_increment_level() instead of increment err_verbosity
-       directly, now that we have a little abstraction.
-
-       * msg-ui.c: New file.
-
-       * msg-ui.h: New file.
-
-       * main.c: (main) Call msg_ui_init().  Use any_errors().
-       (terminate) Call msg_ui_done().  Make termination order more
-       rational.
-
-       * read-line.c: (readln_read) Use reset_msg_count() now we have a
-       little abstraction.
-
-Tue Apr 25 09:39:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       * main.c: (terminate) Mark static and NO_RETURN.  If called
-       recursively, which can only happen via signal, just exit instead
-       of trying to gracefully shut down.      
-
-Fri Mar 31 10:33:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command-line.c: (var pre_syntax_message) -d and -u are no longer
-       supported.
-
-Sat Mar 11 14:18:39 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * automake.mk: Moved the pspp binary here.
-
-Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
-       
-       * Moved files from src directory
diff --git a/src/ui/terminal/OChangeLog b/src/ui/terminal/OChangeLog
new file mode 100644 (file)
index 0000000..a5ad36d
--- /dev/null
@@ -0,0 +1,284 @@
+2008-05-15  Ben Pfaff  <blp@gnu.org>
+
+       * Use unilbrk.h instead of linebreak.h and ulc_width_linebreaks
+       instead of mbs_width_linebreaks for compatibility with latest
+       gnulib.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * main.c (main): Use at_fatal_signal instead of calling signal
+       directly.
+       (interrupt_handler) Removed.
+       (terminate) Rename clean_up.  Don't call exit directly.
+
+2007-09-25  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6210: implement ability to resize output device parameters
+       to fit terminal window size as it changes.  Reviewed by John
+       Darrington.
+       
+       * automake.mk (src_ui_terminal_libui_a_SOURCES): Add new files.
+
+       * terminal.c: New file.
+
+       * terminal.h: New file.
+
+       * main.c (main): No need to set up SIGWINCH handler any longer.
+       But we do need to call terminal_init.
+       (set_fallback_viewport): Move to terminal.c.
+       [HAVE_LIBNCURSES] (get_termcap_viewport): Ditto.
+       [!HAVE_LIBNCURSES] (get_termcap_viewport): Ditto.
+
+       * read-line.c (readln_read): After the first line of a command,
+       call terminal_check_size to allow it to re-detect the terminal
+       size.
+
+2007-09-24  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6210.  Reviewed by John Darrington.
+       * main.c (set_fallback_viewport): Make code easier to understand.
+       (get_termcap_viewport): Ditto.
+
+       * command-line.c (parse_command_line): Don't call force_long_view,
+       as that function is no longer necessary.
+
+       * msg-ui.c (handle_msg): Only wrap message output to the message
+       file to the width of the terminal if the message file is a tty.
+
+2007-09-19  John Darrington <john@darrington.wattle.id.au>
+
+       * main.c: Moved get_termcap_viewport from src/data/settings.c 
+       Added a handler for SIGWINCH to call this function.  Adjusted
+       init_settings to suit new interface. 
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * main.c (i18_init): Set up LC_PAPER locale, if available.  Don't
+       bother with LC_MONETARY locale, since we don't use it anywhere.
+
+2007-08-26  Ben Pfaff  <blp@gnu.org>
+
+       Bug #17238.  Thanks to John Darrington for review.
+
+       * main.c (main): When testing mode is enabled, use a built-in
+       output driver configuration instead of reading it from the
+       configuration file.
+
+       * msg-ui.c (handle_msg): Send error message to non-screen output
+       devices also, if routing to listing files is enabled.
+
+2007-08-23  Ben Pfaff  <blp@gnu.org>
+
+       Implement journaling.  Bug #17240.
+       
+       * msg-ui.c (handle_msg): Send message to write_journal function
+       as well as msg_file.
+       (dump_message): Change interface so that it takes a function
+       pointer instead of a FILE.
+       (write_stream): New function.
+       (write_journal): New function.
+       
+       * read-line.c (welcome): Call journal_enable, so that the journal
+       is enabled by default.
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Make interactive output go to the terminal (bug #17213), by
+       causing the UI to flush output to the user when it prompts for a
+       command.
+
+       * command-line.c (parse_command_line): Configure interactive
+       output devices if appropriate.
+
+       * read-line.c (readln_read): Flush output if this is a prompt for
+       the first line of a command.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       Adapt case sources, sinks, and clients of procedure code to the
+       new infrastructure.
+       
+       * main.c: No need for fastfile_factory any more.
+
+2007-02-25  Ben Pfaff  <blp@gnu.org>
+
+       Thanks to Jason Stover for verifying that this patch helps under
+       NetBSD.
+
+       * main.c [HAVE_IEEE_FP]: Include <ieeefp.h>.
+       (fpu_init) [HAVE_IEEE_FP]: Use setfpmask to mask floating-point
+       exceptions.
+
+Sun Feb 18 13:28:26 2007  Ben Pfaff  <blp@gnu.org>
+
+       * msg-ui.c: Don't include exit.h, because gnulib fixes up stdlib.h
+       as necessary.  Do include stdlib.h, because exit.h did so for us
+       and we need it.
+
+Thu Feb  8 15:07:04 2007  Ben Pfaff  <blp@gnu.org>
+
+       * read-line.c (readln_initialize): Instead of only supporting
+       history in unix, always support history, and only support a
+       history file when $HOME is defined.
+       (readln_uninitialize): Ditto.
+       (welcome) Call readln_initialize instead of duplicating code.
+
+Sun Dec 10 11:13:53 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command-line.c (pre_syntax_message): Use term "syntax" instead
+       of "script".
+
+Sat Dec  9 07:21:02 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * msg-ui.c (msg_ui_done): call msg_locator_done.
+
+Sun Dec  3 11:57:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       * read-line.c (read_interactive): Always read GETL_INTERACTIVE
+       lines.
+       
+Thu Nov 16 20:46:35 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * main.c: Connect debugger on errors.
+
+Tue Nov  7 20:54:32 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * command-line.c msg-ui.c msg-ui.h main.c: Added an -e
+       option to set the file for error messages.
+
+Sat Nov  4 15:48:04 2006  Ben Pfaff  <blp@gnu.org>
+
+       * msg-ui.c (handle_msg): Only write message to terminal if
+       get_error_routing_to_terminal() returns true.
+
+Fri Jul  7 20:03:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * main.c: (main) Register SIGABRT with bug_handler also.
+       (bug_handler) Handle SIGABRT also.
+
+Tue Jun 27 22:44:56 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix regression in command name completion reported by John
+       Darrington.  Now completion is again state-dependent and occurs
+       only on the first line of a command.
+       
+       * main.c (main): Reading of first token in command moved into
+       cmd_parse.
+       (execute_command) Removed.
+
+       * read-line.c: [HAVE_READLINE] (readln_initialize) Postpone
+       setting rl_attempted_completion_function until readln_read.
+       [HAVE_READLINE] (readln_read) Change param from const char * to
+       enum getl_prompt_style.  Set rl_attempted_completion_function
+       based on style.
+       [HAVE_READLINE] (complete_command_name) New function.
+       [HAVE_READLINE] (dont_complete) New function.
+       [HAVE_READLINE] (command_generator) New function.
+
+Tue Jun 27 08:23:07 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (src_ui_terminal_pspp_LDADD): Add $(LIBICONV).
+       Thanks to Jason Stover for reporting the omission.
+
+Thu May  4 21:50:59 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, move
+       procedure.c and procedure.h from src to src/data.  Update
+       makefiles and #includes accordingly.
+
+       * automake.mk: (src_ui_terminal_pspp_SOURCES) Remove
+       src/procedure.c and src/procedure.h.
+       (src_ui_terminal_pspp_LDADD) Move libexpressions.a later in list
+       to make the link work.
+
+Wed May  3 23:09:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming procedure execution.  In this phase, get rid of
+       many global variables, consolidating procedure execution in
+       procedure.c.  Encapsulate transformations in new "struct
+       trns_chain".  Also, change implementation of N OF CASES, FILTER,
+       and PROCESS IF from special cases to transformations.
+        
+       * main.c: (main) Use proc_init().
+       (terminate) Use proc_done().
+
+Wed Apr 26 13:34:54 2006  Ben Pfaff  <blp@gnu.org>
+
+       Improve command name completion in readline.
+       
+       * read-line.c (readln_initialize): Set up readline to only break
+       words for completion at new-line.  That way we can complete a
+       whole command name.  Also, set rl_attempted_completion_function
+       instead of rl_completion_entry_function so we can disable
+       completing on file names, which is usually not what we want in
+       PSPP.
+
+Wed Apr 26 13:31:00 2006  Ben Pfaff  <blp@gnu.org>
+
+       Improve the way we handle the various parsing "states".  Until now
+       we've hard-coded the state transitions in the command definition
+       file, but that's error-prone and, worse, it's redundant--we can
+       figure out what state we're in anyhow.  We can cleanly handle
+       INPUT PROGRAM and FILE TYPE with a nested command-processing loop.
+       
+       * automake.mk (src_ui_terminal_pspp_LDADD): Move libui earlier to
+       avoid link errors.
+
+       * main.c (main): Handle new CMD_* results.
+       (execute_command) Move most per-command actions into cmd_parse().
+       (handle_error) Removed.  cmd_parse() handles command failure.
+
+Tue Apr 25 11:08:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       Finish reforming error message support.  In this phase, move
+       message.c into libpspp.
+       
+       * automake.mk: Remove message.c from sources.
+
+Tue Apr 25 10:58:19 2006  Ben Pfaff  <blp@gnu.org>
+
+       Continue reforming error message support.  In this phase, drop
+       actual message printing from core code, substituting a callback,
+       and add the callback to each UI.  Also, move verbose_msg() into
+       its own module.
+
+       * automake.mk (src_ui_terminal_libui_a_SOURCES): Add msg-ui.c,
+       msg-ui.h.
+
+       * command-line.c: (parse_command_line) Call
+       verbose_increment_level() instead of increment err_verbosity
+       directly, now that we have a little abstraction.
+
+       * msg-ui.c: New file.
+
+       * msg-ui.h: New file.
+
+       * main.c: (main) Call msg_ui_init().  Use any_errors().
+       (terminate) Call msg_ui_done().  Make termination order more
+       rational.
+
+       * read-line.c: (readln_read) Use reset_msg_count() now we have a
+       little abstraction.
+
+Tue Apr 25 09:39:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       * main.c: (terminate) Mark static and NO_RETURN.  If called
+       recursively, which can only happen via signal, just exit instead
+       of trying to gracefully shut down.      
+
+Fri Mar 31 10:33:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command-line.c: (var pre_syntax_message) -d and -u are no longer
+       supported.
+
+Sat Mar 11 14:18:39 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * automake.mk: Moved the pspp binary here.
+
+Thu Mar  2 08:40:33 WST 2006 John Darrington <john@darrington.wattle.id.au>
+       
+       * Moved files from src directory
index ae6d3a5e2d72af46d7d30dae304987708f71106a..598cdddd8eefaeea38196d188be9e33baeda36f0 100644 (file)
@@ -1,48 +1,39 @@
 ## Process this file with automake to produce Makefile.in  -*- makefile -*-
 
-noinst_LIBRARIES += src/ui/terminal/libui.a
+noinst_LTLIBRARIES += src/ui/terminal/libui.la
 
-src_ui_terminal_libui_a_SOURCES = \
-       src/ui/terminal/command-line.c \
-       src/ui/terminal/command-line.h \
+src_ui_terminal_libui_la_SOURCES = \
        src/ui/terminal/read-line.c \
        src/ui/terminal/read-line.h \
        src/ui/terminal/main.c \
        src/ui/terminal/msg-ui.c \
        src/ui/terminal/msg-ui.h \
        src/ui/terminal/terminal.c \
-       src/ui/terminal/terminal.h      
+       src/ui/terminal/terminal.h \
+       src/ui/terminal/terminal-opts.c \
+       src/ui/terminal/terminal-opts.h 
 
-src_ui_terminal_libui_a_CFLAGS = -DINSTALLDIR=\"$(bindir)\" $(NCURSES_CFLAGS)
 
-bin_PROGRAMS += src/ui/terminal/pspp
+src_ui_terminal_libui_la_CFLAGS = -DINSTALLDIR=\"$(bindir)\" $(NCURSES_CFLAGS)
 
+bin_PROGRAMS += src/ui/terminal/pspp
 
 src_ui_terminal_pspp_SOURCES =
 
 src_ui_terminal_pspp_LDADD = \
-       src/ui/terminal/libui.a \
-       src/language/liblanguage.a \
-       src/output/charts/libcharts.a \
-       src/output/liboutput.a \
-       src/math/libpspp_math.a  \
-       src/ui/libuicommon.a \
-       lib/linreg/liblinreg.a  \
-       lib/gsl-extras/libgsl-extras.a  \
-       src/data/libdata.a \
-       src/libpspp/libpspp.a \
-       $(LIBXML2_LIBS) \
-       $(PG_LIBS) \
+       src/ui/terminal/libui.la \
+       src/ui/libuicommon.la \
+       src/libpspp.la \
+       src/libpspp-core.la \
        $(NCURSES_LIBS) \
        $(LIBICONV) \
-       gl/libgl.la \
        @LIBINTL@ @LIBREADLINE@
 
 
-
-
 src_ui_terminal_pspp_LDFLAGS = $(PG_LDFLAGS)
 
 if RELOCATABLE_VIA_LD
 src_ui_terminal_pspp_LDFLAGS += `$(RELOCATABLE_LDFLAGS) $(bindir)`
 endif
+
+EXTRA_DIST += src/ui/terminal/OChangeLog
diff --git a/src/ui/terminal/command-line.c b/src/ui/terminal/command-line.c
deleted file mode 100644 (file)
index 95b22ce..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "command-line.h"
-#include "msg-ui.h"
-#include <libpspp/message.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <errno.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <libpspp/assertion.h>
-#include <libpspp/copyleft.h>
-#include <libpspp/message.h>
-#include <language/syntax-file.h>
-#include "progname.h"
-#include <data/settings.h>
-#include <output/output.h>
-#include <data/file-name.h>
-#include <libpspp/getl.h>
-#include <libpspp/str.h>
-#include <libpspp/version.h>
-#include <libpspp/verbose-msg.h>
-#include "read-line.h"
-
-#include "xalloc.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-static void usage (void);
-
-/* Parses the command line specified by ARGC and ARGV as received by
-   main().  Returns true if normal execution should proceed,
-   false if the command-line indicates that PSPP should exit. */
-bool
-parse_command_line (int argc, char **argv, struct source_stream *ss)
-{
-  static struct option long_options[] =
-  {
-    {"algorithm", required_argument, NULL, 'a'},
-    {"command", required_argument, NULL, 'c'},
-    {"config-directory", required_argument, NULL, 'B'},
-    {"device", required_argument, NULL, 'o'},
-    {"dry-run", no_argument, NULL, 'n'},
-    {"edit", no_argument, NULL, 'n'},
-    {"error-file", required_argument, NULL, 'e'},
-    {"help", no_argument, NULL, 'h'},
-    {"include-directory", required_argument, NULL, 'I'},
-    {"interactive", no_argument, NULL, 'i'},
-    {"just-print", no_argument, NULL, 'n'},
-    {"list", no_argument, NULL, 'l'},
-    {"no-include", no_argument, NULL, 'I'},
-    {"no-statrc", no_argument, NULL, 'r'},
-    {"out-file", required_argument, NULL, 'f'},
-    {"pipe", no_argument, NULL, 'p'},
-    {"recon", no_argument, NULL, 'n'},
-    {"safer", no_argument, NULL, 's'},
-    {"syntax", required_argument, NULL, 'x'},
-    {"testing-mode", no_argument, NULL, 'T'},
-    {"verbose", no_argument, NULL, 'v'},
-    {"version", no_argument, NULL, 'V'},
-    {0, 0, 0, 0},
-  };
-
-  int c, i;
-
-  bool cleared_device_defaults = false;
-  bool process_statrc = true;
-  bool interactive_mode = false;
-  int syntax_files = 0;
-
-  for (;;)
-    {
-      c = getopt_long (argc, argv, "a:x:B:c:e:f:hiI:lno:prsvV", long_options, NULL);
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-         /* Compatibility options */
-        case 'a':
-         if ( 0 == strcmp(optarg,"compatible") )
-             settings_set_algorithm(COMPATIBLE);
-         else if ( 0 == strcmp(optarg,"enhanced"))
-             settings_set_algorithm(ENHANCED);
-         else
-           {
-             usage ();
-              return false;
-           }
-         break;
-
-       case 'x':
-         if ( 0 == strcmp(optarg,"compatible") )
-           settings_set_syntax (COMPATIBLE);
-         else if ( 0 == strcmp(optarg,"enhanced"))
-           settings_set_syntax (ENHANCED);
-         else
-           {
-             usage ();
-              return false;
-           }
-         break;
-       case 'e':
-         msg_ui_set_error_file (optarg);
-         break;
-       case 'B':
-         config_path = optarg;
-         break;
-       case 'f':
-         printf (_("%s is not yet implemented."), "-f");
-          putchar('\n');
-         break;
-       case 'h':
-         usage ();
-          return false;
-       case 'i':
-         interactive_mode = true;
-         break;
-       case 'I':
-         if (optarg == NULL || !strcmp (optarg, "-"))
-           getl_clear_include_path (ss);
-         else
-           getl_add_include_dir (ss, optarg);
-         break;
-       case 'l':
-         outp_list_classes ();
-          return false;
-       case 'n':
-         printf (_("%s is not yet implemented."),"-n");
-          putchar('\n');
-         break;
-       case 'o':
-         if (!cleared_device_defaults)
-           {
-             outp_configure_clear ();
-             cleared_device_defaults = true;
-           }
-         outp_configure_add (optarg);
-         break;
-       case 'p':
-         printf (_("%s is not yet implemented."),"-p");
-          putchar('\n');
-         break;
-       case 'r':
-         process_statrc = false;
-         break;
-       case 's':
-         settings_set_safer_mode ();
-         break;
-       case 'v':
-         verbose_increment_level ();
-         break;
-       case 'V':
-         puts (version);
-         puts (legal);
-         return false;
-        case 'T':
-          settings_set_testing_mode (true);
-          break;
-       case '?':
-         usage ();
-          return false;
-       case 0:
-         break;
-       default:
-         NOT_REACHED ();
-       }
-    }
-
-  if (process_statrc)
-    {
-      char *pspprc_fn = fn_search_path ("rc", config_path);
-      if (pspprc_fn != NULL)
-        {
-         getl_append_source (ss,
-                             create_syntax_file_source (pspprc_fn),
-                             GETL_BATCH,
-                             ERRMODE_CONTINUE
-                             );
-
-          free (pspprc_fn);
-        }
-    }
-
-  for (i = optind; i < argc; i++)
-    if (strchr (argv[i], '='))
-      outp_configure_macro (argv[i]);
-    else
-      {
-       getl_append_source (ss,
-                           create_syntax_file_source (argv[i]),
-                           GETL_BATCH,
-                           ERRMODE_CONTINUE
-                           );
-        syntax_files++;
-      }
-
-  if (!syntax_files || interactive_mode)
-    {
-      getl_append_source (ss, create_readln_source (),
-                         GETL_INTERACTIVE,
-                         ERRMODE_CONTINUE
-                         );
-      if (!cleared_device_defaults)
-        outp_configure_add ("interactive");
-    }
-
-  return true;
-}
-
-/* Message that describes PSPP command-line syntax. */
-static const char pre_syntax_message[] =
-N_("PSPP, a program for statistical analysis of sample data.\n"
-"\nUsage: %s [OPTION]... FILE...\n"
-"\nIf a long option shows an argument as mandatory, then it is mandatory\n"
-"for the equivalent short option also.  Similarly for optional arguments.\n"
-"\nConfiguration:\n"
-"  -a, --algorithm={compatible|enhanced}\n"
-"                            set to `compatible' if you want output\n"
-"                            calculated from broken algorithms\n"
-"  -B, --config-dir=DIR      set configuration directory to DIR\n"
-"  -o, --device=DEVICE       select output driver DEVICE and disable defaults\n"
-"\nInput and output:\n"
-"  -e, --error-file=FILE     send error messages to FILE (appended)\n"
-"  -f, --out-file=FILE       send output to FILE (overwritten)\n"
-"  -p, --pipe                read syntax from stdin, send output to stdout\n"
-"  -I-, --no-include         clear include path\n"
-"  -I, --include=DIR         append DIR to include path\n"
-"\nLanguage modifiers:\n"
-"  -i, --interactive         interpret syntax in interactive mode\n"
-"  -n, --edit                just check syntax; don't actually run the code\n"
-"  -r, --no-statrc           disable execution of .pspp/rc at startup\n"
-"  -s, --safer               don't allow some unsafe operations\n"
-"  -x, --syntax={compatible|enhanced}\n"
-"                            set to `compatible' if you want only to accept\n"
-"                            spss compatible syntax\n"
-"\nInformative output:\n"
-"  -h, --help                print this help, then exit\n"
-"  -l, --list                print a list of known driver classes, then exit\n"
-"  -V, --version             show PSPP version, then exit\n"
-"  -v, --verbose             increments verbosity level\n"
-"\nNon-option arguments:\n"
-" FILE                       syntax file to execute\n"
-" KEY=VALUE                  overrides macros in output initialization file\n"
-"\n");
-
-/* Message that describes PSPP command-line syntax, continued. */
-static const char post_syntax_message[] = N_("\nReport bugs to <%s>.\n");
-
-/* Writes a syntax description to stdout. */
-static void
-usage (void)
-{
-  printf (gettext (pre_syntax_message), program_name);
-  outp_list_classes ();
-  printf (gettext (post_syntax_message), PACKAGE_BUGREPORT);
-}
diff --git a/src/ui/terminal/command-line.h b/src/ui/terminal/command-line.h
deleted file mode 100644 (file)
index 601c73c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-
-   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 3 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 General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
-
-#if !INCLUDED_CMDLINE_H
-#define INCLUDED_CMDLINE_H 1
-
-#include <stdbool.h>
-
-struct source_stream ;
-
-bool parse_command_line (int argc, char **argv, struct source_stream *);
-
-#endif /* cmdline.h */
index b8cabb3acb0fff818faf3e1de71766309b21f7ce..904c9a1dbc772bb1bcbf33d591124da8a41db9b6 100644 (file)
 #include <math/random.h>
 #include <output/output.h>
 #include <ui/debugger.h>
-#include <ui/terminal/command-line.h>
 #include <ui/terminal/msg-ui.h>
 #include <ui/terminal/read-line.h>
 #include <ui/terminal/terminal.h>
+#include <ui/terminal/terminal-opts.h>
+#include <ui/command-line.h>
+#include <ui/source-init-opts.h>
 
 #include "fatal-signal.h"
 #include "progname.h"
@@ -73,17 +75,21 @@ static struct dataset * the_dataset = NULL;
 static struct lexer *the_lexer;
 static struct source_stream *the_source_stream ;
 
+const char *argp_program_version = version;
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+
 /* Program entry point. */
 int
 main (int argc, char **argv)
 {
   int *view_width_p, *view_length_p;
-
+  struct command_line_processor *clp;
   set_program_name (argv[0]);
 
   signal (SIGABRT, bug_handler);
   signal (SIGSEGV, bug_handler);
   signal (SIGFPE, bug_handler);
+  signal (SIGALRM, SIG_IGN);
   at_fatal_signal (clean_up);
 
   i18n_init ();
@@ -105,37 +111,58 @@ main (int argc, char **argv)
 
   the_dataset = create_dataset ();
 
-  if (parse_command_line (argc, argv, the_source_stream))
+
+
+  clp = command_line_processor_create (_("PSPP --- A program for statistical analysis"),
+                                      _("FILE1, FILE2 ... FILEn"), NULL);
+
+  command_line_processor_add_options (clp, &io_argp,
+                                     _("Options affecting input and output locations:"), the_source_stream);
+
+  command_line_processor_add_options (clp, &test_argp,
+                                     _("Diagnositic options:"), the_source_stream);
+
+  command_line_processor_add_options (clp, &post_init_argp,
+                                     _("Options affecting syntax and behavior:"), the_source_stream);
+
+  command_line_processor_parse (clp, argc, argv);
+
+  msg_ui_init (the_source_stream);
+
+  if (!settings_get_testing_mode ())
+    {
+      outp_read_devices ();
+    }
+  else
+    {
+      outp_configure_driver_line
+       (
+        ss_cstr ("raw-ascii:ascii:listing:width=9999 length=9999 "
+                 "output-file=\"pspp.list\" emphasis=none "
+                 "headers=off paginate=off squeeze=on "
+                 "top-margin=0 bottom-margin=0"));
+    }
+
+  the_lexer = lex_create (the_source_stream);
+
+  for (;;)
     {
-      msg_ui_init (the_source_stream);
-      if (!settings_get_testing_mode ())
-        outp_read_devices ();
+      int result = cmd_parse (the_lexer, the_dataset);
+
+      if (result == CMD_EOF || result == CMD_FINISH)
+       break;
+      if (result == CMD_CASCADING_FAILURE &&
+         !getl_is_interactive (the_source_stream))
+       {
+         msg (SE, _("Stopping syntax file processing here to avoid "
+                    "a cascade of dependent command failures."));
+         getl_abort_noninteractive (the_source_stream);
+       }
       else
-        outp_configure_driver_line (
-          ss_cstr ("raw-ascii:ascii:listing:width=9999 length=9999 "
-                   "output-file=\"pspp.list\" emphasis=none "
-                   "headers=off paginate=off squeeze=on "
-                   "top-margin=0 bottom-margin=0"));
-      the_lexer = lex_create (the_source_stream);
-
-      for (;;)
-        {
-          int result = cmd_parse (the_lexer, the_dataset);
-
-          if (result == CMD_EOF || result == CMD_FINISH)
-            break;
-          if (result == CMD_CASCADING_FAILURE &&
-             !getl_is_interactive (the_source_stream))
-            {
-              msg (SE, _("Stopping syntax file processing here to avoid "
-                         "a cascade of dependent command failures."));
-              getl_abort_noninteractive (the_source_stream);
-            }
-          else
-            check_msg_count (the_source_stream);
-        }
+       check_msg_count (the_source_stream);
     }
 
+
   clean_up ();
   return any_errors ();
 }
index b03efb95e5712456cc5929dd42ab7f61cb75d3c4..682d753d8fbd36200f68e33677c239e5ef5b6c17 100644 (file)
@@ -267,7 +267,7 @@ write_stream (int line_indent, struct substring line, void *stream_)
 
 /* Writes LINE to the journal. */
 static void
-write_journal (int line_indent, struct substring line, void *unused UNUSED)
+write_journal (int line_indent UNUSED, struct substring line, void *unused UNUSED)
 {
   char *s = xstrndup (ss_data (line), ss_length (line));
   journal_write (true, s);
diff --git a/src/ui/terminal/terminal-opts.c b/src/ui/terminal/terminal-opts.c
new file mode 100644 (file)
index 0000000..d2ddc6e
--- /dev/null
@@ -0,0 +1,198 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <argp.h>
+#include <stdbool.h>
+#include <xalloc.h>
+#include <stdlib.h>
+#include <data/settings.h>
+#include <output/output.h>
+#include "msg-ui.h"
+#include <ui/command-line.h>
+#include <libpspp/verbose-msg.h>
+#include <libpspp/llx.h>
+#include <data/file-name.h>
+#include "terminal-opts.h"
+#include <libpspp/getl.h>
+#include <language/syntax-file.h>
+#include "read-line.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+
+static const struct argp_option test_options [] =
+  {
+    {"verbose", 'v', 0, 0, N_("Increase diagnostic verbosity level"), 0},
+    {"testing-mode", 'T', 0, OPTION_HIDDEN, 0, 0},
+
+    { 0, 0, 0, 0, 0, 0 }
+  };
+
+static error_t
+parse_test_opts (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case 'T':
+      settings_set_testing_mode (true);
+      break;
+    case 'v':
+      verbose_increment_level ();
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+static const struct argp_option io_options [] =
+  {
+    {"error-file", 'e', "FILE", 0,
+     N_("Send error messages to FILE (appended)"), 0},
+
+    {"device", 'o', "DEVICE", 0,
+     N_("Select output driver DEVICE and disable defaults"), 0},
+
+    {"list", 'l', 0, 0,
+     N_("Print a list of known driver classes, then exit"), 0},
+
+    {"interactive", 'i', 0, 0, N_("Start an interactive session"), 0},
+
+    { 0, 0, 0, 0, 0, 0 }
+  };
+
+
+static error_t
+parse_io_opts (int key, char *arg, struct argp_state *state)
+{
+  struct source_init
+  {
+    struct llx_list file_list;
+    bool cleared_device_defaults;
+    bool interactive;
+  };
+
+  struct fn_element {
+    struct ll ll;
+    const char *fn;
+  };
+
+  struct source_init *sip = state->hook;
+
+  struct source_stream *ss = state->input;
+
+  struct command_line_processor *clp = get_subject (state);
+
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->hook = sip = xzalloc (sizeof (struct source_init));
+      llx_init (&sip->file_list);
+      break;
+    case ARGP_KEY_ARG:
+      if (strchr (arg, '='))
+       outp_configure_macro (arg);
+      else
+       {
+         llx_push_tail (&sip->file_list, arg, &llx_malloc_mgr);
+       }
+      break;
+    case ARGP_KEY_SUCCESS:
+      {
+      struct llx *llx = llx_null (&sip->file_list);
+      while ((llx = llx_next (llx)) != llx_null (&sip->file_list))
+       {
+         const char *fn = llx_data (llx);
+         /* Assume it's a syntax file */
+         getl_append_source (ss,
+                             create_syntax_file_source (fn),
+                             GETL_BATCH,
+                             ERRMODE_CONTINUE
+                             );
+
+       }
+
+      if (sip->interactive || llx_is_empty (&sip->file_list))
+       {
+         getl_append_source (ss, create_readln_source (),
+                             GETL_INTERACTIVE,
+                             ERRMODE_CONTINUE
+                             );
+
+         if (!sip->cleared_device_defaults)
+           outp_configure_add ("interactive");
+       }
+      }
+      break;
+    case ARGP_KEY_FINI:
+      free (sip);
+      break;
+    case 'e':
+      msg_ui_set_error_file (arg);
+      break;
+    case 'i':
+      sip->interactive = true;
+      break;
+    case 'l':
+      outp_list_classes ();
+      break;
+    case 'o':
+      if (! sip->cleared_device_defaults)
+       {
+         outp_configure_clear ();
+         sip->cleared_device_defaults = true;
+       }
+      outp_configure_add (arg);
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+const struct argp io_argp =  {io_options, parse_io_opts, 0, 0, 0, 0, 0};
+const struct argp test_argp =  {test_options, parse_test_opts, 0, 0, 0, 0, 0};
+
+#if 0
+static const struct argp_child children [] =
+  {
+    {&io_argp, 0, N_("Options affecting input and output locations:"), 0},
+    {&test_argp, 0, N_("Diagnostic options:"), 0},
+    {0, 0, 0, 0}
+  };
+
+
+static error_t
+propagate_aux (int key, char *arg, struct argp_state *state)
+{
+  if ( key == ARGP_KEY_INIT)
+    {
+      int i;
+      for (i = 0 ; i < sizeof (children) / sizeof (children[0]) - 1 ; ++i)
+       state->child_inputs[i] = state->input;
+    }
+
+  return ARGP_ERR_UNKNOWN;
+}
+
+const struct argp terminal_argp =  {NULL, propagate_aux, 0, 0, children, 0, 0};
+
+#endif
diff --git a/src/ui/terminal/terminal-opts.h b/src/ui/terminal/terminal-opts.h
new file mode 100644 (file)
index 0000000..e5d032d
--- /dev/null
@@ -0,0 +1,27 @@
+/* PSPPIRE - a graphical user interface for PSPP.
+   Copyright (C) 2008  Free Software Foundation
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef TERMINAL_OPTS
+#define TERMINAL_OPTS
+
+extern const struct argp io_argp ;
+extern const struct argp test_argp ;
+
+extern const struct argp terminal_argp;
+
+#endif
+
diff --git a/tests/ChangeLog b/tests/ChangeLog
deleted file mode 100644 (file)
index 4742a1c..0000000
+++ /dev/null
@@ -1,1242 +0,0 @@
-2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
-
-       * regression.sh, regression-qr.sh: Fixed column showing
-       standardized coefficients.
-
-2008-05-16  John Darrington <john@darrington.wattle.id.au>
-
-       * compression.sh print-crash.sh print-strings.sh very-long-strings.sh :
-       Removed export VAR=VAL syntax.
-
-       * automake.mk:  Added test to check for non-portable shell syntax
-
-2008-04-14  Jason Stover  <jhs@math.gcsu.edu>
-
-       * automake.mk: New test for regression with QR decomposition.
-
-       * command/regression-qr.sh: New test for regression with QR decomposition.
-
-2008-03-16  Ben Pfaff  <blp@gnu.org>
-
-       Bug #22037.
-
-       * automake.mk: Add new test.
-
-       * bugs/crosstabs-crash2.sh: New test.
-
-2008-03-16  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6452.  Reviewed by John Darrington.
-
-       * automake.mk: Add new test.
-
-       * command/variable-display.sh: New test.
-
-2008-03-04  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6441.  Reviewed by John Darrington.
-
-       * automake.mk: Add new test.
-
-       * formats/format-guesser.sh: New test.
-
-2008-02-10  Ben Pfaff  <blp@gnu.org>
-
-       * command/get-data-txt-examples.sh: Update to match changes to
-       documentation (which were in turn updated to show how the escaped
-       quote feature works).
-
-2008-02-02  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add target for dissect-sysfile.
-
-       * dissect-sysfile.c: New program.
-
-2008-02-01  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new test.
-
-       * libpspp/str-test.c: New test.
-
-       * command/get-dat-gnm.sh: Update variable names to match new
-       naming scheme.
-
-2007-12-04  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new tests.
-
-       * command/get-data-txt.sh: New test.
-
-       * command/get-data-txt-examples.sh: New test.
-
-       * command/get-data-txt-importcases.sh: New test.
-
-2007-11-25  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/compression.sh: Don't fail on big-endian system.  Partial
-       fix for bug #21590.
-
-       * bugs/sysfile-info.sh: Disregard "Integer Format" and "Real
-       Format" lines in SYSFILE INFO output, to permit big-endian systems
-       to pass also.  Partial fix for bug #21590.
-
-2007-11-15  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add definition of CHARSETALIASDIR to
-       TESTS_ENVIRONMENT, to allow locale_charset to find charset.alias
-       before running "make install".
-
-2007-11-10  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/compression.sh: Pass -b option to diff to avoid spurious
-       failure on od.
-
-2007-11-08  Ben Pfaff  <blp@gnu.org>
-
-       Patch #6256: add support for binary, 360 file formats.  Reviewed
-       by John Darrington.
-
-       * automake.mk: Add new file.
-
-       * formats/360.sh: New test.
-
-2007-11-07  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/overwrite-input-file.sh: Don't use non-portable "diff -B".
-
-       * bugs/overwrite-special-file.sh: Ditto.
-
-       Reported by Jason Stover.
-
-2007-11-03  Ben Pfaff  <blp@gnu.org>
-
-       Allow output files to overwrite input files (bug #21280).
-
-       * automake.mk: Add new file.
-
-       * bugs/overwrite-input-file.sh: Rewrite to make sure that we can
-       overwrite input files safely.
-
-       * bugs/overwrite-special-file.sh: New test.
-
-       * command/erase.sh: Fix "activity" message.
-
-2007-11-03  John Darrington <john@darrington.wattle.id.au>
-
-       * Book1.gnm.unzipped command/get-data-gnm.sh: New test and data
-       for reading gnumeric files.
-
-2007-10-08  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21280.  Thanks to John Darrington for review.
-
-       * automake.mk: Add new file.
-
-       * bugs/overwrite-input-file.sh: New test.
-
-2007-09-23  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21111.  Reviewed by John Darrington.
-       
-       * command/input-program.sh: New test.
-
-       * command/do-if.sh: New tests.
-
-2007-09-22  Ben Pfaff  <blp@gnu.org>
-
-       Bug #21128.  Reviewed by John Darrington.
-
-       * output/paper-size.sh: New test.
-
-2007-09-21  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/unwritable-dir.sh: New test for bug #21117.
-
-2007-09-19  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/input-crash.sh: Add regression test for bug #21108.
-
-2007-09-04  Ben Pfaff  <blp@gnu.org>
-
-       Update scripts that invoke Perl to invoke it as simply "perl" if
-       not run from the PSPP Makefiles.  Patch #6169.  Thanks to John
-       Darrington for suggestion and review.
-       * bugs/big-input-2.sh: Make $PERL default to perl.
-       * command/sort.sh: Ditto.
-       * formats/bcd-in.sh: Ditto.
-       * formats/date-in.sh: Ditto.
-       * formats/ib-in.sh: Ditto.
-       * formats/legacy-in.sh: Ditto.
-       * formats/num-in.sh: Ditto.
-       * formats/num-out.sh: Ditto.
-       * formats/time-in.sh: Ditto.
-
-2007-08-26  Ben Pfaff  <blp@gnu.org>
-
-       * Updated most invocations of PSPP in the tests to use
-          --testing-mode and to avoid specifying an output format with -o
-         (because --testing-mode implies -o raw-ascii).
-
-2007-08-26  Ben Pfaff  <blp@gnu.org>
-
-       * command/aggregate.sh: Update output to include error messages,
-       which are now sent to output files also.
-
-       * command/ranks.h: Ditto.
-
-2007-08-12  Ben Pfaff  <blp@gnu.org>
-
-       * command/no_case_size.sh: Update to match update DISPLAY and
-       SYSFILE INFO command output.
-
-       * command/rank.sh: Ditto.
-
-       * command/sysfile-info.sh: Ditto.
-
-       * command/very-long-strings.sh: Ditto.
-
-2007-08-09  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #18982.  Thanks to John Darrington for investigation,
-       review, and verification of fix.
-       
-       * formats/date-in.sh: Use a portable pseudo-random number
-       generator.
-       
-       * formats/time-in.sh: Ditto.
-
-       * formats/num-in.sh: Ditto.
-
-2007-08-03  Ben Pfaff  <blp@gnu.org>
-
-       * command/rank.sh: Test RANK with noncontiguous groups of SPLIT
-       FILE variables and how they should behave differently from
-       noncontiguous groups of BY variables.  Regression test for bug
-       #17239.
-
-2007-08-01  Ben Pfaff  <blp@gnu.org>
-
-       * command/weight.sh: Update to match new output format for median
-       under FREQUENCIES.
-       
-       * stats/percentiles-compatible.sh: Ditto.
-
-       * stats/percentiles-enhanced.sh: Ditto.
-
-2007-07-28 John Darrington <john@darrington.wattle.id.au>
-
-       * command/t-test-1-indep-val.sh: Changed the order of groups in the 
-       summary box to match new behaviour. (Fixes bug #19604).
-
-2007-07-25  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #17100.
-       * command/data-list.sh: Add tests for multi-record DATA LIST with
-       and without empty trailing record.
-
-2007-07-24  Ben Pfaff  <blp@gnu.org>
-
-       * command/flip.sh: Add tests to avoid regression on bugs #20493,
-       #20494.
-
-2007-07-22  Ben Pfaff  <blp@gnu.org>
-
-       * command/very-long-strings.sh: Test both compressed and
-       uncompressed system files with very long strings.
-
-2007-07-17  Ben Pfaff  <blp@gnu.org>
-
-       Patch #19335.  Reviewed by John Darrington.
-
-       * expressions/randist/compare.pl: Use strict and all warnings.
-
-       * expressions/randist/randist.pl: Ditto.
-
-       * formats/num-out-cmp.pl: Ditto.
-
-       * formats/num-out-compare.pl: Ditto.
-
-       * formats/num-out-decmp.pl: Ditto.
-
-       * formats/num-out.pl: Ditto.
-
-2007-07-17  Ben Pfaff  <blp@gnu.org>
-
-       * formats/float-format.h: Drop the tests that depend on parsing
-       "-0" from a syntax file.  Also make float-format.sh error messages
-       easier to read, by changing the sed command so that error line
-       numbers are easier to match to the test input.
-       Reviewed by John Darrington as patch #6091.
-
-2007-07-11  Ben Pfaff  <blp@gnu.org>
-
-       * xforms/expressions.sh: Remove unused file.  Fixes bug
-       #18140.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * commands/match-files.sh: Test the new support for FIRST and LAST
-         subcommands.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Remove test.
-
-       * xforms/casefile.sh: Removed test.
-
-2007-06-06  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new test.
-
-       * command/datasheet.sh: New test.
-
-2007-06-03  Ben Pfaff  <blp@gnu.org>
-
-       * libpspp/tower-test.c: Also test tower_last, tower_prev functions.
-
-       * libpspp/range-set-test.c: Also test the range_set_clone function.
-
-2007-05-06  Ben Pfaff  <blp@gnu.org>
-
-       Abstract the documents within a dictionary a little better.
-       Thanks to John Darrington for suggestion, initial version, and
-       review.  Patch #5917.
-
-       * command/file-label.sh: Update to match new DOCUMENT behavior.
-
-2007-04-19 John Darrington <john@darrington.wattle.id.au>
-       
-        * command/no_case_size.sh command/sysfiles-old.sh:
-       Changed tests to reflect new behaviour (case changing) when
-       reading system files with no long name table.
-
-2007-04-15  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add recode.sh to tests.
-
-       * xforms/recode.sh: New test.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-           John McCabe-Dansted <gmatht@gmail.com>
-       
-       * npar-binomial.sh: Be less picky about whitespace in PSPP output.
-
-       * npar-chisquare.sh: Ditto.
-
-       * very-long-strings.sh: Ditto.
-
-2007-04-03  Ben Pfaff  <blp@gnu.org>
-
-       Apply patches #5828, #5837, #5841, #5843.
-
-       * automake.mk (tests_libpspp_bt_test_LDADD): Add range-map-test,
-       range-set-test, tower-test.
-
-       * libpspp/range-map-test.c: New test.
-
-       * libpspp/range-set-test.c: New test.
-
-       * libpspp/tower-test.c: New test.
-
-2007-03-31  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk (tests_libpspp_bt_test_LDADD): Add tests/libpspp/bt.
-
-       * libpspp/bt-test.c: New test.
-
-2007-03-25  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add tests/libpspp/sparse-array-test.
-
-       * libpspp/sparse-array-test.c: New test.
-
-2007-03-18  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Don't try to distribute tests that are compiled
-       from C source.  This fixes "make dist" when "make all" has not yet
-       been run.
-
-Mon Feb 12 06:29:30 2007  Ben Pfaff  <blp@gnu.org>
-
-       * libpspp/ll-test.c, libpspp/llx-test.c: Include <config.h>.
-
-Sat Feb  3 21:57:34 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add tests/command/vector.sh.
-
-       * command/vector.sh: New test.
-
-Wed Jan 24 21:13:53 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add tests/libpspp/abt-test.
-
-       * libpspp/abt-test.c: New test.
-
-       * libpspp/heap-test.c, libpspp/ll-test.c, libpspp/llx-test.c:
-       Style fixes.
-
-Wed Jan 10 06:50:01 2007  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add tests/libpspp/heap-test.
-
-       * libpspp/heap-test.c: New test.
-
-Wed Dec 13 21:00:46 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/rank.sh (activity): Use DELETE VAR (which is new)
-       instead of MODIFY VARS.
-
-Tue Dec 19 08:17:28 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/loop.sh: Test all the possible combinations of clauses.
-
-Sat Dec 16 14:00:48 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/rank.sh: Fix test to allow string grouping variables.
-       See bug #18533.
-
-Sat Dec 16 12:20:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/expressions.sh: Fix DATEDIFF function tests to
-       correspond with change to DATEDIFF.
-
-Wed Dec 13 19:34:29 2006  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/expressions.sh: Test DATEDIFF, DATESUM functions.
-
-Sun Dec 10 16:52:04 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new test.
-
-       * expressions/valuelabel.sh: New test, for VALUELABEL function.
-
-Thu Nov 30 22:46:17 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new test.
-
-       * bugs/compute-sum.sh: New test, for bug #17422.
-
-Thu Nov 30 22:01:57 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add new test.
-
-       * bugs/empty-do-repeat: New test, for bug #18407.
-
-Wed Nov 22 06:28:04 2006  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/signals.sh: Fix race condition.
-
-Sun Nov 19 09:23:34 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add the new tests listed below.
-
-       * formats/bcd-in.sh: New test.
-
-       * formats/bcd-in.expected.cmp.gz: New support file for
-       bcd-in.sh.
-
-       * formats/date-in.sh: New test.
-
-       * formats/ib-in.sh: New test.
-
-       * formats/ib-in.expected.cmp.gz: New test.
-
-       * formats/legacy-in.sh: New test.
-
-       * formats/legacy-in.expected.cmp.gz: New support file for
-       legacy-in.sh.
-
-       * formats/month-in.sh: New test.
-
-       * formats/num-in.sh: New test.
-
-       * formats/num-in.expected.gz: New support file for num-in.sh.
-
-       * formats/time-in.sh: New test.
-
-       * formats/wkday-in.sh: New test.
-
-       * commands/no_case_size.sh: Update output to conform with
-       update scientific notation code.
-
-       * formats/num-out.expected.cmp.gz: Ditto.
-
-Thu Nov  2 20:58:12 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/data-list.sh: Test newly implement SKIP keyword on DATA
-       LIST.
-
-Sat Nov  4 16:08:58 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add binhex-out.sh, date-out.sh, month-out.sh,
-       num-out.sh, time-out.sh, wkday-out.sh from formats directory.  Add
-       formats/inexactify as a program needed by tests.
-
-       * command/no_case_size.sh: Update output to conform with updated
-       formatted output code.
-
-       * expressions/expressions.sh: Ditto.
-
-       * formats/binhex-out.sh: New test.
-
-       * formats/date-out.sh: New test.
-
-       * formats/month-out.sh: New test.
-
-       * formats/num-out.sh: New test.
-
-       * formats/time-out.sh: New test.
-
-       * formats/wkday-out.sh: New test.
-
-Sun Oct 29 14:03:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * ll-test.c, llx-test.c: Reduce verbosity of output.
-
-Thu Oct 26 20:20:39 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add tests/formats/float-format.sh.
-
-       * formats/float-format.sh: New test.
-
-Sat Oct  7 11:06:59 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * command/rank.sh: New file 
-
-Sun Jul 16 21:08:51 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/print.sh: Update output to match PRINT revisions.
-
-Wed Jul 12 10:07:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Put ll-test, llx-test in check_PROGRAMS instead of
-       noinst_PROGRAMS.
-
-Wed Jul  5 22:15:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add expressions/randist/compare.pl to EXTRA_DIST.
-
-Tue Jul  4 09:59:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
-       ALL) and additional underlying system file issues.
-       
-       * automake.mk: Add keep-all.sh to TESTS.
-       
-       * bugs/keep-all.sh: New test.
-
-Mon Jul  3 21:09:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       Modify the random distributions test to verify to 2 more decimal
-       places of accuracy, but to allow +/- 1 units in the last (tested)
-       place.  This allows the test to pass on machines or with compilers
-       whose calculated values are off by epsilon from the expected
-       results.  Because of the way the test is constructed, this was
-       quite common and often caused gratuitous test failures.
-
-       This is patch #5215, tested by Jason Stover and John Darrington.
-        
-       * expressions/randist.sh: Use compare.pl to do comparisons.
-
-       * expressions/randist/compare.pl: New script to do comparisons.
-
-       * expressions/randist/randist.pl: Print output to 4 decimal
-       places, not just 2.  Also, print a brief explanatory header at the
-       top of each output file.
-
-       * expressions/randist/*.out: Replace with new expected output.
-
-Sat Jul  1 15:33:37 2006  Ben Pfaff  <blp@gnu.org>
-
-       * automake.mk: Add ll-test, llx-test to TESTS.
-       
-       * libpspp/ll-test.c: New file.
-
-       * libpspp/llx-test.c: New file.
-
-Sun May  7 18:15:52 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/do-repeat.sh: Only use "A TO B" for increasing runs of
-       integers, which is all we now support (for closer compatibility).
-
-Wed Apr 26 13:36:42 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/missing-values.sh: Update output to match behavior
-       changes.
-
-Mon Apr  3 12:32:36 2006  Ben Pfaff  <blp@gnu.org>
-
-       * Updated tests to match changes in output formatting.
-
-2006-03-23  Jason Stover  <jhs@math.gcsu.edu>
-
-       * command/regression.sh: New test.
-
-Sat Mar 11 14:16:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
-
-       * Updated the tests to use the new location of the pspp binary.
-       * Made all the tests work as stand-alone scripts.
-
-Sun Feb 12 19:07:24 2006  Ben Pfaff  <blp@gnu.org>
-
-       * command/do-repeat.sh: New test.
-
-       * bugs/terminate.sh: Removed (no longer applicable).
-
-Fri Nov  4 19:30:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/recode-bug.sh: Improve failure reports.
-
-Wed Nov  2 21:54:11 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/loop.sh: Update expected error messages.
-
-Sun Aug 21 00:20:02 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/import-export.sh: Simplify.
-
-       * command/sysfiles-old.sh: Use version 2, not 3x.
-
-Sat Aug  6 17:32:39 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/missing-values.sh: New test.
-
-       * Makefile.am: Add new test.
-
-Mon Aug  1 21:51:46 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/big-input-2.sh: Don't use 1...100000 (etc.) with Perl
-       because that may allocate a large amount of memory.
-
-Mon Aug  1 21:48:54 2005  Ben Pfaff  <blp@gnu.org>
-
-       * xforms/expression.sh: Break this monolithic test up into 36
-       subtests to give a better idea of what's failing in some cases.
-
-Sat Jul 30 21:54:23 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/sys-info.sh: Removed.  (This was not actually in TESTS
-       in Makefile.am, so it was never called.  command/sysfile-info.sh
-       does what it was trying to do, but better.)
-       
-Sat Jul 30 21:50:33 2005  Ben Pfaff  <blp@gnu.org>
-
-       Fixes for Solaris.
-
-       * Most tests: Add `cd /' before `rm -rf $TEMPDIR' because some
-       OSes do not allow the current working directory to be removed.
-
-       * bugs/big-input-2.sh: Use perl instead of a shell loop, because
-       the shell loop was very slow on Solaris.
-
-       * command/sort.sh: Use `printf' instead of `echo -n' for
-       portability. 
-       
-Sat Jul 30 21:48:37 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add coverage.sh, temp_template to EXTRA_DIST.
-
-Sun Jul 24 20:35:04 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/sysfile-info.sh: Add "-b -B -w" to diff command line.
-       Fixes apparent failure under Cygwin.  Thanks to John Darrington
-       <john@cellform.com.au> for reporting this problem.
-
-Mon Jul  4 18:02:44 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/sysfile-info.sh: Don't verify endianness.  Fixes bug
-       reported by "Marshall DeBerry" <mdb@radix.net>.
-
-Mon Jun  6 22:40:10 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/print.sh: Get rid of RBHEX output.  It wasn't worth
-       much.  Fixes bug 12312.
-
-Tue May 10 19:59:10 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/agg-crash-2.sh: Fix output given bug 13054.
-
-Wed May  4 23:50:02 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/match-files-scratch.sh: New test for bug 12948.
-
-       * Makefile.am: (TESTS) Add bugs/match-files-scratch.sh.
-
-Sun May  1 23:18:37 2005  Ben Pfaff  <blp@gnu.org>
-
-       Most tests: changed capitalization of variable names in
-       definitions or in output, because now we preserve it.
-
-Mon Apr 25 23:30:17 2005  Ben Pfaff  <blp@gnu.org>
-
-       * commands/match-files.sh: New test.
-
-       * Makefile.am: (TESTS) Add commands/match-files.sh.
-
-Sun Apr 17 16:38:00 2005  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.stat, data-fmts.stat, do-if.stat, do-repeat.stat,
-       gengarbage.c, inpt-pgm.stat, mdfy-vars.stat, means.stat,
-       mtch-file.stat, pcs-if.stat, recode.stat, repeating.stat,
-       reread.data, reread.stat, sys-info.stat, t-test.stat,
-       temporary.stat, time-date.stat, vector.stat: Removed because they
-       were unused.
-
-       * Makefile.am: Removed sort.data references.  Fixed up
-       DISTCLEANFILES.
-
-Sun Mar 20 14:16:31 2005  Ben Pfaff  <blp@gnu.org>
-
-       * command/aggregate.sh: Rewrite.
-
-Mon Mar 14 21:58:23 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS_ENVIRONMENT) Add PERL to the test
-       environment.
-
-       * commands/sort.sh: Rewrite to test more thoroughly and to verify
-       that the sort is stable.
-       
-Sat Mar 12 23:30:37 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/agg-crash-2.sh, bugs/big-input-2.sh, command/aggregate.sh:
-       Fix AGGREGATE command syntax.
-
-Sat Mar 12 13:16:34 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/temp-freq.sh: Add another test.
-
-Fri Mar 11 10:40:41 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/expressions.sh: Add another test.
-
-Sun Mar  6 19:30:14 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/vectors.sh: New test.
-
-       * Makefile.am: Add expressions/vectors.sh.
-
-Sun Mar  6 17:56:27 2005  Ben Pfaff  <blp@gnu.org>
-
-       * expressions/expressions.sh: Add tests for generic optimizations.
-
-Sun Mar  6 11:03:58 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Add expressions/variables.sh.  Remove expr.stat.
-
-       * expr.stat: Removed.
-
-'Mon Feb 28 23:31:16 2005  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Removed xforms/expressions.sh.  Added
-       expressions/expressions.sh, expressions/epoch.sh,
-       expressions/randist.sh.
-
-       * command/print.sh: Update error messages.
-
-Sun Feb 13 16:15:09 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/agg-crash-2.sh: Add new test for Bug #11955.
-
-Fri Feb 11 23:27:08 2005  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/crosstabs-crash.sh: Add new test for Bug #11916.
-
-Tue Jan 18 19:25:24 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * Canonicalised (some of) the tests' temp file names to make it
-       easier to recognise valgrind ouput.
-
-Sun Jan  9 16:39:08 WST 2005 John Darrington <john@darrington.wattle.id.au>
-
-       * bugs/big-input-2.sh Made the test a bit faster
-
-John Darrington <john@darrington.wattle.id.au>
-
-       * command/examine.sh Added
-       
-Mon Nov 15 23:52:55 2004  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/random.sh: Update expected random values to reflect the GSL
-       random number generator.
-
-Sat Nov  6 14:49:27 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * command/oneway-with-splits.sh  Added.
-
-Sun Oct 31 16:08:47 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * bugs/recode-copy-bug.sh bugs/computebug.sh  Fixed problem which 
-       caused make distcheck to not know where some critical files were.
-
-Mon May 31 21:49:19 2004  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/t-test-with-temp.sh: Use $SUPERVISOR.
-
-       * bugs/t-test-1-indep-val.sh: Ditto.
-
-       * bugs/t-test-1-sample-missing-anal.sh: Ditto.
-       
-       * bugs/t-test-1-sample-missing-list.sh: Ditto.
-
-       * bugs/t-test-1s.sh: Ditto.
-
-       * bugs/t-test-groups.sh: Ditto.
-
-       * bugs/t-test-indep-missing-anal.sh: Ditto.
-
-       * bugs/t-test-indep-missing-list.sh: Ditto.
-
-       * bugs/t-test-paired-missing-anal.sh: Ditto.
-
-       * bugs/t-test-paired-missing-list.sh: Ditto.
-
-       * bugs/t-test-pairs.sh: Ditto.
-
-Sun May 30 19:18:26 2004  Ben Pfaff  <blp@gnu.org>
-
-       * command/tabs.sh: Default tab width is now 4.
-
-       * command/data-list.sh: New test.
-
-       * Makefile.am: (TESTS) Add command/data-list.sh.
-
-Sun Apr 11 14:21:16 2004  Ben Pfaff  <blp@gnu.org>
-
-       * stats/moments.sh: Now that our one-pass moments algorithm is
-       better we don't have to omit any of the test cases for it.
-
-Fri Apr  9 20:03:33 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS) Add stats/descript-mean-bug.sh.
-
-       * stats/descript-mean-bug.sh: Add test for a bug where
-       DESCRIPTIVES asking only for the mean assert-failed.
-
-Sat Apr  3 11:42:31 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS) Add bugs/comment-at-eof.sh.  Alphabetize
-       test order.
-       
-       * bugs/comment-at-eof.sh: Add test for a bug where a comment at
-       end of file caused an infinite loop.
-
-Sat Mar 27 11:29:06 WST 2004 John Darrington <john@darrington.wattle.id.au>
-
-       * bugs/get.sh Added regression test for a bug in loading a dictionary
-       with the GET command.
-
-Tue Mar 30 22:10:08 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS) Add bugs/multipass.sh.
-
-Mon Mar 29 15:25:09 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS) Add xforms/casefile.sh,
-       stats/descript-basic.sh, stats/descript-missing.sh,
-       stats/moments.sh.  Remove command/descriptives.sh.
-
-       * command/descriptives.sh: Removed.
-
-       * command/weight.sh: Fix output (statistic values were wrong!).
-
-       * stats/descript-basic.sh: New test.
-       
-       * stats/descript-missing.sh: New test.
-       
-       * stats/moments.sh: New test.
-
-       * xforms/casefile.sh: New test.
-
-       * xforms/expressions.sh: Cleans up after itself now.
-
-Fri Mar 26 00:55:48 2004  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (TESTS) Add xforms/expressions.sh, remove
-       command/compute.sh.
-
-       * command/beg-data.sh: Remove REMARK usage.
-
-       * command/bignum.sh: Ditto.
-
-       * command/list.sh: Ditto.
-
-       * command/print.sh: Ditto.
-
-Sat Mar 20 18:11:15 2004  Ben Pfaff  <blp@gnu.org>
-
-       * command/list.sh: Update output.
-
-       * command/print.sh: Ditto.
-
-       * command/weight.sh: Ditto.
-
-Sun Mar 14 23:04:14 2004  Ben Pfaff  <blp@gnu.org>
-
-       * command/sort.sh: Use numeric, not string, data to avoid spurious
-       valgrind complaints.
-
-Wed Mar 10 21:22:03 2004  Ben Pfaff  <blp@gnu.org>
-
-       * bugs/temporary.sh: Test that basic use of TEMPORARY works.
-
-Mon Feb 16 21:36:57 2004  Ben Pfaff  <blp@gnu.org>
-
-       * */*.sh: Prepend $SUPERVISOR to invocations of pspp so that we
-       can run valgrind or gdb easily with `make check'
-
-Sat Dec 13 00:08:23 2003  Ben Pfaff  <blp@gnu.org>
-
-       * syntax: Run a diff when there's no expected output, too.
-
-Fri Jan  7 20:30:23 2000  Ben Pfaff  <blp@gnu.org>
-
-       * data-fmts.stat: Add more date tests.
-
-       * do-repeat.stat: SET ECHO ON.
-
-       * syntax: Replace test -L with test -h.
-
-Tue Jan  5 14:21:52 1999  Ben Pfaff  <blp@gnu.org>
-
-       * data-list.stat, data-list.data: Adjust so that it can tell if
-       DATA LIST FREE properly parses and pads string values.
-
-       * list.stat: Remove anachronistic `SET EMULATION PC'.
-
-       * Rebuilt benchmark.
-
-Tue Jan  5 14:12:58 1999  Ben Pfaff  <blp@gnu.org>
-
-       * syntax: Replaced `test' calls with `['.  This may or may not fix
-       the problems some people have reported.
-
-Sun Aug  9 11:15:38 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Update for renamed files.
-
-       * autorecode.stat: Renamed autorecod.stat.
-
-       * begin-data.stat: Renamed beg-data.stat.
-
-       * data-formats.stat: Renamed data-fmts.stat.
-
-       * expression.stat: Renamed expr.stat.
-
-       * file-label.stat: Renamed file-lab.stat.
-
-       * input-program.stat: Renamed inpt-pgm.stat.
-
-       * modify-vars.stat: Renamed mdfy-vars.stat.
-
-       * match-files.stat: Renamed mtch-file.stat.
-
-       * process-if.stat: Renamed pcs-if.stat.
-
-       * split-file.stat: Renamed splt-file.stat.
-
-       * sysfile-info.stat: Renamed sys-info.stat.
-
-       * expect/: Refreshed.
-
-Sat Aug  8 00:27:07 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add `syntax'.
-       (dist-hook) New target.
-
-Wed Aug  5 00:04:16 1998  Ben Pfaff  <blp@gnu.org>
-
-       * TEST-RESULTS: Removed.
-
-       * show-check-msg: Removed.
-
-       * expect/: New.
-
-       * syntax: New.  Thanks to James R. Van Zandt <jrv@vanzandt.mv.com>
-       for this implementation of automatic testing.
-
-       * Makefile: (TESTS) Set to the syntax script.
-       (bench) New target.
-       (EXTRA_DIST) Remove TEST-RESULTS.  Add `syntax'.
-
-Sun Jul  5 14:16:18 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add flip.stat.
-
-Sun Jul  5 00:50:41 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.stat: Change to test /MISSING=REPORT.
-
-Tue Jun  2 23:42:23 1998  Ben Pfaff  <blp@gnu.org>
-
-       * flip.stat: New file.
-       
-       * weighting.stat: Update.
-
-Mon May 25 12:45:46 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add crosstabs.stat, match-files.stat.
-
-       * crosstabs.stat: Turn off cells=all.
-
-Tue May 12 16:22:06 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.stat: Minor changes.
-
-Thu May  7 23:16:03 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.stat: Replace with a test that is hopefully better.
-
-Tue Apr 14 01:00:46 1998  Ben Pfaff  <blp@gnu.org>
-
-       * crosstabs.stat: New.
-
-Mon Mar  9 15:40:25 1998  Ben Pfaff  <blp@gnu.org>
-
-       * match-files.stat: More thorough.
-
-Mon Mar  9 01:14:14 1998  Ben Pfaff  <blp@gnu.org>
-
-       * match-files.stat: More thorough.
-
-1998-03-05  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Use ./gengarbage instead of gengarbage.
-
-1998-02-23  Ben Pfaff  <blp@gnu.org>
-
-       * Many tests: Remove final finish command.
-
-1998-02-16  Ben Pfaff  <blp@gnu.org>
-
-       * (DISTCLEANFILES) Clean *.save, pspp.*, foo*
-
-       * file-label.stat, sysfile-info.stat: Replace .sav with .save.
-
-       * match-files.stat: New file.
-       
-Fri Feb 13 15:58:11 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add TEST-RESULTS.
-
-Tue Jan 13 01:11:36 1998  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.stat: Some more testing.
-
-Sat Jan 10 23:57:14 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (DISTCLEANFILES) Add aggregate.save.
-
-       * aggregate.stat: Slightly more thorough.
-
-Sat Jan 10 02:17:00 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add means.stat, t-test.stat.
-       
-       * means.stat: New file.
-
-Thu Jan  8 22:38:59 1998  Ben Pfaff  <blp@gnu.org>
-
-       * Many tests: Removed extra newlines from REMARKs.
-
-Mon Jan  5 11:18:44 1998  Ben Pfaff  <blp@gnu.org>
-
-       * sysfile-info.stat: Test most of the DISPLAY commands.  Update
-       title.
-
-       * vector.stat: Display vectors.
-
-Sun Jan  4 18:31:36 1998  Ben Pfaff  <blp@gnu.org>
-
-       * All tests: Added title.
-
-       * begin-data.stat: Updated REMARK format.
-
-       * descript.stat: Comment fix.
-
-Sun Dec 21 16:57:31 1997  Ben Pfaff  <blp@gnu.org>
-
-       * TEST-RESULTS: New file.
-
-Fri Dec  5 22:02:20 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (DISTCLEANFILES) Add fiasco.html.
-
-Tue Dec  2 14:55:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * t-test.stat: New file.
-
-Fri Nov 14 00:17:25 1997  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.stat: Changed.      
-
-Tue Oct 28 16:26:25 1997  Ben Pfaff  <blp@gnu.org>
-
-       * aggregate.stat: New file.
-
-       * Makefile.am: (EXTRA_DIST) Add aggregate.stat.
-
-Sun Oct  5 16:02:02 1997  Ben Pfaff  <blp@gnu.org>
-
-       * fall92.stat, fall92.data: Removed (unknown copyright).
-
-       * gengarbage.c: Define EXIT_SUCCESS if not defined by headers.
-       From Alexandre Oliva <oliva@dcc.unicamp.br>.
-
-Sat Oct  4 16:35:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * repeating.stat: New file.
-
-       * Makefile.am: (EXTRA_DIST) Add repeating.stat.
-
-Thu Sep 18 21:40:50 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add lag.stat.
-
-Mon Aug 18 18:31:42 1997  Ben Pfaff  <blp@gnu.org>
-
-       * do-repeat.stat: Even more useful.
-
-       * lag.stat: New file.
-
-Sun Aug 17 22:47:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * do-repeat.stat: Made actually useful, not stupid.
-
-Sun Aug  3 11:46:00 1997  Ben Pfaff  <blp@gnu.org>
-
-       * In several files, replace usage of deprecated term `script' by
-       `syntax file'.
-
-Thu Jul 17 02:12:17 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Add tabs.stat.
-
-       * file-label.stat: Improved.
-
-       * sysfile-info.stat: Tests DISPLAY DICTIONARY now as well.
-
-Fri Jul 11 14:13:49 1997  Ben Pfaff  <blp@gnu.org>
-
-       * gengarbage.c: Reformat.  #include's <time.h>.  Uses ANSI C
-       rand() in place of random().  Calls the randomizer srand().
-
-Thu Jul 10 22:16:34 1997  Ben Pfaff  <blp@gnu.org>
-
-       * tabs.stat: New file.
-
-Wed Jun 25 22:54:40 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: (EXTRA_DIST) Removed bug.stat, file-type.stat.
-
-Sun Jun  8 01:24:55 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Added fiasco.ps, fiasco.list, foo, foo.sav, msgs to
-       DISTCLEANFILES.
-
-       * input-program.stat: Made some variables scratch.
-
-Fri Jun  6 22:53:03 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Many files: Comment fixes, removed `set output raw.' commands.
-
-       * Other miscellaneous changes.
-
-Tue Jun  3 23:44:46 1997  Ben Pfaff  <blp@gnu.org>
-
-       * list.stat: Re-enabled some of it.
-
-Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
-
-       * sysfile-info.stat: A little more generalized now.
-
-Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
-
-       * Makefile.am: Maintainer-clean Makefile.in.
-       
-Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
-
-       * gengarbage.pl: Removed.
-       
-Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
-
-       * descript.stat: Syntax fixes.
-
-       * process-if.stat: New test for PROCESS IF.
-
-Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.stat, modify-vars.stat: More thorough.
-
-       * data-formats.stat, file-label.stat: New tests.
-       
-Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
-
-       * bug.stat: Comment fix.
-
-Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
-
-       * filter.stat: New file; tests FILTER behavior.
-
-Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
-
-       * gengarbage.pl: New perl program equivalent to gengarbage.c.
-
-Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
-
-       * gengarbage.c: Changed.
-
-       * sort.stat: Changed.
-
-Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
-
-       * sort.stat: New file.
-
-Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
-
-       * autorecode.stat: New file.
-
-       * fall92.stat: Mods for practicality.
-
-       * test.bat, testall.bat: Removed.
-       
-Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
-
-       * list.stat, weighting.stat: Changed SET COMPATIBILITY subcommand
-       to SET EMULATION in anticipation of change.
-
-Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
-
-       * recode.stat: Removed comment about bug, since I fixed that.
-
-Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
-
-       * print.stat: Slightly more thorough.
-
-Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
-
-       * time-date.stat: Slightly more thorough.
-
-Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
-
-       * time-date.stat: New file.
-
-Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
-
-       * list.data: More data.
-
-       * list.stat: Handles all that extra data.
-
-       * weighting.stat: Doesn't try to list $WEIGHT because PC+ isn't
-       quite supported yet.
-
-Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
-
-       * weighting.stat: Tests for proper ligatures.  Won't work until
-       encodings are correct, of course...
-
-----------------------------------------------------------------------
-Local Variables:
-mode: change-log
-version-control: never
-End:
diff --git a/tests/OChangeLog b/tests/OChangeLog
new file mode 100644 (file)
index 0000000..4742a1c
--- /dev/null
@@ -0,0 +1,1242 @@
+2008-06-21  Jason Stover  <jhs@math.gcsu.edu>
+
+       * regression.sh, regression-qr.sh: Fixed column showing
+       standardized coefficients.
+
+2008-05-16  John Darrington <john@darrington.wattle.id.au>
+
+       * compression.sh print-crash.sh print-strings.sh very-long-strings.sh :
+       Removed export VAR=VAL syntax.
+
+       * automake.mk:  Added test to check for non-portable shell syntax
+
+2008-04-14  Jason Stover  <jhs@math.gcsu.edu>
+
+       * automake.mk: New test for regression with QR decomposition.
+
+       * command/regression-qr.sh: New test for regression with QR decomposition.
+
+2008-03-16  Ben Pfaff  <blp@gnu.org>
+
+       Bug #22037.
+
+       * automake.mk: Add new test.
+
+       * bugs/crosstabs-crash2.sh: New test.
+
+2008-03-16  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6452.  Reviewed by John Darrington.
+
+       * automake.mk: Add new test.
+
+       * command/variable-display.sh: New test.
+
+2008-03-04  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6441.  Reviewed by John Darrington.
+
+       * automake.mk: Add new test.
+
+       * formats/format-guesser.sh: New test.
+
+2008-02-10  Ben Pfaff  <blp@gnu.org>
+
+       * command/get-data-txt-examples.sh: Update to match changes to
+       documentation (which were in turn updated to show how the escaped
+       quote feature works).
+
+2008-02-02  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add target for dissect-sysfile.
+
+       * dissect-sysfile.c: New program.
+
+2008-02-01  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new test.
+
+       * libpspp/str-test.c: New test.
+
+       * command/get-dat-gnm.sh: Update variable names to match new
+       naming scheme.
+
+2007-12-04  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new tests.
+
+       * command/get-data-txt.sh: New test.
+
+       * command/get-data-txt-examples.sh: New test.
+
+       * command/get-data-txt-importcases.sh: New test.
+
+2007-11-25  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/compression.sh: Don't fail on big-endian system.  Partial
+       fix for bug #21590.
+
+       * bugs/sysfile-info.sh: Disregard "Integer Format" and "Real
+       Format" lines in SYSFILE INFO output, to permit big-endian systems
+       to pass also.  Partial fix for bug #21590.
+
+2007-11-15  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add definition of CHARSETALIASDIR to
+       TESTS_ENVIRONMENT, to allow locale_charset to find charset.alias
+       before running "make install".
+
+2007-11-10  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/compression.sh: Pass -b option to diff to avoid spurious
+       failure on od.
+
+2007-11-08  Ben Pfaff  <blp@gnu.org>
+
+       Patch #6256: add support for binary, 360 file formats.  Reviewed
+       by John Darrington.
+
+       * automake.mk: Add new file.
+
+       * formats/360.sh: New test.
+
+2007-11-07  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/overwrite-input-file.sh: Don't use non-portable "diff -B".
+
+       * bugs/overwrite-special-file.sh: Ditto.
+
+       Reported by Jason Stover.
+
+2007-11-03  Ben Pfaff  <blp@gnu.org>
+
+       Allow output files to overwrite input files (bug #21280).
+
+       * automake.mk: Add new file.
+
+       * bugs/overwrite-input-file.sh: Rewrite to make sure that we can
+       overwrite input files safely.
+
+       * bugs/overwrite-special-file.sh: New test.
+
+       * command/erase.sh: Fix "activity" message.
+
+2007-11-03  John Darrington <john@darrington.wattle.id.au>
+
+       * Book1.gnm.unzipped command/get-data-gnm.sh: New test and data
+       for reading gnumeric files.
+
+2007-10-08  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21280.  Thanks to John Darrington for review.
+
+       * automake.mk: Add new file.
+
+       * bugs/overwrite-input-file.sh: New test.
+
+2007-09-23  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21111.  Reviewed by John Darrington.
+       
+       * command/input-program.sh: New test.
+
+       * command/do-if.sh: New tests.
+
+2007-09-22  Ben Pfaff  <blp@gnu.org>
+
+       Bug #21128.  Reviewed by John Darrington.
+
+       * output/paper-size.sh: New test.
+
+2007-09-21  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/unwritable-dir.sh: New test for bug #21117.
+
+2007-09-19  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/input-crash.sh: Add regression test for bug #21108.
+
+2007-09-04  Ben Pfaff  <blp@gnu.org>
+
+       Update scripts that invoke Perl to invoke it as simply "perl" if
+       not run from the PSPP Makefiles.  Patch #6169.  Thanks to John
+       Darrington for suggestion and review.
+       * bugs/big-input-2.sh: Make $PERL default to perl.
+       * command/sort.sh: Ditto.
+       * formats/bcd-in.sh: Ditto.
+       * formats/date-in.sh: Ditto.
+       * formats/ib-in.sh: Ditto.
+       * formats/legacy-in.sh: Ditto.
+       * formats/num-in.sh: Ditto.
+       * formats/num-out.sh: Ditto.
+       * formats/time-in.sh: Ditto.
+
+2007-08-26  Ben Pfaff  <blp@gnu.org>
+
+       * Updated most invocations of PSPP in the tests to use
+          --testing-mode and to avoid specifying an output format with -o
+         (because --testing-mode implies -o raw-ascii).
+
+2007-08-26  Ben Pfaff  <blp@gnu.org>
+
+       * command/aggregate.sh: Update output to include error messages,
+       which are now sent to output files also.
+
+       * command/ranks.h: Ditto.
+
+2007-08-12  Ben Pfaff  <blp@gnu.org>
+
+       * command/no_case_size.sh: Update to match update DISPLAY and
+       SYSFILE INFO command output.
+
+       * command/rank.sh: Ditto.
+
+       * command/sysfile-info.sh: Ditto.
+
+       * command/very-long-strings.sh: Ditto.
+
+2007-08-09  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #18982.  Thanks to John Darrington for investigation,
+       review, and verification of fix.
+       
+       * formats/date-in.sh: Use a portable pseudo-random number
+       generator.
+       
+       * formats/time-in.sh: Ditto.
+
+       * formats/num-in.sh: Ditto.
+
+2007-08-03  Ben Pfaff  <blp@gnu.org>
+
+       * command/rank.sh: Test RANK with noncontiguous groups of SPLIT
+       FILE variables and how they should behave differently from
+       noncontiguous groups of BY variables.  Regression test for bug
+       #17239.
+
+2007-08-01  Ben Pfaff  <blp@gnu.org>
+
+       * command/weight.sh: Update to match new output format for median
+       under FREQUENCIES.
+       
+       * stats/percentiles-compatible.sh: Ditto.
+
+       * stats/percentiles-enhanced.sh: Ditto.
+
+2007-07-28 John Darrington <john@darrington.wattle.id.au>
+
+       * command/t-test-1-indep-val.sh: Changed the order of groups in the 
+       summary box to match new behaviour. (Fixes bug #19604).
+
+2007-07-25  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #17100.
+       * command/data-list.sh: Add tests for multi-record DATA LIST with
+       and without empty trailing record.
+
+2007-07-24  Ben Pfaff  <blp@gnu.org>
+
+       * command/flip.sh: Add tests to avoid regression on bugs #20493,
+       #20494.
+
+2007-07-22  Ben Pfaff  <blp@gnu.org>
+
+       * command/very-long-strings.sh: Test both compressed and
+       uncompressed system files with very long strings.
+
+2007-07-17  Ben Pfaff  <blp@gnu.org>
+
+       Patch #19335.  Reviewed by John Darrington.
+
+       * expressions/randist/compare.pl: Use strict and all warnings.
+
+       * expressions/randist/randist.pl: Ditto.
+
+       * formats/num-out-cmp.pl: Ditto.
+
+       * formats/num-out-compare.pl: Ditto.
+
+       * formats/num-out-decmp.pl: Ditto.
+
+       * formats/num-out.pl: Ditto.
+
+2007-07-17  Ben Pfaff  <blp@gnu.org>
+
+       * formats/float-format.h: Drop the tests that depend on parsing
+       "-0" from a syntax file.  Also make float-format.sh error messages
+       easier to read, by changing the sed command so that error line
+       numbers are easier to match to the test input.
+       Reviewed by John Darrington as patch #6091.
+
+2007-07-11  Ben Pfaff  <blp@gnu.org>
+
+       * xforms/expressions.sh: Remove unused file.  Fixes bug
+       #18140.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * commands/match-files.sh: Test the new support for FIRST and LAST
+         subcommands.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Remove test.
+
+       * xforms/casefile.sh: Removed test.
+
+2007-06-06  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new test.
+
+       * command/datasheet.sh: New test.
+
+2007-06-03  Ben Pfaff  <blp@gnu.org>
+
+       * libpspp/tower-test.c: Also test tower_last, tower_prev functions.
+
+       * libpspp/range-set-test.c: Also test the range_set_clone function.
+
+2007-05-06  Ben Pfaff  <blp@gnu.org>
+
+       Abstract the documents within a dictionary a little better.
+       Thanks to John Darrington for suggestion, initial version, and
+       review.  Patch #5917.
+
+       * command/file-label.sh: Update to match new DOCUMENT behavior.
+
+2007-04-19 John Darrington <john@darrington.wattle.id.au>
+       
+        * command/no_case_size.sh command/sysfiles-old.sh:
+       Changed tests to reflect new behaviour (case changing) when
+       reading system files with no long name table.
+
+2007-04-15  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add recode.sh to tests.
+
+       * xforms/recode.sh: New test.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+           John McCabe-Dansted <gmatht@gmail.com>
+       
+       * npar-binomial.sh: Be less picky about whitespace in PSPP output.
+
+       * npar-chisquare.sh: Ditto.
+
+       * very-long-strings.sh: Ditto.
+
+2007-04-03  Ben Pfaff  <blp@gnu.org>
+
+       Apply patches #5828, #5837, #5841, #5843.
+
+       * automake.mk (tests_libpspp_bt_test_LDADD): Add range-map-test,
+       range-set-test, tower-test.
+
+       * libpspp/range-map-test.c: New test.
+
+       * libpspp/range-set-test.c: New test.
+
+       * libpspp/tower-test.c: New test.
+
+2007-03-31  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk (tests_libpspp_bt_test_LDADD): Add tests/libpspp/bt.
+
+       * libpspp/bt-test.c: New test.
+
+2007-03-25  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add tests/libpspp/sparse-array-test.
+
+       * libpspp/sparse-array-test.c: New test.
+
+2007-03-18  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Don't try to distribute tests that are compiled
+       from C source.  This fixes "make dist" when "make all" has not yet
+       been run.
+
+Mon Feb 12 06:29:30 2007  Ben Pfaff  <blp@gnu.org>
+
+       * libpspp/ll-test.c, libpspp/llx-test.c: Include <config.h>.
+
+Sat Feb  3 21:57:34 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add tests/command/vector.sh.
+
+       * command/vector.sh: New test.
+
+Wed Jan 24 21:13:53 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add tests/libpspp/abt-test.
+
+       * libpspp/abt-test.c: New test.
+
+       * libpspp/heap-test.c, libpspp/ll-test.c, libpspp/llx-test.c:
+       Style fixes.
+
+Wed Jan 10 06:50:01 2007  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add tests/libpspp/heap-test.
+
+       * libpspp/heap-test.c: New test.
+
+Wed Dec 13 21:00:46 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/rank.sh (activity): Use DELETE VAR (which is new)
+       instead of MODIFY VARS.
+
+Tue Dec 19 08:17:28 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/loop.sh: Test all the possible combinations of clauses.
+
+Sat Dec 16 14:00:48 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/rank.sh: Fix test to allow string grouping variables.
+       See bug #18533.
+
+Sat Dec 16 12:20:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/expressions.sh: Fix DATEDIFF function tests to
+       correspond with change to DATEDIFF.
+
+Wed Dec 13 19:34:29 2006  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/expressions.sh: Test DATEDIFF, DATESUM functions.
+
+Sun Dec 10 16:52:04 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new test.
+
+       * expressions/valuelabel.sh: New test, for VALUELABEL function.
+
+Thu Nov 30 22:46:17 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new test.
+
+       * bugs/compute-sum.sh: New test, for bug #17422.
+
+Thu Nov 30 22:01:57 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add new test.
+
+       * bugs/empty-do-repeat: New test, for bug #18407.
+
+Wed Nov 22 06:28:04 2006  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/signals.sh: Fix race condition.
+
+Sun Nov 19 09:23:34 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add the new tests listed below.
+
+       * formats/bcd-in.sh: New test.
+
+       * formats/bcd-in.expected.cmp.gz: New support file for
+       bcd-in.sh.
+
+       * formats/date-in.sh: New test.
+
+       * formats/ib-in.sh: New test.
+
+       * formats/ib-in.expected.cmp.gz: New test.
+
+       * formats/legacy-in.sh: New test.
+
+       * formats/legacy-in.expected.cmp.gz: New support file for
+       legacy-in.sh.
+
+       * formats/month-in.sh: New test.
+
+       * formats/num-in.sh: New test.
+
+       * formats/num-in.expected.gz: New support file for num-in.sh.
+
+       * formats/time-in.sh: New test.
+
+       * formats/wkday-in.sh: New test.
+
+       * commands/no_case_size.sh: Update output to conform with
+       update scientific notation code.
+
+       * formats/num-out.expected.cmp.gz: Ditto.
+
+Thu Nov  2 20:58:12 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/data-list.sh: Test newly implement SKIP keyword on DATA
+       LIST.
+
+Sat Nov  4 16:08:58 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add binhex-out.sh, date-out.sh, month-out.sh,
+       num-out.sh, time-out.sh, wkday-out.sh from formats directory.  Add
+       formats/inexactify as a program needed by tests.
+
+       * command/no_case_size.sh: Update output to conform with updated
+       formatted output code.
+
+       * expressions/expressions.sh: Ditto.
+
+       * formats/binhex-out.sh: New test.
+
+       * formats/date-out.sh: New test.
+
+       * formats/month-out.sh: New test.
+
+       * formats/num-out.sh: New test.
+
+       * formats/time-out.sh: New test.
+
+       * formats/wkday-out.sh: New test.
+
+Sun Oct 29 14:03:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * ll-test.c, llx-test.c: Reduce verbosity of output.
+
+Thu Oct 26 20:20:39 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add tests/formats/float-format.sh.
+
+       * formats/float-format.sh: New test.
+
+Sat Oct  7 11:06:59 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * command/rank.sh: New file 
+
+Sun Jul 16 21:08:51 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/print.sh: Update output to match PRINT revisions.
+
+Wed Jul 12 10:07:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Put ll-test, llx-test in check_PROGRAMS instead of
+       noinst_PROGRAMS.
+
+Wed Jul  5 22:15:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add expressions/randist/compare.pl to EXTRA_DIST.
+
+Tue Jul  4 09:59:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Fix bug #15766 (/KEEP subcommand on SAVE doesn't fully support
+       ALL) and additional underlying system file issues.
+       
+       * automake.mk: Add keep-all.sh to TESTS.
+       
+       * bugs/keep-all.sh: New test.
+
+Mon Jul  3 21:09:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       Modify the random distributions test to verify to 2 more decimal
+       places of accuracy, but to allow +/- 1 units in the last (tested)
+       place.  This allows the test to pass on machines or with compilers
+       whose calculated values are off by epsilon from the expected
+       results.  Because of the way the test is constructed, this was
+       quite common and often caused gratuitous test failures.
+
+       This is patch #5215, tested by Jason Stover and John Darrington.
+        
+       * expressions/randist.sh: Use compare.pl to do comparisons.
+
+       * expressions/randist/compare.pl: New script to do comparisons.
+
+       * expressions/randist/randist.pl: Print output to 4 decimal
+       places, not just 2.  Also, print a brief explanatory header at the
+       top of each output file.
+
+       * expressions/randist/*.out: Replace with new expected output.
+
+Sat Jul  1 15:33:37 2006  Ben Pfaff  <blp@gnu.org>
+
+       * automake.mk: Add ll-test, llx-test to TESTS.
+       
+       * libpspp/ll-test.c: New file.
+
+       * libpspp/llx-test.c: New file.
+
+Sun May  7 18:15:52 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/do-repeat.sh: Only use "A TO B" for increasing runs of
+       integers, which is all we now support (for closer compatibility).
+
+Wed Apr 26 13:36:42 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/missing-values.sh: Update output to match behavior
+       changes.
+
+Mon Apr  3 12:32:36 2006  Ben Pfaff  <blp@gnu.org>
+
+       * Updated tests to match changes in output formatting.
+
+2006-03-23  Jason Stover  <jhs@math.gcsu.edu>
+
+       * command/regression.sh: New test.
+
+Sat Mar 11 14:16:01 WST 2006 John Darrington <john@darrington.wattle.id.au>
+
+       * Updated the tests to use the new location of the pspp binary.
+       * Made all the tests work as stand-alone scripts.
+
+Sun Feb 12 19:07:24 2006  Ben Pfaff  <blp@gnu.org>
+
+       * command/do-repeat.sh: New test.
+
+       * bugs/terminate.sh: Removed (no longer applicable).
+
+Fri Nov  4 19:30:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/recode-bug.sh: Improve failure reports.
+
+Wed Nov  2 21:54:11 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/loop.sh: Update expected error messages.
+
+Sun Aug 21 00:20:02 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/import-export.sh: Simplify.
+
+       * command/sysfiles-old.sh: Use version 2, not 3x.
+
+Sat Aug  6 17:32:39 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/missing-values.sh: New test.
+
+       * Makefile.am: Add new test.
+
+Mon Aug  1 21:51:46 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/big-input-2.sh: Don't use 1...100000 (etc.) with Perl
+       because that may allocate a large amount of memory.
+
+Mon Aug  1 21:48:54 2005  Ben Pfaff  <blp@gnu.org>
+
+       * xforms/expression.sh: Break this monolithic test up into 36
+       subtests to give a better idea of what's failing in some cases.
+
+Sat Jul 30 21:54:23 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/sys-info.sh: Removed.  (This was not actually in TESTS
+       in Makefile.am, so it was never called.  command/sysfile-info.sh
+       does what it was trying to do, but better.)
+       
+Sat Jul 30 21:50:33 2005  Ben Pfaff  <blp@gnu.org>
+
+       Fixes for Solaris.
+
+       * Most tests: Add `cd /' before `rm -rf $TEMPDIR' because some
+       OSes do not allow the current working directory to be removed.
+
+       * bugs/big-input-2.sh: Use perl instead of a shell loop, because
+       the shell loop was very slow on Solaris.
+
+       * command/sort.sh: Use `printf' instead of `echo -n' for
+       portability. 
+       
+Sat Jul 30 21:48:37 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add coverage.sh, temp_template to EXTRA_DIST.
+
+Sun Jul 24 20:35:04 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/sysfile-info.sh: Add "-b -B -w" to diff command line.
+       Fixes apparent failure under Cygwin.  Thanks to John Darrington
+       <john@cellform.com.au> for reporting this problem.
+
+Mon Jul  4 18:02:44 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/sysfile-info.sh: Don't verify endianness.  Fixes bug
+       reported by "Marshall DeBerry" <mdb@radix.net>.
+
+Mon Jun  6 22:40:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/print.sh: Get rid of RBHEX output.  It wasn't worth
+       much.  Fixes bug 12312.
+
+Tue May 10 19:59:10 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/agg-crash-2.sh: Fix output given bug 13054.
+
+Wed May  4 23:50:02 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/match-files-scratch.sh: New test for bug 12948.
+
+       * Makefile.am: (TESTS) Add bugs/match-files-scratch.sh.
+
+Sun May  1 23:18:37 2005  Ben Pfaff  <blp@gnu.org>
+
+       Most tests: changed capitalization of variable names in
+       definitions or in output, because now we preserve it.
+
+Mon Apr 25 23:30:17 2005  Ben Pfaff  <blp@gnu.org>
+
+       * commands/match-files.sh: New test.
+
+       * Makefile.am: (TESTS) Add commands/match-files.sh.
+
+Sun Apr 17 16:38:00 2005  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.stat, data-fmts.stat, do-if.stat, do-repeat.stat,
+       gengarbage.c, inpt-pgm.stat, mdfy-vars.stat, means.stat,
+       mtch-file.stat, pcs-if.stat, recode.stat, repeating.stat,
+       reread.data, reread.stat, sys-info.stat, t-test.stat,
+       temporary.stat, time-date.stat, vector.stat: Removed because they
+       were unused.
+
+       * Makefile.am: Removed sort.data references.  Fixed up
+       DISTCLEANFILES.
+
+Sun Mar 20 14:16:31 2005  Ben Pfaff  <blp@gnu.org>
+
+       * command/aggregate.sh: Rewrite.
+
+Mon Mar 14 21:58:23 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS_ENVIRONMENT) Add PERL to the test
+       environment.
+
+       * commands/sort.sh: Rewrite to test more thoroughly and to verify
+       that the sort is stable.
+       
+Sat Mar 12 23:30:37 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/agg-crash-2.sh, bugs/big-input-2.sh, command/aggregate.sh:
+       Fix AGGREGATE command syntax.
+
+Sat Mar 12 13:16:34 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/temp-freq.sh: Add another test.
+
+Fri Mar 11 10:40:41 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/expressions.sh: Add another test.
+
+Sun Mar  6 19:30:14 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/vectors.sh: New test.
+
+       * Makefile.am: Add expressions/vectors.sh.
+
+Sun Mar  6 17:56:27 2005  Ben Pfaff  <blp@gnu.org>
+
+       * expressions/expressions.sh: Add tests for generic optimizations.
+
+Sun Mar  6 11:03:58 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Add expressions/variables.sh.  Remove expr.stat.
+
+       * expr.stat: Removed.
+
+'Mon Feb 28 23:31:16 2005  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Removed xforms/expressions.sh.  Added
+       expressions/expressions.sh, expressions/epoch.sh,
+       expressions/randist.sh.
+
+       * command/print.sh: Update error messages.
+
+Sun Feb 13 16:15:09 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/agg-crash-2.sh: Add new test for Bug #11955.
+
+Fri Feb 11 23:27:08 2005  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/crosstabs-crash.sh: Add new test for Bug #11916.
+
+Tue Jan 18 19:25:24 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * Canonicalised (some of) the tests' temp file names to make it
+       easier to recognise valgrind ouput.
+
+Sun Jan  9 16:39:08 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+       * bugs/big-input-2.sh Made the test a bit faster
+
+John Darrington <john@darrington.wattle.id.au>
+
+       * command/examine.sh Added
+       
+Mon Nov 15 23:52:55 2004  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/random.sh: Update expected random values to reflect the GSL
+       random number generator.
+
+Sat Nov  6 14:49:27 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * command/oneway-with-splits.sh  Added.
+
+Sun Oct 31 16:08:47 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * bugs/recode-copy-bug.sh bugs/computebug.sh  Fixed problem which 
+       caused make distcheck to not know where some critical files were.
+
+Mon May 31 21:49:19 2004  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/t-test-with-temp.sh: Use $SUPERVISOR.
+
+       * bugs/t-test-1-indep-val.sh: Ditto.
+
+       * bugs/t-test-1-sample-missing-anal.sh: Ditto.
+       
+       * bugs/t-test-1-sample-missing-list.sh: Ditto.
+
+       * bugs/t-test-1s.sh: Ditto.
+
+       * bugs/t-test-groups.sh: Ditto.
+
+       * bugs/t-test-indep-missing-anal.sh: Ditto.
+
+       * bugs/t-test-indep-missing-list.sh: Ditto.
+
+       * bugs/t-test-paired-missing-anal.sh: Ditto.
+
+       * bugs/t-test-paired-missing-list.sh: Ditto.
+
+       * bugs/t-test-pairs.sh: Ditto.
+
+Sun May 30 19:18:26 2004  Ben Pfaff  <blp@gnu.org>
+
+       * command/tabs.sh: Default tab width is now 4.
+
+       * command/data-list.sh: New test.
+
+       * Makefile.am: (TESTS) Add command/data-list.sh.
+
+Sun Apr 11 14:21:16 2004  Ben Pfaff  <blp@gnu.org>
+
+       * stats/moments.sh: Now that our one-pass moments algorithm is
+       better we don't have to omit any of the test cases for it.
+
+Fri Apr  9 20:03:33 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS) Add stats/descript-mean-bug.sh.
+
+       * stats/descript-mean-bug.sh: Add test for a bug where
+       DESCRIPTIVES asking only for the mean assert-failed.
+
+Sat Apr  3 11:42:31 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS) Add bugs/comment-at-eof.sh.  Alphabetize
+       test order.
+       
+       * bugs/comment-at-eof.sh: Add test for a bug where a comment at
+       end of file caused an infinite loop.
+
+Sat Mar 27 11:29:06 WST 2004 John Darrington <john@darrington.wattle.id.au>
+
+       * bugs/get.sh Added regression test for a bug in loading a dictionary
+       with the GET command.
+
+Tue Mar 30 22:10:08 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS) Add bugs/multipass.sh.
+
+Mon Mar 29 15:25:09 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS) Add xforms/casefile.sh,
+       stats/descript-basic.sh, stats/descript-missing.sh,
+       stats/moments.sh.  Remove command/descriptives.sh.
+
+       * command/descriptives.sh: Removed.
+
+       * command/weight.sh: Fix output (statistic values were wrong!).
+
+       * stats/descript-basic.sh: New test.
+       
+       * stats/descript-missing.sh: New test.
+       
+       * stats/moments.sh: New test.
+
+       * xforms/casefile.sh: New test.
+
+       * xforms/expressions.sh: Cleans up after itself now.
+
+Fri Mar 26 00:55:48 2004  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (TESTS) Add xforms/expressions.sh, remove
+       command/compute.sh.
+
+       * command/beg-data.sh: Remove REMARK usage.
+
+       * command/bignum.sh: Ditto.
+
+       * command/list.sh: Ditto.
+
+       * command/print.sh: Ditto.
+
+Sat Mar 20 18:11:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       * command/list.sh: Update output.
+
+       * command/print.sh: Ditto.
+
+       * command/weight.sh: Ditto.
+
+Sun Mar 14 23:04:14 2004  Ben Pfaff  <blp@gnu.org>
+
+       * command/sort.sh: Use numeric, not string, data to avoid spurious
+       valgrind complaints.
+
+Wed Mar 10 21:22:03 2004  Ben Pfaff  <blp@gnu.org>
+
+       * bugs/temporary.sh: Test that basic use of TEMPORARY works.
+
+Mon Feb 16 21:36:57 2004  Ben Pfaff  <blp@gnu.org>
+
+       * */*.sh: Prepend $SUPERVISOR to invocations of pspp so that we
+       can run valgrind or gdb easily with `make check'
+
+Sat Dec 13 00:08:23 2003  Ben Pfaff  <blp@gnu.org>
+
+       * syntax: Run a diff when there's no expected output, too.
+
+Fri Jan  7 20:30:23 2000  Ben Pfaff  <blp@gnu.org>
+
+       * data-fmts.stat: Add more date tests.
+
+       * do-repeat.stat: SET ECHO ON.
+
+       * syntax: Replace test -L with test -h.
+
+Tue Jan  5 14:21:52 1999  Ben Pfaff  <blp@gnu.org>
+
+       * data-list.stat, data-list.data: Adjust so that it can tell if
+       DATA LIST FREE properly parses and pads string values.
+
+       * list.stat: Remove anachronistic `SET EMULATION PC'.
+
+       * Rebuilt benchmark.
+
+Tue Jan  5 14:12:58 1999  Ben Pfaff  <blp@gnu.org>
+
+       * syntax: Replaced `test' calls with `['.  This may or may not fix
+       the problems some people have reported.
+
+Sun Aug  9 11:15:38 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Update for renamed files.
+
+       * autorecode.stat: Renamed autorecod.stat.
+
+       * begin-data.stat: Renamed beg-data.stat.
+
+       * data-formats.stat: Renamed data-fmts.stat.
+
+       * expression.stat: Renamed expr.stat.
+
+       * file-label.stat: Renamed file-lab.stat.
+
+       * input-program.stat: Renamed inpt-pgm.stat.
+
+       * modify-vars.stat: Renamed mdfy-vars.stat.
+
+       * match-files.stat: Renamed mtch-file.stat.
+
+       * process-if.stat: Renamed pcs-if.stat.
+
+       * split-file.stat: Renamed splt-file.stat.
+
+       * sysfile-info.stat: Renamed sys-info.stat.
+
+       * expect/: Refreshed.
+
+Sat Aug  8 00:27:07 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add `syntax'.
+       (dist-hook) New target.
+
+Wed Aug  5 00:04:16 1998  Ben Pfaff  <blp@gnu.org>
+
+       * TEST-RESULTS: Removed.
+
+       * show-check-msg: Removed.
+
+       * expect/: New.
+
+       * syntax: New.  Thanks to James R. Van Zandt <jrv@vanzandt.mv.com>
+       for this implementation of automatic testing.
+
+       * Makefile: (TESTS) Set to the syntax script.
+       (bench) New target.
+       (EXTRA_DIST) Remove TEST-RESULTS.  Add `syntax'.
+
+Sun Jul  5 14:16:18 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add flip.stat.
+
+Sun Jul  5 00:50:41 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.stat: Change to test /MISSING=REPORT.
+
+Tue Jun  2 23:42:23 1998  Ben Pfaff  <blp@gnu.org>
+
+       * flip.stat: New file.
+       
+       * weighting.stat: Update.
+
+Mon May 25 12:45:46 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add crosstabs.stat, match-files.stat.
+
+       * crosstabs.stat: Turn off cells=all.
+
+Tue May 12 16:22:06 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.stat: Minor changes.
+
+Thu May  7 23:16:03 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.stat: Replace with a test that is hopefully better.
+
+Tue Apr 14 01:00:46 1998  Ben Pfaff  <blp@gnu.org>
+
+       * crosstabs.stat: New.
+
+Mon Mar  9 15:40:25 1998  Ben Pfaff  <blp@gnu.org>
+
+       * match-files.stat: More thorough.
+
+Mon Mar  9 01:14:14 1998  Ben Pfaff  <blp@gnu.org>
+
+       * match-files.stat: More thorough.
+
+1998-03-05  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Use ./gengarbage instead of gengarbage.
+
+1998-02-23  Ben Pfaff  <blp@gnu.org>
+
+       * Many tests: Remove final finish command.
+
+1998-02-16  Ben Pfaff  <blp@gnu.org>
+
+       * (DISTCLEANFILES) Clean *.save, pspp.*, foo*
+
+       * file-label.stat, sysfile-info.stat: Replace .sav with .save.
+
+       * match-files.stat: New file.
+       
+Fri Feb 13 15:58:11 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add TEST-RESULTS.
+
+Tue Jan 13 01:11:36 1998  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.stat: Some more testing.
+
+Sat Jan 10 23:57:14 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (DISTCLEANFILES) Add aggregate.save.
+
+       * aggregate.stat: Slightly more thorough.
+
+Sat Jan 10 02:17:00 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add means.stat, t-test.stat.
+       
+       * means.stat: New file.
+
+Thu Jan  8 22:38:59 1998  Ben Pfaff  <blp@gnu.org>
+
+       * Many tests: Removed extra newlines from REMARKs.
+
+Mon Jan  5 11:18:44 1998  Ben Pfaff  <blp@gnu.org>
+
+       * sysfile-info.stat: Test most of the DISPLAY commands.  Update
+       title.
+
+       * vector.stat: Display vectors.
+
+Sun Jan  4 18:31:36 1998  Ben Pfaff  <blp@gnu.org>
+
+       * All tests: Added title.
+
+       * begin-data.stat: Updated REMARK format.
+
+       * descript.stat: Comment fix.
+
+Sun Dec 21 16:57:31 1997  Ben Pfaff  <blp@gnu.org>
+
+       * TEST-RESULTS: New file.
+
+Fri Dec  5 22:02:20 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (DISTCLEANFILES) Add fiasco.html.
+
+Tue Dec  2 14:55:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * t-test.stat: New file.
+
+Fri Nov 14 00:17:25 1997  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.stat: Changed.      
+
+Tue Oct 28 16:26:25 1997  Ben Pfaff  <blp@gnu.org>
+
+       * aggregate.stat: New file.
+
+       * Makefile.am: (EXTRA_DIST) Add aggregate.stat.
+
+Sun Oct  5 16:02:02 1997  Ben Pfaff  <blp@gnu.org>
+
+       * fall92.stat, fall92.data: Removed (unknown copyright).
+
+       * gengarbage.c: Define EXIT_SUCCESS if not defined by headers.
+       From Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+Sat Oct  4 16:35:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * repeating.stat: New file.
+
+       * Makefile.am: (EXTRA_DIST) Add repeating.stat.
+
+Thu Sep 18 21:40:50 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add lag.stat.
+
+Mon Aug 18 18:31:42 1997  Ben Pfaff  <blp@gnu.org>
+
+       * do-repeat.stat: Even more useful.
+
+       * lag.stat: New file.
+
+Sun Aug 17 22:47:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * do-repeat.stat: Made actually useful, not stupid.
+
+Sun Aug  3 11:46:00 1997  Ben Pfaff  <blp@gnu.org>
+
+       * In several files, replace usage of deprecated term `script' by
+       `syntax file'.
+
+Thu Jul 17 02:12:17 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Add tabs.stat.
+
+       * file-label.stat: Improved.
+
+       * sysfile-info.stat: Tests DISPLAY DICTIONARY now as well.
+
+Fri Jul 11 14:13:49 1997  Ben Pfaff  <blp@gnu.org>
+
+       * gengarbage.c: Reformat.  #include's <time.h>.  Uses ANSI C
+       rand() in place of random().  Calls the randomizer srand().
+
+Thu Jul 10 22:16:34 1997  Ben Pfaff  <blp@gnu.org>
+
+       * tabs.stat: New file.
+
+Wed Jun 25 22:54:40 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: (EXTRA_DIST) Removed bug.stat, file-type.stat.
+
+Sun Jun  8 01:24:55 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Added fiasco.ps, fiasco.list, foo, foo.sav, msgs to
+       DISTCLEANFILES.
+
+       * input-program.stat: Made some variables scratch.
+
+Fri Jun  6 22:53:03 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Many files: Comment fixes, removed `set output raw.' commands.
+
+       * Other miscellaneous changes.
+
+Tue Jun  3 23:44:46 1997  Ben Pfaff  <blp@gnu.org>
+
+       * list.stat: Re-enabled some of it.
+
+Wed Apr 23 21:33:48 1997  Ben Pfaff  <blp@gnu.org>
+
+       * sysfile-info.stat: A little more generalized now.
+
+Fri Apr 18 15:42:22 1997  Ben Pfaff  <blp@gnu.org>
+
+       * Makefile.am: Maintainer-clean Makefile.in.
+       
+Thu Mar 27 01:11:29 1997  Ben Pfaff  <blp@gnu.org>
+
+       * gengarbage.pl: Removed.
+       
+Sat Feb 15 21:26:53 1997  Ben Pfaff  <blp@gnu.org>
+
+       * descript.stat: Syntax fixes.
+
+       * process-if.stat: New test for PROCESS IF.
+
+Sun Jan 19 14:22:11 1997  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.stat, modify-vars.stat: More thorough.
+
+       * data-formats.stat, file-label.stat: New tests.
+       
+Thu Jan 16 13:08:57 1997  Ben Pfaff  <blp@gnu.org>
+
+       * bug.stat: Comment fix.
+
+Wed Jan  1 22:08:10 1997  Ben Pfaff  <blp@gnu.org>
+
+       * filter.stat: New file; tests FILTER behavior.
+
+Wed Jan  1 17:00:59 1997  Ben Pfaff  <blp@gnu.org>
+
+       * gengarbage.pl: New perl program equivalent to gengarbage.c.
+
+Sun Dec 29 21:36:48 1996  Ben Pfaff  <blp@gnu.org>
+
+       * gengarbage.c: Changed.
+
+       * sort.stat: Changed.
+
+Sun Dec 22 23:10:39 1996  Ben Pfaff  <blp@gnu.org>
+
+       * sort.stat: New file.
+
+Fri Dec 13 21:30:53 1996  Ben Pfaff  <blp@gnu.org>
+
+       * autorecode.stat: New file.
+
+       * fall92.stat: Mods for practicality.
+
+       * test.bat, testall.bat: Removed.
+       
+Thu Nov 28 23:14:07 1996  Ben Pfaff  <blp@gnu.org>
+
+       * list.stat, weighting.stat: Changed SET COMPATIBILITY subcommand
+       to SET EMULATION in anticipation of change.
+
+Sat Oct 26 23:06:06 1996  Ben Pfaff  <blp@gnu.org>
+
+       * recode.stat: Removed comment about bug, since I fixed that.
+
+Thu Oct 24 20:13:42 1996  Ben Pfaff  <blp@gnu.org>
+
+       * print.stat: Slightly more thorough.
+
+Thu Oct 24 17:47:14 1996  Ben Pfaff  <blp@gnu.org>
+
+       * time-date.stat: Slightly more thorough.
+
+Wed Oct 23 21:53:43 1996  Ben Pfaff  <blp@gnu.org>
+
+       * time-date.stat: New file.
+
+Thu Sep 26 22:20:26 1996  Ben Pfaff  <blp@gnu.org>
+
+       * list.data: More data.
+
+       * list.stat: Handles all that extra data.
+
+       * weighting.stat: Doesn't try to list $WEIGHT because PC+ isn't
+       quite supported yet.
+
+Wed Sep  4 21:45:35 1996  Ben Pfaff  <blp@gnu.org>
+
+       * weighting.stat: Tests for proper ligatures.  Won't work until
+       encodings are correct, of course...
+
+----------------------------------------------------------------------
+Local Variables:
+mode: change-log
+version-control: never
+End:
index 1dd783238fe6011ff710c5c2460e29217640a606..082889cdedfe26d098dff3a4c9bd9196a59c7fe4 100644 (file)
@@ -6,8 +6,11 @@ TESTS_ENVIRONMENT += PERL='@PERL@' PG_CONFIG='@PG_CONFIG@'
 # Allow locale_charset to find charset.alias before running "make install".
 TESTS_ENVIRONMENT += CHARSETALIASDIR='$(abs_top_builddir)/gl'
 
+TESTS_ENVIRONMENT += LC_ALL=C
+
 dist_TESTS = \
        tests/command/aggregate.sh \
+       tests/command/attributes.sh \
        tests/command/autorecod.sh \
        tests/command/beg-data.sh \
        tests/command/bignum.sh \
@@ -40,6 +43,7 @@ dist_TESTS = \
        tests/command/n_of_cases.sh \
        tests/command/npar-binomial.sh \
        tests/command/npar-chisquare.sh \
+       tests/command/npar-wilcoxon.sh \
        tests/command/oneway.sh \
        tests/command/oneway-missing.sh \
        tests/command/oneway-with-splits.sh \
@@ -50,6 +54,7 @@ dist_TESTS = \
        tests/command/rename.sh \
        tests/command/regression.sh \
        tests/command/regression-qr.sh \
+       tests/command/reliability.sh \
        tests/command/sample.sh \
        tests/command/sort.sh \
        tests/command/sysfiles.sh \
@@ -107,6 +112,7 @@ dist_TESTS = \
        tests/bugs/double-frequency.sh \
        tests/bugs/empty-do-repeat.sh \
        tests/bugs/get.sh \
+       tests/bugs/examine-crash.sh \
        tests/bugs/examine-1sample.sh \
        tests/bugs/examine-missing.sh \
        tests/bugs/examine-missing2.sh \
@@ -167,6 +173,8 @@ nodist_TESTS = \
        tests/libpspp/abt-test \
        tests/libpspp/bt-test \
        tests/libpspp/heap-test \
+       tests/libpspp/hmap-test \
+       tests/libpspp/hmapx-test \
        tests/libpspp/ll-test \
        tests/libpspp/llx-test \
        tests/libpspp/range-map-test \
@@ -186,6 +194,7 @@ tests_libpspp_ll_test_SOURCES = \
        src/libpspp/ll.h \
        tests/libpspp/ll-test.c
 tests_libpspp_ll_test_LDADD = gl/libgl.la @LIBINTL@
+tests_libpspp_ll_test_CFLAGS = $(AM_CFLAGS)
 
 tests_libpspp_llx_test_SOURCES = \
        src/libpspp/ll.c \
@@ -194,6 +203,7 @@ tests_libpspp_llx_test_SOURCES = \
        src/libpspp/llx.h \
        tests/libpspp/llx-test.c
 tests_libpspp_llx_test_LDADD = gl/libgl.la @LIBINTL@
+tests_libpspp_llx_test_CFLAGS = $(AM_CFLAGS)
 
 tests_libpspp_heap_test_SOURCES = \
        src/libpspp/heap.c \
@@ -204,6 +214,22 @@ tests_libpspp_heap_test_SOURCES = \
 tests_libpspp_heap_test_LDADD = gl/libgl.la @LIBINTL@
 tests_libpspp_heap_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
 
+tests_libpspp_hmap_test_SOURCES = \
+       src/libpspp/hmap.c \
+       src/libpspp/hmap.h \
+       tests/libpspp/hmap-test.c
+tests_libpspp_hmap_test_LDADD = gl/libgl.la @LIBINTL@
+tests_libpspp_hmap_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
+
+tests_libpspp_hmapx_test_SOURCES = \
+       src/libpspp/hmap.c \
+       src/libpspp/hmap.h \
+       src/libpspp/hmapx.c \
+       src/libpspp/hmapx.h \
+       tests/libpspp/hmapx-test.c
+tests_libpspp_hmapx_test_LDADD = gl/libgl.la @LIBINTL@
+tests_libpspp_hmapx_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
+
 tests_libpspp_abt_test_SOURCES = \
        src/libpspp/abt.c \
        src/libpspp/abt.h \
@@ -240,7 +266,7 @@ tests_libpspp_range_set_test_CPPFLAGS = $(AM_CPPFLAGS) -DASSERT_LEVEL=10
 
 tests_libpspp_str_test_SOURCES = \
        tests/libpspp/str-test.c
-tests_libpspp_str_test_LDADD = src/libpspp/libpspp.a gl/libgl.la @LIBINTL@
+tests_libpspp_str_test_LDADD = src/libpspp/libpspp.la gl/libgl.la @LIBINTL@
 
 tests_libpspp_tower_test_SOURCES = \
        src/libpspp/abt.c \
@@ -270,6 +296,7 @@ tests_dissect_sysfile_SOURCES = \
        src/libpspp/float-format.c \
        tests/dissect-sysfile.c
 tests_dissect_sysfile_LDADD = gl/libgl.la @LIBINTL@
+tests_dissect_sysfile_CPPFLAGS = $(AM_CPPFLAGS) -DINSTALLDIR=\"$(bindir)\"
 
 EXTRA_DIST += \
        $(dist_TESTS) \
@@ -311,8 +338,11 @@ EXTRA_DIST += \
 
 CLEANFILES += *.save pspp.* foo*
 
-dist-hook:
+DIST_HOOKS += check-for-export-var-val
+check-for-export-var-val:
        @if grep -q 'export .*=' $(dist_TESTS) ; then \
         echo 'One or more tests contain non-portable "export VAR=val" syntax' ; \
         false ; \
        fi
+
+EXTRA_DIST += tests/OChangeLog
index 99ec07cac271ebf44c7fbccd528ef9547122d144..eea89304599d63e3c7558ed21f9775f84f40c9f1 100755 (executable)
@@ -108,7 +108,7 @@ diff -b  -w $TEMPDIR/pspp.list - << EOF
 #           5.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
 #           6.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
 #           7.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
-#Total          #     .0%|     .0%|     .0%|     .0%|    1.0%|     .0%|     .0%|    1.0%#
+#Total          #      .0|      .0|      .0|      .0|     1.0|      .0|      .0|     1.0#
 #===============#========#========#========#========#========#========#========#========#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
index 5866d0e58c584d5ca28f8a611dca22372c1094e7..060fa234378eaa0a926da02cf08d64d77a01a386 100755 (executable)
@@ -108,7 +108,7 @@ $TEMPDIR/crosstabs-crash2.sh.sps:6: warning: BEGIN DATA: Missing value(s) for al
 #           1.00#     1.0|      .0|      .0|     1.0|     2.0#
 #           2.00#      .0|      .0|     1.0|      .0|     1.0#
 #           3.00#      .0|     1.0|      .0|      .0|     1.0#
-#Total          #    1.0%|    1.0%|    1.0%|    1.0%|    4.0%#
+#Total          #     1.0|     1.0|     1.0|     1.0|     4.0#
 #===============#========#========#========#========#========#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
diff --git a/tests/bugs/examine-crash.sh b/tests/bugs/examine-crash.sh
new file mode 100755 (executable)
index 0000000..6cd172f
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+# This program tests for a bug which crashed EXAMINE
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+# ensure that top_srcdir and top_builddir  are absolute
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+top_srcdir=`cd $top_srcdir; pwd`
+top_builddir=`cd $top_builddir; pwd`
+
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+LANG=C
+export LANG
+
+
+cleanup()
+{
+     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
+       echo "NOT cleaning $TEMPDIR"
+       return ; 
+     fi
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+cat <<EOF > $TESTFILE
+data list list /a * x * y *.
+begin data.
+3 1 3
+5 1 4
+7 2 3
+end data.
+
+examine a by x by y
+       /statistics=DESCRIPTIVES
+       . 
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass;
index 965b600ee230f2eff7e9adf5e8bcbc69d2cfba95..97b192625f60b6d4752c7a1109f89fcb22705213 100755 (executable)
@@ -92,26 +92,26 @@ diff -b  $TEMPDIR/pspp.list - <<EOF
 |y       |F8.0  |
 +--------+------+
 2.1 EXAMINE.  Case Processing Summary
-#=#=============================#
-# #            Cases            #
-# #---------+---------+---------#
-# #  Valid  | Missing |  Total  #
-# #-+-------+-+-------+-+-------#
-# #N|Percent|N|Percent|N|Percent#
-#=#=#=======#=#=======#=#=======#
-#x#6|    86%|1|    14%|7|   100%#
-#=#=#=======#=#=======#=#=======#
+#=#===============================#
+# #             Cases             #
+# #----------+----------+---------#
+# #   Valid  |  Missing |  Total  #
+# #-+--------+-+--------+-+-------#
+# #N| Percent|N| Percent|N|Percent#
+#=#=#========#=#========#=#=======#
+#x#6|85.7143%|1|14.2857%|7|   100%#
+#=#=#========#=#========#=#=======#
 2.2 EXAMINE.  Case Processing Summary
-#==========#=============================#
-#          #            Cases            #
-#          #---------+---------+---------#
-#          #  Valid  | Missing |  Total  #
-#          #-+-------+-+-------+-+-------#
-#      y   #N|Percent|N|Percent|N|Percent#
-#==========#=#=======#=#=======#=#=======#
-#x     1.00#4|   100%|0|     0%|4|   100%#
-#      2.00#2|    67%|1|    33%|3|   100%#
-#==========#=#=======#=#=======#=#=======#
+#==========#===============================#
+#          #             Cases             #
+#          #----------+----------+---------#
+#          #   Valid  |  Missing |  Total  #
+#          #-+--------+-+--------+-+-------#
+#      y   #N| Percent|N| Percent|N|Percent#
+#==========#=#========#=#========#=#=======#
+#x     1.00#4|    100%|0|      0%|4|   100%#
+#      2.00#2|66.6667%|1|33.3333%|3|   100%#
+#==========#=#========#=#========#=#=======#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
index 0992e45bced84e734faab4dd25c57b00c68a2f39..63abc6f3b003ac093ee59434736522d9d64d27c8 100755 (executable)
@@ -146,6 +146,8 @@ cat > agg-skel.pspp <<EOF
        /NPOUT23I = pout.(n, 2, 3)
        /SPOUT23 = pout(s, '2', '3')
        /SPOUT23I = pout.(s, '2', '3')
+       /NMEDIAN = median(n)
+       /NMEDIANI = median.(n)
        /NSD = sd(n)
        /NSDI = sd.(n)
        /NSUM = sum(n)
@@ -158,12 +160,13 @@ warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-o
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-G        N       NI      NU     NUI NFGT2 NFGT2I SFGT2 SFGT2I NFIN23 NFIN23I SFIN23 SFIN23I NFLT2 NFLT2I SFLT2 SFLT2I NFIRST NFIRSTI SFIRST SFIRSTI NFOUT23 NFOUT23I SFOUT23 SFOUT23I NLAST NLASTI SLAST SLASTI NMAX NMAXI SMAX SMAXI    NMEAN   NMEANI NMIN NMINI SMIN SMINI       NN      NNI       SN      SNI   NNMISS  NNMISSI   SNMISS  SNMISSI     NNU    NNUI     SNU    SNUI NNUMISS NNUMISSI SNUMISS SNUMISSI NPGT2 NPGT2I SPGT2 SPGT2I NPIN23 NPIN23I SPIN23 SPIN23I NPLT2 NPLT2I SPLT2 SPLT2I NPOUT23 NPOUT23I SPOUT23 SPOUT23I      NSD     NSDI     NSUM    NSUMI
-- -------- -------- ------- ------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------ ------- ------ ------- ------- -------- ------- -------- ----- ------ ----- ------ ---- ----- ---- ----- -------- -------- ---- ----- ---- ----- -------- -------- -------- -------- -------- -------- -------- -------- ------- ------- ------- ------- ------- -------- ------- -------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------- -------- ------- -------- -------- -------- -------- --------
-1     7.00     7.00       6       6  .333   .429  .333   .429   .333    .286   .333    .286  .500   .429  .500   .429      0       0      0       0    .667     .714    .667     .714     5      5     5      5    5     5    5     5     2.00     2.29    0     0    0     0     6.00     7.00     6.00     7.00     1.00      .00     1.00      .00       5       6       5       6       1        0       1        0  33.3   42.9  33.3   42.9   33.3    28.6   33.3    28.6  50.0   42.9  50.0   42.9    66.7     71.4    66.7     71.4     1.79     1.80    12.00    16.00 
-2     5.00     5.00       4       4 1.000  1.000 1.000  1.000   .000    .000   .000    .000  .000   .000  .000   .000      6       6      6       4   1.000    1.000   1.000    1.000     8      8     8      8    8     8    8     8     7.00     7.00    6     6    6     4     3.00     3.00     3.00     5.00     2.00     2.00     2.00      .00       3       3       3       4       1        1       1        0 100.0  100.0 100.0  100.0     .0      .0     .0      .0    .0     .0    .0     .0   100.0    100.0   100.0    100.0     1.00     1.00    21.00    21.00 
-3     2.00     2.00       1       1  .000   .000  .000   .000   .000    .000   .000    .000 1.000  1.000 1.000  1.000      1       1      1       1   1.000    1.000   1.000    1.000     1      1     1      1    1     1    1     1     1.00     1.00    1     1    1     1     2.00     2.00     2.00     2.00      .00      .00      .00      .00       1       1       1       1       0        0       0        0    .0     .0    .0     .0     .0      .0     .0      .0 100.0  100.0 100.0  100.0   100.0    100.0   100.0    100.0      .00      .00     2.00     2.00 
-4     1.00     1.00       1       1  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            4    .     .          4      .        .      .     .          4      .00      .00      .00     1.00     1.00     1.00     1.00      .00       0       0       0       1       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      .        .        .        .   
+G        N       NI      NU     NUI NFGT2 NFGT2I SFGT2 SFGT2I NFIN23 NFIN23I SFIN23 SFIN23I NFLT2 NFLT2I SFLT2 SFLT2I NFIRST NFIRSTI SFIRST SFIRSTI NFOUT23 NFOUT23I SFOUT23 SFOUT23I NLAST NLASTI SLAST SLASTI NMAX NMAXI SMAX SMAXI    NMEAN   NMEANI NMIN NMINI SMIN SMINI       NN      NNI       SN      SNI   NNMISS  NNMISSI   SNMISS  SNMISSI     NNU    NNUI     SNU    SNUI NNUMISS NNUMISSI SNUMISS SNUMISSI NPGT2 NPGT2I SPGT2 SPGT2I NPIN23 NPIN23I SPIN23 SPIN23I NPLT2 NPLT2I SPLT2 SPLT2I NPOUT23 NPOUT23I SPOUT23 SPOUT23I  NMEDIAN NMEDIANI      NSD     NSDI     NSUM    NSUMI
+- -------- -------- ------- ------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------ ------- ------ ------- ------- -------- ------- -------- ----- ------ ----- ------ ---- ----- ---- ----- -------- -------- ---- ----- ---- ----- -------- -------- -------- -------- -------- -------- -------- -------- ------- ------- ------- ------- ------- -------- ------- -------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------- -------- ------- -------- -------- -------- -------- -------- -------- --------
+1     7.00     7.00       6       6  .333   .429  .333   .429   .333    .286   .333    .286  .500   .429  .500   .429      0       0      0       0    .667     .714    .667     .714     5      5     5      5    5     5    5     5     2.00     2.29    0     0    0     0     6.00     7.00     6.00     7.00     1.00      .00     1.00      .00       5       6       5       6       1        0       1        0  33.3   42.9  33.3   42.9   33.3    28.6   33.3    28.6  50.0   42.9  50.0   42.9    66.7     71.4    66.7     71.4     1.50     2.00     1.79     1.80    12.00    16.00 
+2     5.00     5.00       4       4 1.000  1.000 1.000  1.000   .000    .000   .000    .000  .000   .000  .000   .000      6       6      6       4   1.000    1.000   1.000    1.000     8      8     8      8    8     8    8     8     7.00     7.00    6     6    6     4     3.00     3.00     3.00     5.00     2.00     2.00     2.00      .00       3       3       3       4       1        1       1        0 100.0  100.0 100.0  100.0     .0      .0     .0      .0    .0     .0    .0     .0   100.0    100.0   100.0    100.0     7.00     7.00     1.00     1.00    21.00    21.00 
+3     2.00     2.00       1       1  .000   .000  .000   .000   .000    .000   .000    .000 1.000  1.000 1.000  1.000      1       1      1       1   1.000    1.000   1.000    1.000     1      1     1      1    1     1    1     1     1.00     1.00    1     1    1     1     2.00     2.00     2.00     2.00      .00      .00      .00      .00       1       1       1       1       0        0       0        0    .0     .0    .0     .0     .0      .0     .0      .0 100.0  100.0 100.0  100.0   100.0    100.0   100.0    100.0     1.00     1.00      .00      .00     2.00     2.00 
+4     1.00     1.00       1       1  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            4    .     .          4      .        .      .     .          4      .00      .00      .00     1.00     1.00     1.00     1.00      .00       0       0       0       1       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      NaN      NaN      .        .        .        .   
+
 EOF
 
 activity="expected output (columnwise missing) create"
@@ -172,12 +175,12 @@ warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-o
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
 warning: AGGREGATE: The value arguments passed to the FOUT function are out-of-order.  They will be treated as if they had been specified in the correct order.
-G        N       NI      NU     NUI NFGT2 NFGT2I SFGT2 SFGT2I NFIN23 NFIN23I SFIN23 SFIN23I NFLT2 NFLT2I SFLT2 SFLT2I NFIRST NFIRSTI SFIRST SFIRSTI NFOUT23 NFOUT23I SFOUT23 SFOUT23I NLAST NLASTI SLAST SLASTI NMAX NMAXI SMAX SMAXI    NMEAN   NMEANI NMIN NMINI SMIN SMINI       NN      NNI       SN      SNI   NNMISS  NNMISSI   SNMISS  SNMISSI     NNU    NNUI     SNU    SNUI NNUMISS NNUMISSI SNUMISS SNUMISSI NPGT2 NPGT2I SPGT2 SPGT2I NPIN23 NPIN23I SPIN23 SPIN23I NPLT2 NPLT2I SPLT2 SPLT2I NPOUT23 NPOUT23I SPOUT23 SPOUT23I      NSD     NSDI     NSUM    NSUMI
-- -------- -------- ------- ------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------ ------- ------ ------- ------- -------- ------- -------- ----- ------ ----- ------ ---- ----- ---- ----- -------- -------- ---- ----- ---- ----- -------- -------- -------- -------- -------- -------- -------- -------- ------- ------- ------- ------- ------- -------- ------- -------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------- -------- ------- -------- -------- -------- -------- --------
-1     7.00     7.00       6       6  .      .429  .      .429   .       .286   .       .286  .      .429  .      .429      .       0              0    .        .714    .        .714     .      5            5    .     5          5      .       2.29    .     0          0     6.00     7.00     6.00     7.00     1.00      .00     1.00      .00       5       6       5       6       1        0       1        0    .    42.9    .    42.9     .     28.6     .     28.6    .    42.9    .    42.9      .      71.4      .      71.4      .       1.80      .      16.00 
-2     5.00     5.00       4       4  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            8    .     .          8      .        .      .     .          4     3.00     3.00     3.00     5.00     2.00     2.00     2.00      .00       3       3       3       4       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      .        .        .        .   
-3     2.00     2.00       1       1  .000   .000  .000   .000   .000    .000   .000    .000 1.000  1.000 1.000  1.000      1       1      1       1   1.000    1.000   1.000    1.000     1      1     1      1    1     1    1     1     1.00     1.00    1     1    1     1     2.00     2.00     2.00     2.00      .00      .00      .00      .00       1       1       1       1       0        0       0        0    .0     .0    .0     .0     .0      .0     .0      .0 100.0  100.0 100.0  100.0   100.0    100.0   100.0    100.0      .00      .00     2.00     2.00 
-4     1.00     1.00       1       1  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            4    .     .          4      .        .      .     .          4      .00      .00      .00     1.00     1.00     1.00     1.00      .00       0       0       0       1       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      .        .        .        .   
+G        N       NI      NU     NUI NFGT2 NFGT2I SFGT2 SFGT2I NFIN23 NFIN23I SFIN23 SFIN23I NFLT2 NFLT2I SFLT2 SFLT2I NFIRST NFIRSTI SFIRST SFIRSTI NFOUT23 NFOUT23I SFOUT23 SFOUT23I NLAST NLASTI SLAST SLASTI NMAX NMAXI SMAX SMAXI    NMEAN   NMEANI NMIN NMINI SMIN SMINI       NN      NNI       SN      SNI   NNMISS  NNMISSI   SNMISS  SNMISSI     NNU    NNUI     SNU    SNUI NNUMISS NNUMISSI SNUMISS SNUMISSI NPGT2 NPGT2I SPGT2 SPGT2I NPIN23 NPIN23I SPIN23 SPIN23I NPLT2 NPLT2I SPLT2 SPLT2I NPOUT23 NPOUT23I SPOUT23 SPOUT23I  NMEDIAN NMEDIANI      NSD     NSDI     NSUM    NSUMI
+- -------- -------- ------- ------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------ ------- ------ ------- ------- -------- ------- -------- ----- ------ ----- ------ ---- ----- ---- ----- -------- -------- ---- ----- ---- ----- -------- -------- -------- -------- -------- -------- -------- -------- ------- ------- ------- ------- ------- -------- ------- -------- ----- ------ ----- ------ ------ ------- ------ ------- ----- ------ ----- ------ ------- -------- ------- -------- -------- -------- -------- -------- -------- --------
+1     7.00     7.00       6       6  .      .429  .      .429   .       .286   .       .286  .      .429  .      .429      .       0              0    .        .714    .        .714     .      5            5    .     5          5      .       2.29    .     0          0     6.00     7.00     6.00     7.00     1.00      .00     1.00      .00       5       6       5       6       1        0       1        0    .    42.9    .    42.9     .     28.6     .     28.6    .    42.9    .    42.9      .      71.4      .      71.4      .       2.00      .       1.80      .      16.00 
+2     5.00     5.00       4       4  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            8    .     .          8      .        .      .     .          4     3.00     3.00     3.00     5.00     2.00     2.00     2.00      .00       3       3       3       4       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      .        .        .        .        .        .   
+3     2.00     2.00       1       1  .000   .000  .000   .000   .000    .000   .000    .000 1.000  1.000 1.000  1.000      1       1      1       1   1.000    1.000   1.000    1.000     1      1     1      1    1     1    1     1     1.00     1.00    1     1    1     1     2.00     2.00     2.00     2.00      .00      .00      .00      .00       1       1       1       1       0        0       0        0    .0     .0    .0     .0     .0      .0     .0      .0 100.0  100.0 100.0  100.0   100.0    100.0   100.0    100.0     1.00     1.00      .00      .00     2.00     2.00 
+4     1.00     1.00       1       1  .      .     .     1.000   .       .      .       .000  .      .     .      .000      .       .              4    .        .       .       1.000     .      .            4    .     .          4      .        .      .     .          4      .00      .00      .00     1.00     1.00     1.00     1.00      .00       0       0       0       1       1        1       1        0    .      .     .   100.0     .       .      .       .0    .      .     .      .0      .        .       .     100.0      .        .        .        .        .        .   
 EOF
 
 for outfile in scratch active external; do
diff --git a/tests/command/attributes.sh b/tests/command/attributes.sh
new file mode 100755 (executable)
index 0000000..d4d36e6
--- /dev/null
@@ -0,0 +1,148 @@
+#!/bin/sh
+
+# This program tests VARIABLE ATTRIBUTE and DATAFILE ATTRIBUTE
+# commands, including the ability to write attributes to system files
+# and read them back in again.
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+# ensure that top_builddir  are absolute
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+top_builddir=`cd $top_builddir; pwd`
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+# ensure that top_srcdir is absolute
+top_srcdir=`cd $top_srcdir; pwd`
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+
+cleanup()
+{
+     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
+       echo "NOT cleaning $TEMPDIR" 
+       return ; 
+     fi
+     cd /
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+activity="create program"
+cat > $TESTFILE <<EOF
+DATA LIST FREE/a b c.
+BEGIN DATA.
+1 2 3
+END DATA.
+
+DATAFILE ATTRIBUTE
+       ATTRIBUTE=key('value')
+                  array('array element 1')
+                  Array[2]('array element 2').
+VARIABLE ATTRIBUTE
+        VARIABLES=a b
+        ATTRIBUTE=ValidationRule[2]("a + b > 2")
+                  ValidationRule[1]('a * b > 3')
+       /VARIABLES=c
+        ATTRIBUTE=QuestionWording('X or Y?').
+DISPLAY ATTRIBUTES.
+
+SAVE OUTFILE='attributes.sav'.
+NEW FILE.
+GET FILE='attributes.sav'.
+
+DATAFILE ATTRIBUTE
+         DELETE=Array[1] Array[2].
+VARIABLE ATTRIBUTE
+         VARIABLES=a
+         DELETE=ValidationRule
+        /VARIABLE=b
+         DELETE=validationrule[2].
+
+DISPLAY ATTRIBUTES.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program"
+$SUPERVISOR $PSPP --testing-mode $TESTFILE
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare output"
+perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
+diff -b  -w $TEMPDIR/pspp.list - << EOF
+1.1 DISPLAY.  
++--------+-----------------+-----------------------------------+
+|Variable|Description      |                                   |
+#========#=================#===================================#
+|a       |Custom attributes|                                   |
+|        |ValidationRule[1]|a * b > 3                          |
+|        |ValidationRule[2]|a + b > 2                          |
++--------+-----------------+-----------------------------------+
+|b       |Custom attributes|                                   |
+|        |ValidationRule[1]|a * b > 3                          |
+|        |ValidationRule[2]|a + b > 2                          |
++--------+-----------------+-----------------------------------+
+|c       |Custom attributes|                                   |
+|        |QuestionWording  |X or Y?                            |
++--------+-----------------+-----------------------------------+
+1.2 DISPLAY.  Custom data file attributes.
++---------+---------------+
+|Attribute|Value          |
+#=========#===============#
+|array[1] |array element 1|
+|array[2] |array element 2|
+|key      |value          |
++---------+---------------+
+2.1 DISPLAY.  
++--------+---------------+-----------------------------------+
+|Variable|Description    |                                   |
+#========#===============#===================================#
+|b       |Custom attribut|s:                                 |
+|        |ValidationRule |a * b > 3                          |
++--------+---------------+-----------------------------------+
+|c       |Custom attribut|s:                                 |
+|        |QuestionWording|X or Y?                            |
++--------+---------------+-----------------------------------+
+2.2 DISPLAY.  Custom data file attributes.
++---------+---------------+
+|Attribute|Value          |
+#=========#===============#
+|array    |array element 2|
+|key      |value          |
++---------+---------------+
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+pass;
index fc648313b4db9cd8710579eee5e8436115770cc4..8524bf5e52807d0f0df5a3ee9bd43d30d91c763c 100755 (executable)
@@ -124,9 +124,9 @@ diff -b  $TEMPDIR/pspp.list - << EOF
 #  ----------#-----------+-----#
 #    Lowest 1#          1| 1.00#
 #           2#          2| 2.00#
-#           3#          4| 3.00#
+#           3#          3| 3.00#
 #           4#          3| 3.00#
-#           5#          3| 3.00#
+#           5#          4| 3.00#
 #           6#          5| 4.00#
 #============#===========#=====#
 EOF
index d63c258709a7b3b049594b47b6e39b00dd421357..095ee0fb93987fcc9735139c39618780c61acabd 100755 (executable)
@@ -148,11 +148,11 @@ Case#  QUALITY        W    BRAND
 #=========================#===========#=====#
 #Breaking Strain Highest 1#         12| 7.00#
 #                        2#         16| 6.00#
-#                               3#         14| 5.00#
+#                               3#          7| 5.00#
 #               ----------#-----------+-----#
-#                 Lowest 1#          4| 1.00#
+#                 Lowest 1#          3| 1.00#
 #                        2#          3| 1.00#
-#                        3#          3| 1.00#
+#                        3#          4| 1.00#
 #=========================#===========#=====#
 2.3 EXAMINE.  Descriptives
 #============================================================#=========#==========#
@@ -188,20 +188,20 @@ Case#  QUALITY        W    BRAND
 #======================================#===========#=====#
 #                Manufacturer          #Case Number|Value#
 #======================================#===========#=====#
-#Breaking Strain Aspeger      Highest 1#          6| 4.00#
-#                                     2#          5| 4.00#
+#Breaking Strain Aspeger      Highest 1#          5| 4.00#
+#                                     2#          6| 4.00#
 #                                     3#          1| 3.00#
 #                            ----------#-----------+-----#
-#                              Lowest 1#          4| 1.00#
+#                              Lowest 1#          3| 1.00#
 #                                     2#          3| 1.00#
-#                                     3#          3| 1.00#
+#                                     3#          4| 1.00#
 #               -----------------------#-----------+-----#
 #                Bloggs       Highest 1#          7| 5.00#
 #                                     2#          9| 4.00#
 #                                     3#          9| 4.00#
 #                            ----------#-----------+-----#
-#                              Lowest 1#         10| 2.00#
-#                                     2#          8| 2.00#
+#                              Lowest 1#          8| 2.00#
+#                                     2#         10| 2.00#
 #                                     3#         11| 3.00#
 #               -----------------------#-----------+-----#
 #                       Charlies     Highest 1#         12| 7.00#
index 354a54f898497c8bcdccaf1ec1af8aae6ec0bf8f..be7f9e08c565c52677a4e0704f92acd86b84a948 100755 (executable)
@@ -2,7 +2,8 @@
 
 # This program tests the INSERT command
 
-TEMPDIR=/tmp/pspp-tst-$$
+BASETEMPDIR=/tmp/pspp-tst-$$
+TEMPDIR=$BASETEMPDIR/link
 TESTFILE=$TEMPDIR/`basename $0`.sps
 
 # ensure that top_srcdir and top_builddir  are absolute
@@ -23,11 +24,11 @@ export LANG
 cleanup()
 {
      if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
-       echo "NOT cleaning $TEMPDIR"
+       echo "NOT cleaning $BASETEMPDIR"
        return ; 
      fi
      cd /
-     rm -rf $TEMPDIR
+     rm -rf $BASETEMPDIR
 }
 
 
@@ -54,7 +55,9 @@ pass()
     exit 0;
 }
 
-mkdir -p $TEMPDIR
+mkdir -p $BASETEMPDIR/target
+
+ln -s $BASETEMPDIR/target $TEMPDIR
 
 cd $TEMPDIR
 
@@ -249,6 +252,4 @@ $TEMPDIR/foo.sps:10: error: DISPLAY: AKSDJ is not a variable name.
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
 
-
-
 pass;
index 2a75f64b5e8ab629dfa50c556f8213c094184c26..49a7cd4c2a26c449034973e35e8f415fb7c5d0c3 100755 (executable)
@@ -119,7 +119,7 @@ AlphaBetaGamma        B        X Yabbadabbadoo
 #           5.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
 #           6.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
 #           7.00#      .0|      .0|      .0|      .0|      .0|      .0|      .0|      .0#
-#Total          #     .0%|     .0%|     .0%|     .0%|    1.0%|     .0%|     .0%|    1.0%#
+#Total          #      .0|      .0|      .0|      .0|     1.0|      .0|      .0|     1.0#
 #===============#========#========#========#========#========#========#========#========#
 EOF
 if [ $? -ne 0 ] ; then fail ; fi
diff --git a/tests/command/npar-wilcoxon.sh b/tests/command/npar-wilcoxon.sh
new file mode 100755 (executable)
index 0000000..c4a5d82
--- /dev/null
@@ -0,0 +1,174 @@
+#!/bin/sh
+
+# This program tests the wilcoxon subcommand of npar tests
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+# ensure that top_srcdir and top_builddir  are absolute
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+top_srcdir=`cd $top_srcdir; pwd`
+top_builddir=`cd $top_builddir; pwd`
+
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+LANG=C
+export LANG
+
+
+cleanup()
+{
+     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
+       echo "NOT cleaning $TEMPDIR"
+       return ; 
+     fi
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+activity="create program 1"
+cat > $TESTFILE <<  EOF
+data list notable list /foo * bar * w *.
+begin data.
+1.00     1.00   1
+1.00     2.00   1
+2.00     1.00   1
+1.00     4.00   1
+2.00     5.00   1
+1.00    19.00   1
+2.00     7.00   1
+4.00     5.00   1
+1.00    12.00   1
+2.00    13.00   1
+2.00     2.00   1
+12.00      .00  2
+12.00     1.00  1
+13.00     1.00  1
+end data
+
+variable labels foo "first" bar "second".
+
+weight by w.
+
+npar test
+ /wilcoxon=foo with bar (paired)
+ /missing analysis
+ /method=exact.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program 1"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="generate results"
+cat > $TEMPDIR/results.txt <<EOF
+1.1 NPAR TESTS.  Ranks
+#============================#==#=========#============#
+#                            # N|Mean Rank|Sum of Ranks#
+#============================#==#=========#============#
+#second - firstNegative Ranks# 5|     8.60|       43.00#
+#              Positive Ranks# 8|     6.00|       48.00#
+#              Ties          # 2|         |            #
+#              Total         #15|         |            #
+#============================#==#=========#============#
+
+1.2 NPAR TESTS.  Test Statistics
+#=====================#==============#
+#                     #second - first#
+#=====================#==============#
+#Z                    #         -.175#
+#Asymp. Sig (2-tailed)#          .861#
+#Exact Sig (2-tailed) #          .893#
+#Exact Sig (1-tailed) #          .446#
+#=====================#==============#
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="compare output 1"
+diff pspp.list $TEMPDIR/results.txt
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+# No weights this time. But some missing values
+activity="create program 2"
+cat > $TESTFILE <<  EOF
+data list notable list /foo * bar * dummy *.
+begin data.
+1.00     1.00    1
+1.00     2.00    1
+2.00     1.00    1
+1.00     4.00    .
+2.00     5.00    .
+1.00    19.00    .
+2.00     7.00    1
+4.00     5.00    1
+1.00    12.00    1
+2.00    13.00    1
+2.00     2.00    1
+12.00      .00   1
+12.00      .00   1
+34.2       .     1
+12.00     1.00   1  
+13.00     1.00   1
+end data
+
+variable labels foo "first" bar "second".
+
+npar test
+ /wilcoxon=foo with bar (paired)
+ /missing analysis
+ /method=exact.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program 2"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="compare output 2"
+diff pspp.list $TEMPDIR/results.txt
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+
+pass;
diff --git a/tests/command/reliability.sh b/tests/command/reliability.sh
new file mode 100755 (executable)
index 0000000..0bfa733
--- /dev/null
@@ -0,0 +1,345 @@
+#!/bin/sh
+
+# This program tests the reliability command.
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+# ensure that top_srcdir and top_builddir  are absolute
+if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi
+if [ -z "$top_builddir" ] ; then top_builddir=. ; fi
+top_srcdir=`cd $top_srcdir; pwd`
+top_builddir=`cd $top_builddir; pwd`
+
+PSPP=$top_builddir/src/ui/terminal/pspp
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+LANG=C
+export LANG
+
+
+cleanup()
+{
+     if [ x"$PSPP_TEST_NO_CLEANUP" != x ] ; then 
+       echo "NOT cleaning $TEMPDIR"
+       return ; 
+     fi
+     rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+    echo $activity
+    echo FAILED
+    cleanup;
+    exit 1;
+}
+
+
+no_result()
+{
+    echo $activity
+    echo NO RESULT;
+    cleanup;
+    exit 2;
+}
+
+pass()
+{
+    cleanup;
+    exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+
+activity="create program"
+cat > $TESTFILE <<EOF
+
+data list notable list  /var1 *
+       var2  *
+       var6  *
+       var7  *
+       var8  *
+       var9  *
+       var11 *
+       var12 *
+       var15 *
+       var16 *
+       var17 *
+       var19 *
+       .
+
+begin data.
+6 7 7 5 7 7 7 7 7 7 6 6
+6 7 7 6 7 6 7 5 6 5 7 7
+6 6 7 6 5 3 6 4 5 6 4 5
+4 6 5 6 6 5 4 3 5 6 5 6
+5 6 5 5 6 5 4 4 6 6 5 5
+6 6 7 6 6 5 6 5 6 6 5 6
+5 6 6 5 6 5 5 4 6 5 5 5
+5 7 7 7 7 7 6 5 7 7 7 7
+6 6 6 5 5 7 6 5 6 6 5 6
+. . . . . . . . . . . .
+6 6 5 5 5 6 6 4 6 5 5 5
+7 7 7 6 7 6 7 6 6 6 7 6
+4 7 6 6 6 5 5 4 4 5 5 6
+5 6 3 5 4 1 4 6 2 3 3 2
+3 6 6 5 6 2 4 2 2 4 4 5
+6 6 7 5 6 5 7 6 5 6 6 5
+6 5 6 6 5 6 6 6 6 4 5 5
+5 7 7 . 6 6 6 5 6 6 6 6
+5 7 5 5 4 6 7 6 5 4 6 5
+7 7 7 6 7 7 7 6 7 7 7 6
+3 6 5 6 5 7 7 3 4 7 5 7
+6 7 7 6 5 6 5 5 6 6 6 6
+5 5 6 5 5 5 5 4 5 5 5 6
+6 6 7 4 5 6 6 6 6 5 5 6
+6 5 6 6 4 4 5 4 5 6 4 5
+5 6 7 6 6 7 7 5 6 6 6 5
+5 6 5 7 4 6 6 5 7 7 5 6
+. . . . . . . . . . . .
+7 6 6 5 6 6 7 6 6 5 5 6
+6 6 7 7 7 7 7 6 7 6 6 7
+7 5 5 . 5 . 7 3 5 4 5 3
+7 6 7 5 4 5 7 5 7 5 5 6
+6 5 6 6 6 5 5 5 5 6 5 6
+7 7 7 7 7 7 7 7 5 6 7 7
+. . . . . . . . . . . .
+5 5 6 7 5 6 6 4 6 6 6 5
+6 6 5 7 5 6 7 5 6 5 4 6
+7 6 7 6 7 5 6 7 7 6 6 6
+5 6 5 6 5 6 7 2 5 7 3 7
+6 6 5 6 5 6 6 6 6 6 5 6
+7 6 7 6 6 6 6 6 6 7 6 7
+7 7 6 5 6 6 7 7 7 4 6 5
+3 7 7 6 6 7 7 7 6 6 6 4
+3 5 3 4 3 3 3 3 3 3 3 5
+5 7 7 7 5 7 6 2 6 7 6 7
+7 7 7 7 7 7 7 6 7 7 7 6
+6 5 7 4 4 4 5 6 5 5 4 5
+4 7 7 4 4 3 6 3 5 3 4 5
+7 7 7 7 7 7 7 7 7 7 7 5
+3 6 5 5 4 5 4 4 5 5 3 5
+6 7 6 6 6 7 7 6 6 6 7 6
+2 5 4 6 3 2 2 2 2 7 2 2
+4 6 6 5 5 5 6 5 5 6 6 5
+5 7 4 5 6 6 6 5 6 6 5 6
+5 7 7 5 6 5 6 5 5 4 5 4
+4 5 6 5 6 4 5 5 5 4 5 5
+7 6 6 5 5 6 7 5 6 5 7 6
+5 6 6 5 4 5 5 3 4 5 5 5
+5 7 6 4 4 5 6 5 6 4 4 6
+6 6 6 6 5 7 7 6 5 5 6 6
+6 6 7 6 7 6 6 5 6 7 6 5
+7 6 7 6 7 6 7 7 5 5 6 6
+5 6 6 5 5 5 6 5 6 7 7 5
+5 6 6 5 6 5 6 6 6 6 6 6
+5 5 5 5 6 4 5 3 4 7 6 5
+5 7 7 6 6 6 6 5 6 7 6 7
+6 6 7 7 7 5 6 5 5 5 5 4
+2 7 5 4 6 5 5 2 5 6 4 6
+6 7 7 5 6 6 7 6 6 7 5 7
+5 6 7 6 6 3 5 7 6 6 5 6
+6 6 6 3 5 5 5 6 6 6 4 5
+4 7 7 4 7 4 5 5 5 7 4 4
+. . . . . . . . . . . .
+6 6 7 6 7 6 7 7 6 7 7 6
+. . . . . . . . . . . .
+5 6 5 7 6 5 6 6 5 6 4 6
+5 5 5 5 4 5 5 5 7 5 5 5
+6 6 6 4 5 4 6 6 6 4 5 4
+6 5 7 4 6 4 6 5 6 6 6 3
+5 7 6 5 5 5 5 5 6 7 6 6
+5 5 7 7 5 5 6 6 5 5 5 7
+5 6 7 6 7 5 6 4 6 7 6 7
+4 5 5 5 6 5 6 5 6 6 5 6
+6 5 5 5 6 3 4 5 5 4 5 3
+6 6 6 5 5 5 4 3 4 5 5 5
+6 7 7 6 2 3 6 6 6 5 7 7
+6 7 5 5 6 6 6 5 6 6 6 6
+6 7 7 6 7 7 7 5 5 6 6 6
+6 6 6 6 7 6 6 7 6 6 6 6
+5 6 6 6 3 5 6 6 5 5 4 6
+4 6 5 6 6 5 6 5 6 6 5 5
+6 4 6 5 4 6 7 4 5 6 5 5
+6 7 6 4 6 5 7 6 7 7 6 5
+6 7 7 6 7 6 7 7 7 6 6 6
+6 6 6 4 5 6 7 7 5 6 4 4
+3 3 5 3 3 1 5 6 3 2 3 3
+7 7 5 6 6 7 7 6 7 7 7 7
+5 6 6 6 7 5 4 5 4 7 6 7
+3 6 5 4 3 3 3 5 5 6 3 4
+5 7 6 4 6 5 5 6 6 7 5 6
+5 7 6 6 6 6 6 5 6 7 7 6
+7 7 5 6 7 7 7 7 6 5 7 7
+6 7 6 6 5 6 7 7 6 5 6 6
+6 7 7 7 7 6 6 7 6 7 7 7
+4 6 4 7 3 6 5 5 4 3 5 6
+5 5 7 5 4 6 7 5 4 6 6 5
+5 5 6 4 6 5 7 6 5 5 5 6
+. . . . . . . . . . . .
+. . . . . . . . . . . .
+5 7 7 5 6 6 7 7 6 6 6 7
+6 7 7 1 2 1 7 7 5 5 5 2
+. . . . . . . . . . . .
+3 7 4 6 4 7 4 6 4 7 4 7
+5 7 3 5 5 6 7 5 4 7 7 4
+4 7 7 5 4 6 7 7 6 5 4 4
+6 6 2 2 6 4 6 5 5 1 5 2
+5 5 6 4 5 4 6 5 5 6 5 5
+. . . . . . . . . . . .
+5 7 6 6 6 6 6 6 5 6 6 6
+6 6 6 5 6 6 6 6 7 5 6 7
+3 6 3 3 5 3 3 5 3 5 7 4
+4 4 6 3 3 3 4 3 4 2 3 6
+5 7 7 6 5 4 7 5 7 7 3 7
+4 5 4 4 4 4 3 3 3 4 3 3
+6 7 7 5 6 6 7 5 4 5 5 5
+3 5 3 3 1 3 4 3 4 7 6 7
+4 5 4 4 4 3 4 5 6 6 4 5
+5 6 3 4 5 3 5 3 4 5 6 4
+5 5 5 6 6 6 6 4 5 6 6 5
+6 7 7 2 2 6 7 7 7 7 5 7
+5 7 7 4 6 5 7 5 5 5 6 6
+6 6 7 7 5 5 5 7 6 7 7 7
+6 5 7 3 6 5 6 5 5 6 5 4
+5 7 6 5 6 6 6 5 6 5 5 6
+4 5 5 5 6 3 5 3 3 6 5 5
+. . . . . . . . . . . .
+5 6 6 4 4 4 5 3 5 5 2 6
+5 6 7 5 5 6 6 5 5 6 6 6
+6 7 7 6 4 7 7 6 7 5 6 7
+6 6 5 4 5 2 7 6 6 5 6 6
+2 2 2 2 2 2 3 2 3 1 1 2
+end data.
+
+RELIABILITY
+  /VARIABLES=var2 var8 var15 var17 var6
+  /SCALE('Everything') var6 var8 var15 var17
+  /MODEL=ALPHA.
+
+RELIABILITY
+  /VARIABLES=var6 var8 var15 var17
+  /SCALE('Nothing') ALL
+  /MODEL=SPLIT(2)
+ .
+
+RELIABILITY
+  /VARIABLES=var2 var6 var8 var15 var17 var19
+  /SCALE('Totals') var6 var8 var15 var17 
+  /SUMMARY = total
+ .
+
+
+RELIABILITY
+  /VARIABLES=var6 var8 var15 var17 
+  .
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run program"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="compare output"
+diff pspp.list - << EOF
+Scale: Everything
+
+1.1 RELIABILITY.  Case Processing Summary
+#==============#===#=====#
+#              # N |  %  #
+#==============#===#=====#
+#Cases Valid   #131| 92.9#
+#      Excluded# 10|  7.1#
+#      Total   #141|100.0#
+#==============#===#=====#
+
+1.2 RELIABILITY.  Reliability Statistics
+#================#==========#
+#Cronbach's Alpha#N of items#
+#================#==========#
+#            .748#         4#
+#================#==========#
+
+Scale: Nothing
+
+2.1 RELIABILITY.  Case Processing Summary
+#==============#===#=====#
+#              # N |  %  #
+#==============#===#=====#
+#Cases Valid   #131| 92.9#
+#      Excluded# 10|  7.1#
+#      Total   #141|100.0#
+#==============#===#=====#
+
+2.2 RELIABILITY.  Reliability Statistics
+#==========================================================#====#
+#Cronbach's Alpha               Part 1           Value     #.550#
+#                                                N of Items#   2#
+#                               Part 2           Value     #.631#
+#                                                N of Items#   2#
+#                               Total N of Items           #   4#
+#Correlation Between Forms                                 #.606#
+#Spearman-Brown Coefficient     Equal Length               #.755#
+#                               Unequal Length             #.755#
+#Guttman Split-Half Coefficient                            #.754#
+#==========================================================#====#
+
+Scale: Totals
+
+3.1 RELIABILITY.  Case Processing Summary
+#==============#===#=====#
+#              # N |  %  #
+#==============#===#=====#
+#Cases Valid   #131| 92.9#
+#      Excluded# 10|  7.1#
+#      Total   #141|100.0#
+#==============#===#=====#
+
+3.2 RELIABILITY.  Reliability Statistics
+#================#==========#
+#Cronbach's Alpha#N of items#
+#================#==========#
+#            .748#         4#
+#================#==========#
+
+3.3 RELIABILITY.  Item-Total Statistics
+#=====#==========================#==============================#================================#================================#
+#     #Scale Mean if Item Deleted|Scale Variance if Item Deleted|Corrected Item-Total Correlation|Cronbach's Alpha if Item Deleted#
+#=====#==========================#==============================#================================#================================#
+#var6 #                    15.969|                         8.430|                            .513|                            .705#
+#var8 #                    16.565|                         7.863|                            .530|                            .698#
+#var15#                    16.473|                         8.451|                            .558|                            .682#
+#var17#                    16.603|                         7.995|                            .570|                            .673#
+#=====#==========================#==============================#================================#================================#
+
+Scale: ANY
+
+4.1 RELIABILITY.  Case Processing Summary
+#==============#===#=====#
+#              # N |  %  #
+#==============#===#=====#
+#Cases Valid   #131| 92.9#
+#      Excluded# 10|  7.1#
+#      Total   #141|100.0#
+#==============#===#=====#
+
+4.2 RELIABILITY.  Reliability Statistics
+#================#==========#
+#Cronbach's Alpha#N of items#
+#================#==========#
+#            .748#         4#
+#================#==========#
+
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass;
index 532684237745e5eef82aafa0eefa8f977f160e4a..25d01158ee77b1c80062f8c6689f7a5f0fb608fa 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
 
    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
@@ -62,12 +62,18 @@ static void read_long_var_name_map (struct sfm_reader *r,
                                     size_t size, size_t count);
 static void read_long_string_map (struct sfm_reader *r,
                                   size_t size, size_t count);
+static void read_datafile_attributes (struct sfm_reader *r,
+                                      size_t size, size_t count);
+static void read_variable_attributes (struct sfm_reader *r,
+                                      size_t size, size_t count);
 
-static struct variable_to_value_map *open_variable_to_value_map (
+static struct text_record *open_text_record (
   struct sfm_reader *, size_t size);
-static void close_variable_to_value_map (struct variable_to_value_map *);
-static bool read_variable_to_value_map (struct variable_to_value_map *,
-                                        char **key, char **value);
+static void close_text_record (struct text_record *);
+static bool read_variable_to_value_pair (struct text_record *,
+                                         char **key, char **value);
+static char *text_tokenize (struct text_record *, int delimiter);
+static bool text_match (struct text_record *text, int c);
 
 static void usage (int exit_code);
 static void sys_warn (struct sfm_reader *, const char *, ...)
@@ -87,50 +93,61 @@ int
 main (int argc, char *argv[])
 {
   struct sfm_reader r;
-  int rec_type;
+  int i;
 
   set_program_name (argv[0]);
-  if (argc != 2)
+  if (argc < 2)
     usage (EXIT_FAILURE);
 
-  r.file_name = argv[1];
-  r.file = fopen (r.file_name, "rb");
-  if (r.file == NULL)
-    error (EXIT_FAILURE, errno, "error opening \"%s\"", r.file_name);
-  r.n_variable_records = 0;
-  r.n_variables = 0;
-
-  read_header (&r);
-  while ((rec_type = read_int (&r)) != 999)
+  for (i = 1; i < argc; i++) 
     {
-      switch (rec_type)
+      int rec_type;
+
+      r.file_name = argv[i];
+      r.file = fopen (r.file_name, "rb");
+      if (r.file == NULL)
+        error (EXIT_FAILURE, errno, "error opening \"%s\"", r.file_name);
+      r.n_variable_records = 0;
+      r.n_variables = 0;
+
+      if (argc > 2)
+        printf ("Reading \"%s\":\n", r.file_name);
+      
+      read_header (&r);
+      while ((rec_type = read_int (&r)) != 999)
         {
-        case 2:
-          read_variable_record (&r);
-          break;
+          switch (rec_type)
+            {
+            case 2:
+              read_variable_record (&r);
+              break;
 
-        case 3:
-          read_value_label_record (&r);
-          break;
+            case 3:
+              read_value_label_record (&r);
+              break;
 
-        case 4:
-          sys_error (&r, _("Misplaced type 4 record."));
+            case 4:
+              sys_error (&r, _("Misplaced type 4 record."));
 
-        case 6:
-          read_document_record (&r);
-          break;
+            case 6:
+              read_document_record (&r);
+              break;
 
-        case 7:
-          read_extension_record (&r);
-          break;
+            case 7:
+              read_extension_record (&r);
+              break;
 
-        default:
-          sys_error (&r, _("Unrecognized record type %d."), rec_type);
+            default:
+              sys_error (&r, _("Unrecognized record type %d."), rec_type);
+            }
         }
-    }
-  printf ("%08lx: end-of-dictionary record (first byte of data at %08lx)\n",
-          ftell (r.file), ftell (r.file) + 4);
+      printf ("%08lx: end-of-dictionary record "
+              "(first byte of data at %08lx)\n",
+              ftell (r.file), ftell (r.file) + 4);
 
+      fclose (r.file);
+    }
+  
   return 0;
 }
 
@@ -486,9 +503,12 @@ read_extension_record (struct sfm_reader *r)
       break;
 
     case 17:
-      /* Text field that defines variable attributes.  New in
-         SPSS 14. */
-      break;
+      read_datafile_attributes (r, size, count);
+      return;
+
+    case 18:
+      read_variable_attributes (r, size, count);
+      return;
 
     default:
       sys_warn (r, _("Unrecognized record type 7, subtype %d."), subtype);
@@ -613,15 +633,15 @@ read_display_parameters (struct sfm_reader *r, size_t size, size_t count)
 static void
 read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count)
 {
-  struct variable_to_value_map *map;
+  struct text_record *text;
   char *var;
   char *long_name;
 
   printf ("%08lx: long variable names (short => long)\n", ftell (r->file));
-  map = open_variable_to_value_map (r, size * count);
-  while (read_variable_to_value_map (map, &var, &long_name))
+  text = open_text_record (r, size * count);
+  while (read_variable_to_value_pair (text, &var, &long_name))
     printf ("\t%s => %s\n", var, long_name);
-  close_variable_to_value_map (map);
+  close_text_record (text);
 }
 
 /* Reads record type 7, subtype 14, which gives the real length
@@ -629,89 +649,170 @@ read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count)
 static void
 read_long_string_map (struct sfm_reader *r, size_t size, size_t count)
 {
-  struct variable_to_value_map *map;
+  struct text_record *text;
   char *var;
   char *length_s;
 
   printf ("%08lx: very long strings (variable => length)\n", ftell (r->file));
-  map = open_variable_to_value_map (r, size * count);
-  while (read_variable_to_value_map (map, &var, &length_s))
+  text = open_text_record (r, size * count);
+  while (read_variable_to_value_pair (text, &var, &length_s))
     printf ("\t%s => %d\n", var, atoi (length_s));
-  close_variable_to_value_map (map);
+  close_text_record (text);
+}
+
+static bool
+read_attributes (struct sfm_reader *r, struct text_record *text,
+                 const char *variable)
+{
+  const char *key;
+  int index;
+
+  for (;;) 
+    {
+      key = text_tokenize (text, '(');
+      if (key == NULL)
+        return true;
+  
+      for (index = 1; ; index++)
+        {
+          /* Parse the value. */
+          const char *value = text_tokenize (text, '\n');
+          if (value == NULL) 
+            {
+              sys_warn (r, _("%s: Error parsing attribute value %s[%d]"),
+                        variable, key, index);
+              return false;
+            }
+          if (strlen (value) < 2
+              || value[0] != '\'' || value[strlen (value) - 1] != '\'')
+            sys_warn (r, _("%s: Attribute value %s[%d] is not quoted: %s"),
+                      variable, key, index, value);
+          else
+            printf ("\t%s: %s[%d] = \"%.*s\"\n",
+                    variable, key, index, (int) strlen (value) - 2, value + 1);
+
+          /* Was this the last value for this attribute? */
+          if (text_match (text, ')'))
+            break;
+        }
+
+      if (text_match (text, '/'))
+        return true; 
+    }
+}
+
+static void
+read_datafile_attributes (struct sfm_reader *r, size_t size, size_t count) 
+{
+  struct text_record *text;
+  
+  printf ("%08lx: datafile attributes\n", ftell (r->file));
+  text = open_text_record (r, size * count);
+  read_attributes (r, text, "datafile");
+  close_text_record (text);
+}
+
+static void
+read_variable_attributes (struct sfm_reader *r, size_t size, size_t count) 
+{
+  struct text_record *text;
+  
+  printf ("%08lx: variable attributes\n", ftell (r->file));
+  text = open_text_record (r, size * count);
+  for (;;) 
+    {
+      const char *variable = text_tokenize (text, ':');
+      if (variable == NULL || !read_attributes (r, text, variable))
+        break; 
+    }
+  close_text_record (text);
 }
 \f
-/* Helpers for reading records that contain "variable=value"
-   pairs. */
+/* Helpers for reading records that consist of structured text
+   strings. */
 
 /* State. */
-struct variable_to_value_map
+struct text_record
   {
     char *buffer;               /* Record contents. */
     size_t size;                /* Size of buffer. */
     size_t pos;                 /* Current position in buffer. */
   };
 
-/* Reads SIZE bytes into a "variable=value" map for R,
-   and returns the map. */
-static struct variable_to_value_map *
-open_variable_to_value_map (struct sfm_reader *r, size_t size)
+/* Reads SIZE bytes into a text record for R,
+   and returns the new text record. */
+static struct text_record *
+open_text_record (struct sfm_reader *r, size_t size)
 {
-  struct variable_to_value_map *map = xmalloc (sizeof *map);
+  struct text_record *text = xmalloc (sizeof *text);
   char *buffer = xmalloc (size + 1);
   read_bytes (r, buffer, size);
-  map->buffer = buffer;
-  map->size = size;
-  map->pos = 0;
-  return map;
+  text->buffer = buffer;
+  text->size = size;
+  text->pos = 0;
+  return text;
 }
 
-/* Closes MAP and frees its storage.
-   Not really needed, because the pool will free the map anyway,
+/* Closes TEXT and frees its storage.
+   Not really needed, because the pool will free the text record anyway,
    but can be used to free it earlier. */
 static void
-close_variable_to_value_map (struct variable_to_value_map *map)
+close_text_record (struct text_record *text)
 {
-  free (map);
-  free (map->buffer);
+  free (text->buffer);
+  free (text);
 }
 
 static char *
-tokenize (struct variable_to_value_map *map, int delimiter)
+text_tokenize (struct text_record *text, int delimiter)
 {
-  size_t start = map->pos;
-  while (map->pos < map->size
-         && map->buffer[map->pos] != delimiter
-         && map->buffer[map->pos] != '\0')
-    map->pos++;
-  if (map->pos == map->size)
+  size_t start = text->pos;
+  while (text->pos < text->size
+         && text->buffer[text->pos] != delimiter
+         && text->buffer[text->pos] != '\0')
+    text->pos++;
+  if (text->pos == text->size)
     return NULL;
-  map->buffer[map->pos++] = '\0';
-  return &map->buffer[start];
+  text->buffer[text->pos++] = '\0';
+  return &text->buffer[start];
+}
+
+static bool
+text_match (struct text_record *text, int c) 
+{
+  if (text->pos < text->size && text->buffer[text->pos] == c) 
+    {
+      text->pos++;
+      return true;
+    }
+  else
+    return false;
 }
 
-/* Reads the next variable=value pair from MAP.
+/* Reads a variable=value pair from TEXT.
    Looks up the variable in DICT and stores it into *VAR.
    Stores a null-terminated value into *VALUE. */
 static bool
-read_variable_to_value_map (struct variable_to_value_map *map,
-                            char **key, char **value)
+read_variable_to_value_pair (struct text_record *text,
+                             char **key, char **value)
 {
-  *key = tokenize (map, '=');
-  *value = tokenize (map, '\t');
+  *key = text_tokenize (text, '=');
+  *value = text_tokenize (text, '\t');
   if (!*key || !*value)
     return false;
 
-  while (map->pos < map->size
-         && (map->buffer[map->pos] == '\t'
-             || map->buffer[map->pos] == '\0'))
-    map->pos++;
+  while (text->pos < text->size
+         && (text->buffer[text->pos] == '\t'
+             || text->buffer[text->pos] == '\0'))
+    text->pos++;
   return true;
 }
 \f
 static void
 usage (int exit_code)
 {
-  printf ("usage: %s SYSFILE, where SYSFILE is the name of a system file\n",
+  printf ("usage: %s SYSFILE...\n"
+          "where each SYSFILE is the name of a system file\n",
           program_name);
   exit (exit_code);
 }
index 1c29a7a523f2a4ee42e4b3f5dc2f030d19f83c63..cb0f5ba3a04161a27ca712c4b43df36c7e83e2a8 100755 (executable)
@@ -60,6 +60,7 @@ cat > $TEMPDIR/valuelabel.stat <<EOF
 DATA LIST notable /n 1 s 2(a).
 VALUE LABELS /n 0 'Very dissatisfied'
                 1 'Dissatisfied'
+               1.5 'Slightly Peeved'
                 2 'Neutral'
                 3 'Satisfied'
                 4 'Very satisfied'.
@@ -82,6 +83,7 @@ BEGIN DATA.
 5f
 6g
 END DATA.
+
 EOF
 if [ $? -ne 0 ] ; then no_result ; fi
 
diff --git a/tests/libpspp/hmap-test.c b/tests/libpspp/hmap-test.c
new file mode 100644 (file)
index 0000000..e59ea46
--- /dev/null
@@ -0,0 +1,999 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/* This is a test program for the hmap_* routines defined in
+   hmap.c.  This test program aims to be as comprehensive as
+   possible.  "gcov -a -b" should report 100% coverage of lines,
+   blocks and branches in hmap.c (when compiled with -DNDEBUG).
+   "valgrind --leak-check=yes --show-reachable=yes" should give a
+   clean report. */
+
+/* Warning:
+
+   GCC 4.3 will miscompile this test program, specifically
+   test_moved(), given small changes.  This is a bug in GCC
+   triggered by the test program, not by the library under test,
+   so you may safely ignore it.  To avoid miscompilation, compile
+   this file with GCC 4.2 or earlier or GCC 4.4 or later.
+
+   Here is a minimal test program that demonstrates the same or a
+   similar bug in GCC 4.3:
+
+   #include <stdio.h>
+   #include <stdlib.h>
+
+   struct node
+     {
+       struct node *next;
+       unsigned int data1;
+       int data2;
+     };
+   struct list
+     {
+       struct node *head;
+       int dummy;
+     };
+
+   static void *
+   xmalloc (int n)
+   {
+     return malloc (n);
+   }
+
+   static void
+   check_list (struct list *list)
+   {
+     int i __attribute__((unused));
+     struct node *e;
+     for (e = list->head; e != NULL; e = e->next)
+       if (e->data1 != e->data2)
+         abort ();
+   }
+
+   int
+   main (void)
+   {
+   #define MAX_ELEMS 2
+     struct node *elements = xmalloc (MAX_ELEMS * sizeof *elements);
+     int *values = xmalloc (MAX_ELEMS * sizeof *values);
+     struct list list;
+     int i;
+
+     list.head = NULL;
+     for (i = 0; i < MAX_ELEMS; i++)
+       {
+         values[i] = elements[i].data2 = i;
+         elements[i].data1 = elements[i].data2;
+         elements[i].next = list.head;
+         list.head = &elements[i];
+       }
+     check_list (&list);
+     return 0;
+   }
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libpspp/hmap.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libpspp/compiler.h>
+\f
+/* Currently running test. */
+static const char *test_name;
+
+/* Exit with a failure code.
+   (Place a breakpoint on this function while debugging.) */
+static void
+check_die (void)
+{
+  exit (EXIT_FAILURE);
+}
+
+/* If OK is not true, prints a message about failure on the
+   current source file and the given LINE and terminates. */
+static void
+check_func (bool ok, int line)
+{
+  if (!ok)
+    {
+      printf ("Check failed in %s test at %s, line %d\n",
+              test_name, __FILE__, line);
+      check_die ();
+    }
+}
+
+/* Verifies that EXPR evaluates to true.
+   If not, prints a message citing the calling line number and
+   terminates. */
+#define check(EXPR) check_func ((EXPR), __LINE__)
+
+/* Prints a message about memory exhaustion and exits with a
+   failure code. */
+static void
+xalloc_die (void)
+{
+  printf ("virtual memory exhausted\n");
+  exit (EXIT_FAILURE);
+}
+
+static void *xmalloc (size_t n) MALLOC_LIKE;
+static void *xnmalloc (size_t n, size_t m) MALLOC_LIKE;
+static void *xmemdup (const void *p, size_t n) MALLOC_LIKE;
+
+/* Allocates and returns N bytes of memory. */
+static void *
+xmalloc (size_t n)
+{
+  if (n != 0)
+    {
+      void *p = malloc (n);
+      if (p == NULL)
+        xalloc_die ();
+
+      return p;
+    }
+  else
+    return NULL;
+}
+
+static void *
+xmemdup (const void *p, size_t n)
+{
+  void *q = xmalloc (n);
+  memcpy (q, p, n);
+  return q;
+}
+
+/* Allocates and returns N * M bytes of memory. */
+static void *
+xnmalloc (size_t n, size_t m)
+{
+  if ((size_t) -1 / m <= n)
+    xalloc_die ();
+  return xmalloc (n * m);
+}
+\f
+/* Node type and support routines. */
+
+/* Test data element. */
+struct element
+  {
+    struct hmap_node node;    /* Embedded hash table element. */
+    int data;                 /* Primary value. */
+  };
+
+/* Returns the `struct element' that NODE is embedded within. */
+static struct element *
+hmap_node_to_element (const struct hmap_node *node)
+{
+  return HMAP_DATA (node, struct element, node);
+}
+
+/* Compares A and B and returns a strcmp-type return value. */
+static int
+compare_ints (const void *a_, const void *b_)
+{
+  const int *a = a_;
+  const int *b = b_;
+
+  return *a < *b ? -1 : *a > *b;
+}
+
+/* Swaps *A and *B. */
+static void
+swap (int *a, int *b)
+{
+  int t = *a;
+  *a = *b;
+  *b = t;
+}
+
+/* Reverses the order of the CNT integers starting at VALUES. */
+static void
+reverse (int *values, size_t cnt)
+{
+  size_t i = 0;
+  size_t j = cnt;
+
+  while (j > i)
+    swap (&values[i++], &values[--j]);
+}
+
+/* Arranges the CNT elements in VALUES into the lexicographically
+   next greater permutation.  Returns true if successful.
+   If VALUES is already the lexicographically greatest
+   permutation of its elements (i.e. ordered from greatest to
+   smallest), arranges them into the lexicographically least
+   permutation (i.e. ordered from smallest to largest) and
+   returns false. */
+static bool
+next_permutation (int *values, size_t cnt)
+{
+  if (cnt > 0)
+    {
+      size_t i = cnt - 1;
+      while (i != 0)
+        {
+          i--;
+          if (values[i] < values[i + 1])
+            {
+              size_t j;
+              for (j = cnt - 1; values[i] >= values[j]; j--)
+                continue;
+              swap (values + i, values + j);
+              reverse (values + (i + 1), cnt - (i + 1));
+              return true;
+            }
+        }
+
+      reverse (values, cnt);
+    }
+
+  return false;
+}
+
+/* Returns N!. */
+static unsigned int
+factorial (unsigned int n)
+{
+  unsigned int value = 1;
+  while (n > 1)
+    value *= n--;
+  return value;
+}
+
+/* Randomly shuffles the CNT elements in ARRAY, each of which is
+   SIZE bytes in size. */
+static void
+random_shuffle (void *array_, size_t cnt, size_t size)
+{
+  char *array = array_;
+  char *tmp = xmalloc (size);
+  size_t i;
+
+  for (i = 0; i < cnt; i++)
+    {
+      size_t j = rand () % (cnt - i) + i;
+      if (i != j)
+        {
+          memcpy (tmp, array + j * size, size);
+          memcpy (array + j * size, array + i * size, size);
+          memcpy (array + i * size, tmp, size);
+        }
+    }
+
+  free (tmp);
+}
+
+typedef size_t hash_function (int data);
+
+static size_t
+identity_hash (int data) 
+{
+  return data;
+}
+
+static size_t
+constant_hash (int data UNUSED) 
+{
+  return 0x12345678u;
+}
+
+static inline uint32_t
+md4_round (uint32_t a, uint32_t b, uint32_t c, uint32_t d,
+           uint32_t data, uint32_t n)
+{
+  uint32_t x = a + (d ^ (b & (c ^ d))) + data;
+  return (x << n) | (x >> (32 - n));
+}
+
+static size_t
+random_hash (int data)
+{
+  uint32_t a = data;
+  uint32_t b = data;
+  uint32_t c = data;
+  uint32_t d = data;
+  a = md4_round (a, b, c, d, 0, 3);
+  d = md4_round (d, a, b, c, 1, 7);
+  c = md4_round (c, d, a, b, 2, 11);
+  b = md4_round (b, c, d, a, 3, 19);
+  return a ^ b ^ c ^ d;
+}
+
+static struct hmap_node *
+find_element (struct hmap *hmap, int data, hash_function *hash)
+{
+  struct element *e;
+  HMAP_FOR_EACH_WITH_HASH (e, struct element, node, hash (data), hmap)
+    if (e->data == data)
+      break;
+  return &e->node;
+}
+
+/* Checks that HMAP contains the CNT ints in DATA, that its
+   structure is correct, and that certain operations on HMAP
+   produce the expected results. */
+static void
+check_hmap (struct hmap *hmap, const int data[], size_t cnt,
+            hash_function *hash)
+{
+  size_t i, j;
+  int *order;
+
+  check (hmap_count (hmap) == cnt);
+  check (cnt <= hmap_capacity (hmap));
+
+  order = xmemdup (data, cnt * sizeof *data);
+  qsort (order, cnt, sizeof *order, compare_ints);
+
+  for (i = 0; i < cnt; i = j)
+    {
+      struct element *e;
+      int count;
+
+      for (j = i + 1; j < cnt; j++)
+        if (order[i] != order[j])
+          break;
+
+      count = 0;
+      HMAP_FOR_EACH_WITH_HASH (e, struct element, node, hash (order[i]), hmap)
+        if (e->data == order[i]) 
+          count++;
+
+      check (count == j - i);
+    }
+
+  check (find_element (hmap, -1, hash) == NULL);
+
+  if (cnt == 0)
+    check (hmap_first (hmap) == NULL);
+  else
+    {
+      struct hmap_node *p;
+      int left;
+
+      left = cnt;
+      for (p = hmap_first (hmap), i = 0; i < cnt; p = hmap_next (hmap, p), i++)
+        {
+          struct element *e = hmap_node_to_element (p);
+          size_t j;
+
+          check (hmap_node_hash (&e->node) == hash (e->data));
+          for (j = 0; j < left; j++)
+            if (order[j] == e->data) 
+              {
+                order[j] = order[--left];
+                goto next;
+              }
+          check_die ();
+
+        next: ;
+        }
+      check (p == NULL);
+    }
+
+  free (order);
+}
+
+/* Inserts the CNT values from 0 to CNT - 1 (inclusive) into an
+   HMAP in the order specified by INSERTIONS, then deletes them in
+   the order specified by DELETIONS, checking the HMAP's contents
+   for correctness after each operation.  Uses HASH as the hash
+   function. */
+static void
+test_insert_delete (const int insertions[],
+                    const int deletions[],
+                    size_t cnt,
+                    hash_function *hash)
+{
+  struct element *elements;
+  struct hmap hmap;
+  size_t i;
+
+  elements = xnmalloc (cnt, sizeof *elements);
+  for (i = 0; i < cnt; i++)
+    elements[i].data = i;
+
+  hmap_init (&hmap);
+  hmap_reserve (&hmap, 1);
+  check_hmap (&hmap, NULL, 0, hash);
+  for (i = 0; i < cnt; i++)
+    {
+      size_t capacity;
+      hmap_insert (&hmap, &elements[insertions[i]].node, hash (insertions[i]));
+      check_hmap (&hmap, insertions, i + 1, hash);
+
+      /* A series of insertions should not produce a shrinkable hmap. */
+      capacity = hmap_capacity (&hmap);
+      hmap_shrink (&hmap);
+      check (capacity == hmap_capacity (&hmap));
+    }
+  for (i = 0; i < cnt; i++)
+    {
+      hmap_delete (&hmap, &elements[deletions[i]].node);
+      check_hmap (&hmap, deletions + i + 1, cnt - i - 1, hash);
+    }
+  hmap_destroy (&hmap);
+
+  free (elements);
+}
+\f
+/* Inserts values into an HMAP in each possible order, then
+   removes them in each possible order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_any (hash_function *hash)
+{
+  const int max_elems = 5;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *insertions, *deletions;
+      unsigned int ins_perm_cnt;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+
+      for (ins_perm_cnt = 0;
+           ins_perm_cnt == 0 || next_permutation (insertions, cnt);
+           ins_perm_cnt++)
+        {
+          unsigned int del_perm_cnt;
+          int i;
+
+          for (i = 0; i < cnt; i++)
+            deletions[i] = i;
+
+          for (del_perm_cnt = 0;
+               del_perm_cnt == 0 || next_permutation (deletions, cnt);
+               del_perm_cnt++)
+            test_insert_delete (insertions, deletions, cnt, hash);
+
+          check (del_perm_cnt == factorial (cnt));
+        }
+      check (ins_perm_cnt == factorial (cnt));
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_insert_any_remove_any_random_hash (void) 
+{
+  test_insert_any_remove_any (random_hash);
+}
+
+static void
+test_insert_any_remove_any_identity_hash (void) 
+{
+  test_insert_any_remove_any (identity_hash);
+}
+
+static void
+test_insert_any_remove_any_constant_hash (void) 
+{
+  test_insert_any_remove_any (constant_hash);
+}
+
+/* Inserts values into an HMAP in each possible order, then
+   removes them in the same order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_same (hash_function *hash)
+{
+  const int max_elems = 7;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *values;
+      unsigned int permutation_cnt;
+      int i;
+
+      values = xnmalloc (cnt, sizeof *values);
+      for (i = 0; i < cnt; i++)
+        values[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (values, cnt);
+           permutation_cnt++)
+        test_insert_delete (values, values, cnt, hash);
+      check (permutation_cnt == factorial (cnt));
+
+      free (values);
+    }
+}
+
+static void
+test_insert_any_remove_same_random_hash (void) 
+{
+  test_insert_any_remove_same (random_hash);
+}
+
+static void
+test_insert_any_remove_same_identity_hash (void) 
+{
+  test_insert_any_remove_same (identity_hash);
+}
+
+static void
+test_insert_any_remove_same_constant_hash (void) 
+{
+  test_insert_any_remove_same (constant_hash);
+}
+
+/* Inserts values into an HMAP in each possible order, then
+   removes them in reverse order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_reverse (hash_function *hash)
+{
+  const int max_elems = 7;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *insertions, *deletions;
+      unsigned int permutation_cnt;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (insertions, cnt);
+           permutation_cnt++)
+        {
+          memcpy (deletions, insertions, sizeof *insertions * cnt);
+          reverse (deletions, cnt);
+
+          test_insert_delete (insertions, deletions, cnt, hash);
+        }
+      check (permutation_cnt == factorial (cnt));
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_insert_any_remove_reverse_random_hash (void)
+{
+  test_insert_any_remove_reverse (random_hash);
+}
+
+static void
+test_insert_any_remove_reverse_identity_hash (void)
+{
+  test_insert_any_remove_reverse (identity_hash);
+}
+
+static void
+test_insert_any_remove_reverse_constant_hash (void)
+{
+  test_insert_any_remove_reverse (constant_hash);
+}
+
+/* Inserts and removes up to MAX_ELEMS values in an hmap, in
+   random order, using hash function HASH. */
+static void
+test_random_sequence (int max_elems, hash_function *hash)
+{
+  const int max_trials = 8;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt += 2)
+    {
+      int *insertions, *deletions;
+      int trial;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+      for (i = 0; i < cnt; i++)
+        deletions[i] = i;
+
+      for (trial = 0; trial < max_trials; trial++)
+        {
+          random_shuffle (insertions, cnt, sizeof *insertions);
+          random_shuffle (deletions, cnt, sizeof *deletions);
+
+          test_insert_delete (insertions, deletions, cnt, hash);
+        }
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_random_sequence_random_hash (void) 
+{
+  test_random_sequence (64, random_hash);
+}
+
+static void
+test_random_sequence_identity_hash (void) 
+{
+  test_random_sequence (64, identity_hash);
+}
+
+static void
+test_random_sequence_constant_hash (void) 
+{
+  test_random_sequence (32, constant_hash);
+}
+
+/* Inserts MAX_ELEMS elements into an HMAP in ascending order,
+   then delete in ascending order and shrink the hmap at each
+   step, using hash function HASH. */
+static void
+test_insert_ordered (int max_elems, hash_function *hash)
+{
+  struct element *elements;
+  int *values;
+  struct hmap hmap;
+  int i;
+
+  hmap_init (&hmap);
+  elements = xnmalloc (max_elems, sizeof *elements);
+  values = xnmalloc (max_elems, sizeof *values);
+  for (i = 0; i < max_elems; i++)
+    {
+      values[i] = elements[i].data = i;
+      hmap_insert (&hmap, &elements[i].node, hash (elements[i].data));
+      check_hmap (&hmap, values, i + 1, hash);
+
+      if (hash == identity_hash) 
+        {
+          /* Check that every every hash bucket has (almost) the
+             same number of nodes in it.  */
+          int min = INT_MAX;
+          int max = INT_MIN;
+          int j;
+
+          for (j = 0; j <= hmap.mask; j++) 
+            {
+              int count = 0;
+              struct hmap_node *node;
+
+              for (node = hmap.buckets[j]; node != NULL; node = node->next)
+                count++;
+              if (count < min)
+                min = count;
+              if (count > max)
+                max = count;
+            }
+          check (max - min <= 1);
+        }
+    }
+  for (i = 0; i < max_elems; i++)
+    {
+      hmap_delete (&hmap, &elements[i].node);
+      hmap_shrink (&hmap);
+      check_hmap (&hmap, values + i + 1, max_elems - i - 1, hash);
+    }
+  hmap_destroy (&hmap);
+  free (elements);
+  free (values);
+}
+
+static void
+test_insert_ordered_random_hash (void)
+{
+  test_insert_ordered (1024, random_hash);
+}
+
+static void
+test_insert_ordered_identity_hash (void)
+{
+  test_insert_ordered (1024, identity_hash);
+}
+
+static void
+test_insert_ordered_constant_hash (void)
+{
+  test_insert_ordered (128, constant_hash);
+}
+
+/* Inserts up to MAX_ELEMS elements into an HMAP, then moves the
+   nodes around in memory, using hash function HASH. */
+static void
+test_moved (int max_elems, hash_function *hash)
+{
+  struct element *e[2];
+  int cur;
+  int *values;
+  struct hmap hmap;
+  int i, j;
+
+  hmap_init (&hmap);
+  e[0] = xnmalloc (max_elems, sizeof *e[0]);
+  e[1] = xnmalloc (max_elems, sizeof *e[1]);
+  values = xnmalloc (max_elems, sizeof *values);
+  cur = 0;
+  for (i = 0; i < max_elems; i++)
+    {
+      values[i] = e[cur][i].data = i;
+      hmap_insert (&hmap, &e[cur][i].node, hash (e[cur][i].data));
+      check_hmap (&hmap, values, i + 1, hash);
+
+      for (j = 0; j <= i; j++)
+        {
+          e[!cur][j] = e[cur][j];
+          hmap_moved (&hmap, &e[!cur][j].node, &e[cur][j].node);
+          check_hmap (&hmap, values, i + 1, hash);
+        }
+      cur = !cur;
+    }
+  hmap_destroy (&hmap);
+  free (e[0]);
+  free (e[1]);
+  free (values);
+}
+
+static void
+test_moved_random_hash (void) 
+{
+  test_moved (128, random_hash);
+}
+
+static void
+test_moved_identity_hash (void) 
+{
+  test_moved (128, identity_hash);
+}
+
+static void
+test_moved_constant_hash (void) 
+{
+  test_moved (32, constant_hash);
+}
+
+/* Inserts values into an HMAP, then changes their values, using
+   hash function HASH. */
+static void
+test_changed (hash_function *hash)
+{
+  const int max_elems = 6;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *values, *changed_values;
+      struct element *elements;
+      unsigned int permutation_cnt;
+      int i;
+
+      values = xnmalloc (cnt, sizeof *values);
+      changed_values = xnmalloc (cnt, sizeof *changed_values);
+      elements = xnmalloc (cnt, sizeof *elements);
+      for (i = 0; i < cnt; i++)
+        values[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (values, cnt);
+           permutation_cnt++)
+        {
+          for (i = 0; i < cnt; i++)
+            {
+              int j, k;
+              for (j = 0; j <= cnt; j++)
+                {
+                  struct hmap hmap;
+
+                  hmap_init (&hmap);
+
+                  /* Add to HMAP in order. */
+                  for (k = 0; k < cnt; k++)
+                    {
+                      int n = values[k];
+                      elements[n].data = n;
+                      hmap_insert (&hmap, &elements[n].node,
+                                   hash (elements[n].data));
+                    }
+                  check_hmap (&hmap, values, cnt, hash);
+
+                  /* Change value i to j. */
+                  elements[i].data = j;
+                  hmap_changed (&hmap, &elements[i].node,
+                                hash (elements[i].data));
+                  for (k = 0; k < cnt; k++)
+                    changed_values[k] = k;
+                  changed_values[i] = j;
+                  check_hmap (&hmap, changed_values, cnt, hash);
+
+                  hmap_destroy (&hmap);
+                }
+            }
+        }
+      check (permutation_cnt == factorial (cnt));
+
+      free (values);
+      free (changed_values);
+      free (elements);
+    }
+}
+
+static void
+test_changed_random_hash (void)
+{
+  test_changed (random_hash);
+}
+
+static void
+test_changed_identity_hash (void)
+{
+  test_changed (identity_hash);
+}
+
+static void
+test_changed_constant_hash (void)
+{
+  test_changed (constant_hash);
+}
+
+static void
+test_swap (int max_elems, hash_function *hash) 
+{
+  struct element *elements;
+  int *values;
+  struct hmap a, b;
+  struct hmap *working, *empty;
+  int i;
+
+  hmap_init (&a);
+  hmap_init (&b);
+  working = &a;
+  empty = &b;
+  elements = xnmalloc (max_elems, sizeof *elements);
+  values = xnmalloc (max_elems, sizeof *values);
+  for (i = 0; i < max_elems; i++)
+    {
+      struct hmap *tmp;
+      values[i] = elements[i].data = i;
+      hmap_insert (working, &elements[i].node, hash (elements[i].data));
+      check_hmap (working, values, i + 1, hash);
+      check_hmap (empty, NULL, 0, hash);
+      hmap_swap (&a, &b);
+      tmp = working;
+      working = empty;
+      empty = tmp;
+    }
+  hmap_destroy (&a);
+  hmap_destroy (&b);
+  free (elements);
+  free (values);
+}
+
+static void
+test_swap_random_hash (void) 
+{
+  test_swap (128, random_hash);
+}
+
+static void
+test_destroy_null (void) 
+{
+  hmap_destroy (NULL);
+}
+
+/* Test shrinking an empty hash table. */
+static void
+test_shrink_empty (void)
+{
+  struct hmap hmap;
+
+  hmap_init (&hmap);
+  hmap_reserve (&hmap, 123);
+  hmap_shrink (&hmap);
+  hmap_destroy (&hmap);
+}
+\f
+/* Main program. */
+
+/* Runs TEST_FUNCTION and prints a message about NAME. */
+static void
+run_test (void (*test_function) (void), const char *name)
+{
+  test_name = name;
+  putchar ('.');
+  fflush (stdout);
+  test_function ();
+}
+
+int
+main (void)
+{
+  run_test (test_insert_any_remove_any_random_hash,
+            "insert any order, delete any order (random hash)");
+  run_test (test_insert_any_remove_any_identity_hash,
+            "insert any order, delete any order (identity hash)");
+  run_test (test_insert_any_remove_any_constant_hash,
+            "insert any order, delete any order (constant hash)");
+
+  run_test (test_insert_any_remove_same_random_hash,
+            "insert any order, delete same order (random hash)");
+  run_test (test_insert_any_remove_same_identity_hash,
+            "insert any order, delete same order (identity hash)");
+  run_test (test_insert_any_remove_same_constant_hash,
+            "insert any order, delete same order (constant hash)");
+
+  run_test (test_insert_any_remove_reverse_random_hash,
+            "insert any order, delete reverse order (random hash)");
+  run_test (test_insert_any_remove_reverse_identity_hash,
+            "insert any order, delete reverse order (identity hash)");
+  run_test (test_insert_any_remove_reverse_constant_hash,
+            "insert any order, delete reverse order (constant hash)");
+
+  run_test (test_random_sequence_random_hash,
+            "insert and delete in random sequence (random hash)");
+  run_test (test_random_sequence_identity_hash,
+            "insert and delete in random sequence (identity hash)");
+  run_test (test_random_sequence_constant_hash,
+            "insert and delete in random sequence (constant hash)");
+
+  run_test (test_insert_ordered_random_hash,
+            "insert in ascending order (random hash)");
+  run_test (test_insert_ordered_identity_hash,
+            "insert in ascending order (identity hash)");
+  run_test (test_insert_ordered_constant_hash,
+            "insert in ascending order (constant hash)");
+
+  run_test (test_moved_random_hash,
+            "move elements around in memory (random hash)");
+  run_test (test_moved_identity_hash,
+            "move elements around in memory (identity hash)");
+  run_test (test_moved_constant_hash,
+            "move elements around in memory (constant hash)");
+
+  run_test (test_changed_random_hash,
+            "change key data in nodes (random hash)");
+  run_test (test_changed_identity_hash,
+            "change key data in nodes (identity hash)");
+  run_test (test_changed_constant_hash,
+            "change key data in nodes (constant hash)");
+
+  run_test (test_swap_random_hash, "test swapping tables");
+
+  run_test (test_destroy_null, "test destroying null table");
+  run_test (test_shrink_empty, "test shrinking an empty table");
+
+  putchar ('\n');
+
+  return 0;
+}
diff --git a/tests/libpspp/hmapx-test.c b/tests/libpspp/hmapx-test.c
new file mode 100644 (file)
index 0000000..fc08ca6
--- /dev/null
@@ -0,0 +1,1034 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+   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 3 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+/* This is a test program for the hmapx_* routines defined in
+   hmapx.c.  This test program aims to be as comprehensive as
+   possible.  "gcov -a -b" should report 100% coverage of lines,
+   blocks and branches in hmapx.c (when compiled with -DNDEBUG).
+   "valgrind --leak-check=yes --show-reachable=yes" should give a
+   clean report. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libpspp/hmapx.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libpspp/compiler.h>
+\f
+/* Currently running test. */
+static const char *test_name;
+
+/* If OK is not true, prints a message about failure on the
+   current source file and the given LINE and terminates. */
+static void
+check_func (bool ok, int line)
+{
+  if (!ok)
+    {
+      printf ("Check failed in %s test at %s, line %d\n",
+              test_name, __FILE__, line);
+      abort ();
+    }
+}
+
+/* Verifies that EXPR evaluates to true.
+   If not, prints a message citing the calling line number and
+   terminates. */
+#define check(EXPR) check_func ((EXPR), __LINE__)
+
+/* Prints a message about memory exhaustion and exits with a
+   failure code. */
+static void
+xalloc_die (void)
+{
+  printf ("virtual memory exhausted\n");
+  exit (EXIT_FAILURE);
+}
+
+/* Allocates and returns N bytes of memory. */
+static void *
+xmalloc (size_t n)
+{
+  if (n != 0)
+    {
+      void *p = malloc (n);
+      if (p == NULL)
+        xalloc_die ();
+
+      return p;
+    }
+  else
+    return NULL;
+}
+
+static void *
+xmemdup (const void *p, size_t n)
+{
+  void *q = xmalloc (n);
+  memcpy (q, p, n);
+  return q;
+}
+
+/* Allocates and returns N * M bytes of memory. */
+static void *
+xnmalloc (size_t n, size_t m)
+{
+  if ((size_t) -1 / m <= n)
+    xalloc_die ();
+  return xmalloc (n * m);
+}
+\f
+/* Node type and support routines. */
+
+/* Test data element. */
+struct element
+  {
+    int data;                 /* Primary value. */
+  };
+
+/* Compares A and B and returns a strcmp-type return value. */
+static int
+compare_ints (const void *a_, const void *b_)
+{
+  const int *a = a_;
+  const int *b = b_;
+
+  return *a < *b ? -1 : *a > *b;
+}
+
+/* Swaps *A and *B. */
+static void
+swap (int *a, int *b)
+{
+  int t = *a;
+  *a = *b;
+  *b = t;
+}
+
+/* Reverses the order of the CNT integers starting at VALUES. */
+static void
+reverse (int *values, size_t cnt)
+{
+  size_t i = 0;
+  size_t j = cnt;
+
+  while (j > i)
+    swap (&values[i++], &values[--j]);
+}
+
+/* Arranges the CNT elements in VALUES into the lexicographically
+   next greater permutation.  Returns true if successful.
+   If VALUES is already the lexicographically greatest
+   permutation of its elements (i.e. ordered from greatest to
+   smallest), arranges them into the lexicographically least
+   permutation (i.e. ordered from smallest to largest) and
+   returns false. */
+static bool
+next_permutation (int *values, size_t cnt)
+{
+  if (cnt > 0)
+    {
+      size_t i = cnt - 1;
+      while (i != 0)
+        {
+          i--;
+          if (values[i] < values[i + 1])
+            {
+              size_t j;
+              for (j = cnt - 1; values[i] >= values[j]; j--)
+                continue;
+              swap (values + i, values + j);
+              reverse (values + (i + 1), cnt - (i + 1));
+              return true;
+            }
+        }
+
+      reverse (values, cnt);
+    }
+
+  return false;
+}
+
+/* Returns N!. */
+static unsigned int
+factorial (unsigned int n)
+{
+  unsigned int value = 1;
+  while (n > 1)
+    value *= n--;
+  return value;
+}
+
+/* Randomly shuffles the CNT elements in ARRAY, each of which is
+   SIZE bytes in size. */
+static void
+random_shuffle (void *array_, size_t cnt, size_t size)
+{
+  char *array = array_;
+  char *tmp = xmalloc (size);
+  size_t i;
+
+  for (i = 0; i < cnt; i++)
+    {
+      size_t j = rand () % (cnt - i) + i;
+      if (i != j)
+        {
+          memcpy (tmp, array + j * size, size);
+          memcpy (array + j * size, array + i * size, size);
+          memcpy (array + i * size, tmp, size);
+        }
+    }
+
+  free (tmp);
+}
+
+typedef size_t hash_function (int data);
+
+static size_t
+identity_hash (int data) 
+{
+  return data;
+}
+
+static size_t
+constant_hash (int data UNUSED) 
+{
+  return 0x12345678u;
+}
+
+static inline uint32_t
+md4_round (uint32_t a, uint32_t b, uint32_t c, uint32_t d,
+           uint32_t data, uint32_t n)
+{
+  uint32_t x = a + (d ^ (b & (c ^ d))) + data;
+  return (x << n) | (x >> (32 - n));
+}
+
+static size_t
+random_hash (int data)
+{
+  uint32_t a = data;
+  uint32_t b = data;
+  uint32_t c = data;
+  uint32_t d = data;
+  a = md4_round (a, b, c, d, 0, 3);
+  d = md4_round (d, a, b, c, 1, 7);
+  c = md4_round (c, d, a, b, 2, 11);
+  b = md4_round (b, c, d, a, 3, 19);
+  return a ^ b ^ c ^ d;
+}
+
+static struct hmapx_node *
+find_element (struct hmapx *hmapx, int data, hash_function *hash)
+{
+  struct hmapx_node *node;
+  struct element *e;
+  HMAPX_FOR_EACH_WITH_HASH (e, node, hash (data), hmapx)
+    if (e->data == data)
+      break;
+  return node;
+}
+
+/* Checks that HMAPX contains the CNT ints in DATA, that its
+   structure is correct, and that certain operations on HMAPX
+   produce the expected results. */
+static void
+check_hmapx (struct hmapx *hmapx, const int data[], size_t cnt,
+            hash_function *hash)
+{
+  size_t i, j;
+  int *order;
+
+  check (hmapx_count (hmapx) == cnt);
+  check (cnt <= hmapx_capacity (hmapx));
+
+  order = xmemdup (data, cnt * sizeof *data);
+  qsort (order, cnt, sizeof *order, compare_ints);
+
+  for (i = 0; i < cnt; i = j)
+    {
+      struct hmapx_node *node;
+      struct element *e;
+      int count;
+
+      for (j = i + 1; j < cnt; j++)
+        if (order[i] != order[j])
+          break;
+
+      count = 0;
+      HMAPX_FOR_EACH_WITH_HASH (e, node, hash (order[i]), hmapx)
+        if (e->data == order[i]) 
+          count++; 
+
+      check (count == j - i);
+    }
+
+  check (find_element (hmapx, -1, hash) == NULL);
+
+  if (cnt == 0)
+    check (hmapx_first (hmapx) == NULL);
+  else
+    {
+      struct hmapx_node *p;
+      int left;
+
+      left = cnt;
+      for (p = hmapx_first (hmapx), i = 0; i < cnt;
+           p = hmapx_next (hmapx, p), i++)
+        {
+          struct element *e = hmapx_node_data (p);
+          size_t j;
+
+          check (hmapx_node_hash (p) == hash (e->data));
+          for (j = 0; j < left; j++)
+            if (order[j] == e->data) 
+              {
+                order[j] = order[--left];
+                goto next;
+              }
+          abort ();
+
+        next: ;
+        }
+      check (p == NULL);
+    }
+
+  free (order);
+}
+
+/* Inserts the CNT values from 0 to CNT - 1 (inclusive) into an
+   HMAPX in the order specified by INSERTIONS, then deletes them in
+   the order specified by DELETIONS, checking the HMAPX's contents
+   for correctness after each operation.  Uses HASH as the hash
+   function. */
+static void
+test_insert_delete (const int insertions[],
+                    const int deletions[],
+                    size_t cnt,
+                    hash_function *hash,
+                    size_t reserve)
+{
+  struct element *elements;
+  struct hmapx_node **nodes;
+  struct hmapx hmapx;
+  size_t i;
+
+  elements = xnmalloc (cnt, sizeof *elements);
+  nodes = xnmalloc (cnt, sizeof *nodes);
+  for (i = 0; i < cnt; i++)
+    elements[i].data = i;
+
+  hmapx_init (&hmapx);
+  hmapx_reserve (&hmapx, reserve);
+  check_hmapx (&hmapx, NULL, 0, hash);
+  for (i = 0; i < cnt; i++)
+    {
+      struct hmapx_node *(*insert) (struct hmapx *, void *, size_t hash);
+      size_t capacity;
+
+      /* Insert the node.  Use hmapx_insert_fast if we have not
+         yet exceeded the reserve. */
+      insert = i < reserve ? hmapx_insert_fast : hmapx_insert;
+      nodes[insertions[i]] = insert (&hmapx, &elements[insertions[i]],
+                                     hash (insertions[i]));
+      check_hmapx (&hmapx, insertions, i + 1, hash);
+
+      /* A series of insertions should not produce a shrinkable hmapx. */
+      if (i >= reserve) 
+        {
+          capacity = hmapx_capacity (&hmapx);
+          hmapx_shrink (&hmapx);
+          check (capacity == hmapx_capacity (&hmapx)); 
+        }
+    }
+  for (i = 0; i < cnt; i++)
+    {
+      hmapx_delete (&hmapx, nodes[deletions[i]]);
+      check_hmapx (&hmapx, deletions + i + 1, cnt - i - 1, hash);
+    }
+  hmapx_destroy (&hmapx);
+
+  free (elements);
+  free (nodes);
+}
+\f
+/* Inserts values into an HMAPX in each possible order, then
+   removes them in each possible order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_any (hash_function *hash)
+{
+  const int max_elems = 5;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *insertions, *deletions;
+      unsigned int ins_perm_cnt;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+
+      for (ins_perm_cnt = 0;
+           ins_perm_cnt == 0 || next_permutation (insertions, cnt);
+           ins_perm_cnt++)
+        {
+          unsigned int del_perm_cnt;
+          int i;
+
+          for (i = 0; i < cnt; i++)
+            deletions[i] = i;
+
+          for (del_perm_cnt = 0;
+               del_perm_cnt == 0 || next_permutation (deletions, cnt);
+               del_perm_cnt++)
+            test_insert_delete (insertions, deletions, cnt, hash, 1);
+
+          check (del_perm_cnt == factorial (cnt));
+        }
+      check (ins_perm_cnt == factorial (cnt));
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_insert_any_remove_any_random_hash (void) 
+{
+  test_insert_any_remove_any (random_hash);
+}
+
+static void
+test_insert_any_remove_any_identity_hash (void) 
+{
+  test_insert_any_remove_any (identity_hash);
+}
+
+static void
+test_insert_any_remove_any_constant_hash (void) 
+{
+  test_insert_any_remove_any (constant_hash);
+}
+
+/* Inserts values into an HMAPX in each possible order, then
+   removes them in the same order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_same (hash_function *hash)
+{
+  const int max_elems = 7;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *values;
+      unsigned int permutation_cnt;
+      int i;
+
+      values = xnmalloc (cnt, sizeof *values);
+      for (i = 0; i < cnt; i++)
+        values[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (values, cnt);
+           permutation_cnt++)
+        test_insert_delete (values, values, cnt, hash, cnt / 2);
+      check (permutation_cnt == factorial (cnt));
+
+      free (values);
+    }
+}
+
+static void
+test_insert_any_remove_same_random_hash (void) 
+{
+  test_insert_any_remove_same (random_hash);
+}
+
+static void
+test_insert_any_remove_same_identity_hash (void) 
+{
+  test_insert_any_remove_same (identity_hash);
+}
+
+static void
+test_insert_any_remove_same_constant_hash (void) 
+{
+  test_insert_any_remove_same (constant_hash);
+}
+
+/* Inserts values into an HMAPX in each possible order, then
+   removes them in reverse order, up to a specified maximum
+   size, using hash function HASH. */
+static void
+test_insert_any_remove_reverse (hash_function *hash)
+{
+  const int max_elems = 7;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *insertions, *deletions;
+      unsigned int permutation_cnt;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (insertions, cnt);
+           permutation_cnt++)
+        {
+          memcpy (deletions, insertions, sizeof *insertions * cnt);
+          reverse (deletions, cnt);
+
+          test_insert_delete (insertions, deletions, cnt, hash, cnt);
+        }
+      check (permutation_cnt == factorial (cnt));
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_insert_any_remove_reverse_random_hash (void)
+{
+  test_insert_any_remove_reverse (random_hash);
+}
+
+static void
+test_insert_any_remove_reverse_identity_hash (void)
+{
+  test_insert_any_remove_reverse (identity_hash);
+}
+
+static void
+test_insert_any_remove_reverse_constant_hash (void)
+{
+  test_insert_any_remove_reverse (constant_hash);
+}
+
+/* Inserts and removes up to MAX_ELEMS values in an hmapx, in
+   random order, using hash function HASH. */
+static void
+test_random_sequence (int max_elems, hash_function *hash)
+{
+  const int max_trials = 8;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt += 2)
+    {
+      int *insertions, *deletions;
+      int trial;
+      int i;
+
+      insertions = xnmalloc (cnt, sizeof *insertions);
+      deletions = xnmalloc (cnt, sizeof *deletions);
+      for (i = 0; i < cnt; i++)
+        insertions[i] = i;
+      for (i = 0; i < cnt; i++)
+        deletions[i] = i;
+
+      for (trial = 0; trial < max_trials; trial++)
+        {
+          random_shuffle (insertions, cnt, sizeof *insertions);
+          random_shuffle (deletions, cnt, sizeof *deletions);
+
+          test_insert_delete (insertions, deletions, cnt, hash, 0);
+        }
+
+      free (insertions);
+      free (deletions);
+    }
+}
+
+static void
+test_random_sequence_random_hash (void) 
+{
+  test_random_sequence (64, random_hash);
+}
+
+static void
+test_random_sequence_identity_hash (void) 
+{
+  test_random_sequence (64, identity_hash);
+}
+
+static void
+test_random_sequence_constant_hash (void) 
+{
+  test_random_sequence (32, constant_hash);
+}
+
+/* Inserts MAX_ELEMS elements into an HMAPX in ascending order,
+   then delete in ascending order and shrink the hmapx at each
+   step, using hash function HASH. */
+static void
+test_insert_ordered (int max_elems, hash_function *hash)
+{
+  struct element *elements;
+  struct hmapx_node **nodes;
+  int *values;
+  struct hmapx hmapx;
+  int i;
+
+  hmapx_init (&hmapx);
+  elements = xnmalloc (max_elems, sizeof *elements);
+  nodes = xnmalloc (max_elems, sizeof *nodes);
+  values = xnmalloc (max_elems, sizeof *values);
+  for (i = 0; i < max_elems; i++)
+    {
+      values[i] = elements[i].data = i;
+      nodes[i] = hmapx_insert (&hmapx, &elements[i], hash (elements[i].data));
+      check_hmapx (&hmapx, values, i + 1, hash);
+
+      if (hash == identity_hash) 
+        {
+          /* Check that every every hash bucket has (almost) the
+             same number of nodes in it.  */
+          int min = INT_MAX;
+          int max = INT_MIN;
+          int j;
+
+          for (j = 0; j <= hmapx.hmap.mask; j++) 
+            {
+              int count = 0;
+              struct hmap_node *node;
+
+              for (node = hmapx.hmap.buckets[j]; node != NULL;
+                   node = node->next)
+                count++;
+              if (count < min)
+                min = count;
+              if (count > max)
+                max = count;
+            }
+          check (max - min <= 1);
+        }
+    }
+  for (i = 0; i < max_elems; i++)
+    {
+      hmapx_delete (&hmapx, nodes[i]);
+      hmapx_shrink (&hmapx);
+      check_hmapx (&hmapx, values + i + 1, max_elems - i - 1, hash);
+    }
+  hmapx_destroy (&hmapx);
+  free (elements);
+  free (nodes);
+  free (values);
+}
+
+static void
+test_insert_ordered_random_hash (void)
+{
+  test_insert_ordered (1024, random_hash);
+}
+
+static void
+test_insert_ordered_identity_hash (void)
+{
+  test_insert_ordered (1024, identity_hash);
+}
+
+static void
+test_insert_ordered_constant_hash (void)
+{
+  test_insert_ordered (128, constant_hash);
+}
+
+/* Inserts up to MAX_ELEMS elements into an HMAPX, then moves the
+   nodes around in memory, using hash function HASH. */
+static void
+test_moved (int max_elems, hash_function *hash)
+{
+  struct element *e[2];
+  int cur;
+  int *values;
+  struct hmapx_node **nodes;
+  struct hmapx hmapx;
+  int i, j;
+
+  hmapx_init (&hmapx);
+  e[0] = xnmalloc (max_elems, sizeof *e[0]);
+  e[1] = xnmalloc (max_elems, sizeof *e[1]);
+  values = xnmalloc (max_elems, sizeof *values);
+  nodes = xnmalloc (max_elems, sizeof *nodes);
+  cur = 0;
+  for (i = 0; i < max_elems; i++)
+    {
+      values[i] = e[cur][i].data = i;
+      nodes[i] = hmapx_insert (&hmapx, &e[cur][i], hash (e[cur][i].data));
+      check_hmapx (&hmapx, values, i + 1, hash);
+
+      for (j = 0; j <= i; j++)
+        {
+          e[!cur][j] = e[cur][j];
+          hmapx_move (nodes[j], &e[cur][j]);
+          check_hmapx (&hmapx, values, i + 1, hash);
+        }
+      cur = !cur;
+    }
+  hmapx_destroy (&hmapx);
+  free (e[0]);
+  free (e[1]);
+  free (values);
+  free (nodes);
+}
+
+static void
+test_moved_random_hash (void) 
+{
+  test_moved (128, random_hash);
+}
+
+static void
+test_moved_identity_hash (void) 
+{
+  test_moved (128, identity_hash);
+}
+
+static void
+test_moved_constant_hash (void) 
+{
+  test_moved (32, constant_hash);
+}
+
+/* Inserts values into an HMAPX, then changes their values, using
+   hash function HASH. */
+static void
+test_changed (hash_function *hash)
+{
+  const int max_elems = 6;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *values, *changed_values;
+      struct hmapx_node **nodes;
+      struct element *elements;
+      unsigned int permutation_cnt;
+      int i;
+
+      values = xnmalloc (cnt, sizeof *values);
+      changed_values = xnmalloc (cnt, sizeof *changed_values);
+      elements = xnmalloc (cnt, sizeof *elements);
+      nodes = xnmalloc (cnt, sizeof *nodes);
+      for (i = 0; i < cnt; i++)
+        values[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (values, cnt);
+           permutation_cnt++)
+        {
+          for (i = 0; i < cnt; i++)
+            {
+              int j, k;
+              for (j = 0; j <= cnt; j++)
+                {
+                  struct hmapx hmapx;
+
+                  hmapx_init (&hmapx);
+
+                  /* Add to HMAPX in order. */
+                  for (k = 0; k < cnt; k++)
+                    {
+                      int n = values[k];
+                      elements[n].data = n;
+                      nodes[n] = hmapx_insert (&hmapx, &elements[n],
+                                               hash (elements[n].data));
+                    }
+                  check_hmapx (&hmapx, values, cnt, hash);
+
+                  /* Change value i to j. */
+                  elements[i].data = j;
+                  hmapx_changed (&hmapx, nodes[i], 
+                                 hash (elements[i].data));
+                  for (k = 0; k < cnt; k++)
+                    changed_values[k] = k;
+                  changed_values[i] = j;
+                  check_hmapx (&hmapx, changed_values, cnt, hash);
+
+                  hmapx_destroy (&hmapx);
+                }
+            }
+        }
+      check (permutation_cnt == factorial (cnt));
+
+      free (values);
+      free (changed_values);
+      free (elements);
+      free (nodes);
+    }
+}
+
+static void
+test_changed_random_hash (void)
+{
+  test_changed (random_hash);
+}
+
+static void
+test_changed_identity_hash (void)
+{
+  test_changed (identity_hash);
+}
+
+static void
+test_changed_constant_hash (void)
+{
+  test_changed (constant_hash);
+}
+
+/* Inserts values into an HMAPX, then changes and moves their
+   values, using hash function HASH. */
+static void
+test_change (hash_function *hash)
+{
+  const int max_elems = 6;
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      int *values, *changed_values;
+      struct hmapx_node **nodes;
+      struct element *elements;
+      struct element replacement;
+      unsigned int permutation_cnt;
+      int i;
+
+      values = xnmalloc (cnt, sizeof *values);
+      changed_values = xnmalloc (cnt, sizeof *changed_values);
+      elements = xnmalloc (cnt, sizeof *elements);
+      nodes = xnmalloc (cnt, sizeof *nodes);
+      for (i = 0; i < cnt; i++)
+        values[i] = i;
+
+      for (permutation_cnt = 0;
+           permutation_cnt == 0 || next_permutation (values, cnt);
+           permutation_cnt++)
+        {
+          for (i = 0; i < cnt; i++)
+            {
+              int j, k;
+              for (j = 0; j <= cnt; j++)
+                {
+                  struct hmapx hmapx;
+
+                  hmapx_init (&hmapx);
+
+                  /* Add to HMAPX in order. */
+                  for (k = 0; k < cnt; k++)
+                    {
+                      int n = values[k];
+                      elements[n].data = n;
+                      nodes[n] = hmapx_insert (&hmapx, &elements[n],
+                                               hash (elements[n].data));
+                    }
+                  check_hmapx (&hmapx, values, cnt, hash);
+
+                  /* Change value i to j. */
+                  replacement.data = j;
+                  hmapx_change (&hmapx, nodes[i], &replacement, hash (j));
+                  for (k = 0; k < cnt; k++)
+                    changed_values[k] = k;
+                  changed_values[i] = j;
+                  check_hmapx (&hmapx, changed_values, cnt, hash);
+
+                  hmapx_destroy (&hmapx);
+                }
+            }
+        }
+      check (permutation_cnt == factorial (cnt));
+
+      free (values);
+      free (changed_values);
+      free (elements);
+      free (nodes);
+    }
+}
+
+static void
+test_change_random_hash (void)
+{
+  test_change (random_hash);
+}
+
+static void
+test_change_identity_hash (void)
+{
+  test_change (identity_hash);
+}
+
+static void
+test_change_constant_hash (void)
+{
+  test_change (constant_hash);
+}
+
+static void
+test_swap (int max_elems, hash_function *hash) 
+{
+  struct element *elements;
+  int *values;
+  struct hmapx a, b;
+  struct hmapx *working, *empty;
+  int i;
+
+  hmapx_init (&a);
+  hmapx_init (&b);
+  working = &a;
+  empty = &b;
+  elements = xnmalloc (max_elems, sizeof *elements);
+  values = xnmalloc (max_elems, sizeof *values);
+  for (i = 0; i < max_elems; i++)
+    {
+      struct hmapx *tmp;
+      values[i] = elements[i].data = i;
+      hmapx_insert (working, &elements[i], hash (elements[i].data));
+      check_hmapx (working, values, i + 1, hash);
+      check_hmapx (empty, NULL, 0, hash);
+      hmapx_swap (&a, &b);
+      tmp = working;
+      working = empty;
+      empty = tmp;
+    }
+  hmapx_destroy (&a);
+  hmapx_destroy (&b);
+  free (elements);
+  free (values);
+}
+
+static void
+test_swap_random_hash (void) 
+{
+  test_swap (128, random_hash);
+}
+
+static void
+test_destroy_null (void) 
+{
+  hmapx_destroy (NULL);
+}
+
+/* Test shrinking an empty hash table. */
+static void
+test_shrink_empty (void)
+{
+  struct hmapx hmapx;
+
+  hmapx_init (&hmapx);
+  hmapx_reserve (&hmapx, 123);
+  hmapx_shrink (&hmapx);
+  hmapx_destroy (&hmapx);
+}
+\f
+/* Main program. */
+
+/* Runs TEST_FUNCTION and prints a message about NAME. */
+static void
+run_test (void (*test_function) (void), const char *name)
+{
+  test_name = name;
+  putchar ('.');
+  fflush (stdout);
+  test_function ();
+}
+
+int
+main (void)
+{
+  run_test (test_insert_any_remove_any_random_hash,
+            "insert any order, delete any order (random hash)");
+  run_test (test_insert_any_remove_any_identity_hash,
+            "insert any order, delete any order (identity hash)");
+  run_test (test_insert_any_remove_any_constant_hash,
+            "insert any order, delete any order (constant hash)");
+
+  run_test (test_insert_any_remove_same_random_hash,
+            "insert any order, delete same order (random hash)");
+  run_test (test_insert_any_remove_same_identity_hash,
+            "insert any order, delete same order (identity hash)");
+  run_test (test_insert_any_remove_same_constant_hash,
+            "insert any order, delete same order (constant hash)");
+
+  run_test (test_insert_any_remove_reverse_random_hash,
+            "insert any order, delete reverse order (random hash)");
+  run_test (test_insert_any_remove_reverse_identity_hash,
+            "insert any order, delete reverse order (identity hash)");
+  run_test (test_insert_any_remove_reverse_constant_hash,
+            "insert any order, delete reverse order (constant hash)");
+
+  run_test (test_random_sequence_random_hash,
+            "insert and delete in random sequence (random hash)");
+  run_test (test_random_sequence_identity_hash,
+            "insert and delete in random sequence (identity hash)");
+  run_test (test_random_sequence_constant_hash,
+            "insert and delete in random sequence (constant hash)");
+
+  run_test (test_insert_ordered_random_hash,
+            "insert in ascending order (random hash)");
+  run_test (test_insert_ordered_identity_hash,
+            "insert in ascending order (identity hash)");
+  run_test (test_insert_ordered_constant_hash,
+            "insert in ascending order (constant hash)");
+
+  run_test (test_moved_random_hash,
+            "move elements around in memory (random hash)");
+  run_test (test_moved_identity_hash,
+            "move elements around in memory (identity hash)");
+  run_test (test_moved_constant_hash,
+            "move elements around in memory (constant hash)");
+
+  run_test (test_changed_random_hash,
+            "change key data in nodes (random hash)");
+  run_test (test_changed_identity_hash,
+            "change key data in nodes (identity hash)");
+  run_test (test_changed_constant_hash,
+            "change key data in nodes (constant hash)");
+
+  run_test (test_change_random_hash,
+            "change and move key data in nodes (random hash)");
+  run_test (test_change_identity_hash,
+            "change and move key data in nodes (identity hash)");
+  run_test (test_change_constant_hash,
+            "change and move key data in nodes (constant hash)");
+
+  run_test (test_swap_random_hash, "test swapping tables");
+
+  run_test (test_destroy_null, "test destroying null table");
+  run_test (test_shrink_empty, "test shrinking an empty table");
+
+  putchar ('\n');
+
+  return 0;
+}
index b9cabe0a82d34488b0d5f8b40b614dd92bd71f41..ae29cc4d1d48cc0bf962facc9072cc2ceb93628b 100755 (executable)
@@ -124,15 +124,17 @@ RECODE x (LOWEST THRU 5=1)(ELSE=COPY) INTO cx5.
 RECODE x (4 THRU HIGHEST=2)(ELSE=COPY) INTO cx6.
 RECODE x (LO THRU HI=3)(ELSE=COPY) INTO cx7.
 RECODE x (SYSMIS=4)(ELSE=COPY) INTO cx8.
-LIST x cx0 TO cx8.
+RECODE x (5=COPY)(ELSE=22) INTO cx9.
+LIST x cx0 TO cx9.
 
 * String to string, with INTO, without COPY.
-STRING s0 TO s2 (A4)/t0 TO t3 (A10).
+STRING s0 TO s3 (A4)/t0 TO t3 (A10).
 RECODE s t ('a'='b')('ab'='bc') INTO s0 t0.
 RECODE s t ('abcd'='xyzw') INTO s1 t1.
 RECODE s t ('abc'='def')(ELSE='xyz') INTO s2 t2.
 RECODE t ('a'='b')('abcdefghi'='xyz')('abcdefghij'='jklmnopqr') INTO t3.
-LIST s t s0 TO s2 t0 TO t3.
+RECODE s (MISSING='gone') INTO s3.
+LIST s t s0 TO s3 t0 TO t3.
 
 * String to string, with INTO, with COPY.
 STRING cs0 TO cs2 (A4)/ct0 TO ct3 (A10).
@@ -168,97 +170,96 @@ perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -bu $TEMPDIR/pspp.list - <<EOF
 x  x0  x1  x2  x3  x4  x5  x6  x7  x8
 - --- --- --- --- --- --- --- --- ---
-0   0   0   0   0   0   1   0   3   0
-1   9   9   8  10  10   1   1   3   1
-2   2   2   9  10  10   1   2   3   2
-3   3   8   9  10  10   1   3   3   3
-4   4   4   9  10  10   1   2   3   4
-5   5   7   9  10  10   1   2   3   5
-6   6   6   9  10  10   6   2   3   6
-7   7   7   7  10  10   7   2   3   7
-8   8   8   9  10  10   8   2   3   8
-9   9   9   1  10  11   9   2   3   9
-.   .   .   .  11  11   .   .   .   4
+0   0   0   0   0   0   1   0   3   0 
+1   9   9   8  10  10   1   1   3   1 
+2   2   2   9  10  10   1   2   3   2 
+3   3   8   9  10  10   1   3   3   3 
+4   4   4   9  10  10   1   2   3   4 
+5   5   7   9  10  10   1   2   3   5 
+6   6   6   9  10  10   6   2   3   6 
+7   7   7   7  10  10   7   2   3   7 
+8   8   8   9  10  10   8   2   3   8 
+9   9   9   1  10  11   9   2   3   9 
+.   .   .   .  11  11   .   .   .   4 
 x ix0 ix1 ix2 ix3 ix4 ix5 ix6 ix7 ix8
 - --- --- --- --- --- --- --- --- ---
-0   .   .   .   .   .   1   .   3   .
-1   9   9   8  10  10   1   .   3   .
-2   .   .   9  10  10   1   .   3   .
-3   .   8   9  10  10   1   .   3   .
-4   .   .   9  10  10   1   2   3   .
-5   .   7   9  10  10   1   2   3   .
-6   .   .   9  10  10   .   2   3   .
-7   .   .   .  10  10   .   2   3   .
-8   .   .   9  10  10   .   2   3   .
-9   .   .   1  10  11   .   2   3   .
-.   .   .   .  11  11   .   .   .   4
-x cx0 cx1 cx2 cx3 cx4 cx5 cx6 cx7 cx8
-- --- --- --- --- --- --- --- --- ---
-0   0   0   0   0   0   1   0   3   0
-1   9   9   8  10  10   1   1   3   1
-2   2   2   9  10  10   1   2   3   2
-3   3   8   9  10  10   1   3   3   3
-4   4   4   9  10  10   1   2   3   4
-5   5   7   9  10  10   1   2   3   5
-6   6   6   9  10  10   6   2   3   6
-7   7   7   7  10  10   7   2   3   7
-8   8   8   9  10  10   8   2   3   8
-9   9   9   1  10  11   9   2   3   9
-.   .   .   .  11  11   .   .   .   4
-   s          t   s0   s1   s2         t0         t1         t2         t3
----- ---------- ---- ---- ---- ---------- ---------- ---------- ----------
-                          xyz                        xyz
-a    a          b         xyz  b                     xyz        b
-ab   ab         bc        xyz  bc                    xyz
-abc  abc                  def                        def
-abcd abcd            xyzw xyz             xyzw       xyz
-123  123                  xyz                        xyz
- 123  123                 xyz                        xyz
-+1   +1                   xyz                        xyz
-1x   1x                   xyz                        xyz
-abcd abcdefghi       xyzw xyz                        xyz        xyz
-xxx  abcdefghij           xyz                        xyz        jklmnopqr
+0   .   .   .   .   .   1   .   3   . 
+1   9   9   8  10  10   1   .   3   . 
+2   .   .   9  10  10   1   .   3   . 
+3   .   8   9  10  10   1   .   3   . 
+4   .   .   9  10  10   1   2   3   . 
+5   .   7   9  10  10   1   2   3   . 
+6   .   .   9  10  10   .   2   3   . 
+7   .   .   .  10  10   .   2   3   . 
+8   .   .   9  10  10   .   2   3   . 
+9   .   .   1  10  11   .   2   3   . 
+.   .   .   .  11  11   .   .   .   4 
+x cx0 cx1 cx2 cx3 cx4 cx5 cx6 cx7 cx8      cx9
+- --- --- --- --- --- --- --- --- --- --------
+0   0   0   0   0   0   1   0   3   0    22.00 
+1   9   9   8  10  10   1   1   3   1    22.00 
+2   2   2   9  10  10   1   2   3   2    22.00 
+3   3   8   9  10  10   1   3   3   3    22.00 
+4   4   4   9  10  10   1   2   3   4    22.00 
+5   5   7   9  10  10   1   2   3   5     5.00 
+6   6   6   9  10  10   6   2   3   6    22.00 
+7   7   7   7  10  10   7   2   3   7    22.00 
+8   8   8   9  10  10   8   2   3   8    22.00 
+9   9   9   1  10  11   9   2   3   9    22.00 
+.   .   .   .  11  11   .   .   .   4    22.00 
+   s          t   s0   s1   s2   s3         t0         t1         t2         t3
+---- ---------- ---- ---- ---- ---- ---------- ---------- ---------- ----------
+                          xyz                             xyz                   
+a    a          b         xyz       b                     xyz        b          
+ab   ab         bc        xyz       bc                    xyz                   
+abc  abc                  def                             def                   
+abcd abcd            xyzw xyz                  xyzw       xyz                   
+123  123                  xyz                             xyz                   
+ 123  123                 xyz                             xyz                   
++1   +1                   xyz                             xyz                   
+1x   1x                   xyz                             xyz                   
+abcd abcdefghi       xyzw xyz                             xyz        xyz        
+xxx  abcdefghij           xyz  gone                       xyz        jklmnopqr  
    s          t  cs0  cs1  cs2        ct0        ct1        ct2        ct3
 ---- ---------- ---- ---- ---- ---------- ---------- ---------- ----------
-                          xyz                        xyz
-a    a          b    a    xyz  b          a          xyz        b
-ab   ab         bc   ab   xyz  bc         ab         xyz        ab
-abc  abc        abc  abc  def  abc        abc        def        abc
-abcd abcd       abcd xyzw xyz  abcd       xyzw       xyz        abcd
-123  123        123  123  xyz  123        123        xyz        123
- 123  123        123  123 xyz   123        123       xyz         123
-+1   +1         +1   +1   xyz  +1         +1         xyz        +1
-1x   1x         1x   1x   xyz  1x         1x         xyz        1x
-abcd abcdefghi  abcd xyzw xyz  abcdefghi  abcdefghi  xyz        xyz
-xxx  abcdefghij xxx  xxx  xyz  abcdefghij abcdefghij xyz        jklmnopqr
+                          xyz                        xyz                   
+a    a          b    a    xyz  b          a          xyz        b          
+ab   ab         bc   ab   xyz  bc         ab         xyz        ab         
+abc  abc        abc  abc  def  abc        abc        def        abc        
+abcd abcd       abcd xyzw xyz  abcd       xyzw       xyz        abcd       
+123  123        123  123  xyz  123        123        xyz        123        
+ 123  123        123  123 xyz   123        123       xyz         123       
++1   +1         +1   +1   xyz  +1         +1         xyz        +1         
+1x   1x         1x   1x   xyz  1x         1x         xyz        1x         
+abcd abcdefghi  abcd xyzw xyz  abcdefghi  abcdefghi  xyz        xyz        
+xxx  abcdefghij xxx  xxx  xyz  abcdefghij abcdefghij xyz        jklmnopqr  
    s          t ns0 ns1 ns2 nt0 nt1 nt2
 ---- ---------- --- --- --- --- --- ---
-                  .   0   3   .   0   3
-a    a            .   .   3   .   .   3
-ab   ab           .   .   3   .   .   3
-abc  abc          .   .   3   .   .   3
-abcd abcd         1   1   2   1   1   2
-123  123        123 123   3 123 123   3
- 123  123       123 123   3 123 123   3
-+1   +1           1   1   3   1   1   3
-1x   1x           .   .   1   .   .   1
-abcd abcdefghi    1   1   2   .   .   3
-xxx  abcdefghij   .   .   3   .   .   3
+                  .   0   3   .   0   3 
+a    a            .   .   3   .   .   3 
+ab   ab           .   .   3   .   .   3 
+abc  abc          .   .   3   .   .   3 
+abcd abcd         1   1   2   1   1   2 
+123  123        123 123   3 123 123   3 
+ 123  123       123 123   3 123 123   3 
++1   +1           1   1   3   1   1   3 
+1x   1x           .   .   1   .   .   1 
+abcd abcdefghi    1   1   2   .   .   3 
+xxx  abcdefghij   .   .   3   .   .   3 
 x        sx0        sx1        sx2
 - ---------- ---------- ----------
-0            xxx        foobar
-1 abcdefghij xxx        foobar
-2 abcdefghij            xyz
-3 abcdefghij xxx        xyz
-4 abcdefghij            xyz
-5 abcdefghij xxx        xyz
-6 abcdefghij            xyz
-7 abcdefghij xxx        foobar
-8 abcdefghij            foobar
-9 abcdefghij xxx        foobar
-.            xxx        xyz
+0            xxx        foobar     
+1 abcdefghij xxx        foobar     
+2 abcdefghij            xyz        
+3 abcdefghij xxx        xyz        
+4 abcdefghij            xyz        
+5 abcdefghij xxx        xyz        
+6 abcdefghij            xyz        
+7 abcdefghij xxx        foobar     
+8 abcdefghij            foobar     
+9 abcdefghij xxx        foobar     
+.            xxx        xyz        
 EOF
-
 if [ $? -ne 0 ] ; then fail ; fi
 
 pass