+++ /dev/null
-To build this project from the sources direct from the cvs archive,
-you must install the prerequisites listed in README, plus the
-following:
-
- * Autoconf 2.60 (or later).
-
- * Automake 1.10 (or later).
-
- * Gettext 0.17 (or later).
-
- * GNU M4 1.4.9 (or later).
-
- * pkg-config 0.21 (or later).
-
- * gperf 3.0.1 (or later).
-
- * Gnulib, from Git at <git://git.savannah.gnu.org/gnulib.git>.
- If you do not have Git installed, up-to-date snapshots are
- at <http://git.savannah.gnu.org/gitweb/?p=gnulib.git>.
- Note that Gnulib does not require any form of installation:
- simply checking it out into a directory is sufficient. We
- recommend checking out gnulib into a directory named `gnulib'
- at the same level as PSPP.
-
- * libtool 1.5.22 (or later).
-
- * Texinfo 4.7 or later, to build the documentation.
-
-Once you have these installed, execute
- make -f Smake
-If you checked Gnulib out in a directory named `gnulib' at the same
-level as PSPP, then this is sufficient. Otherwise, provide the
-location of GNULIB on the `make' command line:
- make -f Smake GNULIB=/gnulib/base/directory/name
-
-After executing Smake, you may configure the source tree in the usual
-way with ./configure, e.g.
- ./configure
-For a list of options:
- ./configure --help
-
-To test:
- make check
-
-For a very thorough test:
- make distcheck
--- /dev/null
+Prerequisites for Building PSPP from Git
+----------------------------------------
+
+To build this project from the sources direct from the Git archive,
+you must install the prerequisites listed in README, plus the
+following:
+
+ * Autoconf 2.60 (or later).
+
+ * Automake 1.10 (or later).
+
+ * Gettext 0.17 (or later).
+
+ * GNU M4 1.4.9 (or later).
+
+ * pkg-config 0.21 (or later).
+
+ * gperf 3.0.1 (or later).
+
+ * Gnulib (see below for details).
+
+ * libtool 1.5.22 (or later).
+
+ * Texinfo 4.7 or later, to build the documentation.
+
+After you install PSPP's prerequisites, you must obtain a copy of
+Gnulib, then bootstrap the tree, as described in the sections below.
+After that, you may follow the procedure described in INSTALL.
+
+Obtaining Gnulib
+----------------
+
+This version of PSPP should work with the Gnulib commit shown below.
+Gnulib does not maintain a stable API or ABI, so it is possible that
+PSPP will not work with older or newer versions of Gnulib.
+
+ commit c5588be343f580be8e87d99e043dcdf3d7606759
+ Author: Paolo Bonzini <bonzini@gnu.org>
+ Date: Thu Dec 3 18:39:47 2009 +0100
+
+ exclude: Fix header file problems.
+
+To clone Gnulib into a directory named "gnulib" using Git, and then
+check out this particular commit, run these commands:
+ git clone git://git.savannah.gnu.org/gnulib.git gnulib
+ cd gnulib
+ git checkout $COMMIT
+where $COMMIT should be replaced by the commit number listed above
+(usually it is sufficient to just type the first 6 or so digits).
+
+If you do not have Git installed, then you may alternately download
+http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=snapshot;h=$COMMIT;sf=tgz
+where $COMMIT is, again, at least the first few digits of the commit
+number listed above. This download will yield a tar.gz file that you
+may extract with "gunzip" and "tar" to yield identical results.
+
+Bootstrapping
+-------------
+
+Once you have Gnulib installed, PSPP must be "bootstrapped" using the
+following command:
+ make -f Smake
+If you checked Gnulib out in a directory named `gnulib' at the same
+level as PSPP, then this is sufficient. Otherwise, provide the
+location of GNULIB on the `make' command line:
+ make -f Smake GNULIB=/gnulib/base/directory/name
+
+After executing Smake, follow the procedure described in INSTALL to
+build and install PSPP. On some systems this may be as simple as:
+ ./configure
+ make
+
+Once PSPP is built, you may run its self-tests with:
+ make check
+or for a more thorough test:
+ make distcheck
byteswap \
c-ctype \
c-strtod \
+ canonicalize \
close \
crypto/md4 \
dirname \
variable @code{bias} from the file header. For example,
code 105 with bias 100.0 (the normal value) indicates a numeric variable
of value 5.
+One file has been seen written by SPSS 14 that contained such a code
+in a @emph{string} field with the value 0 (after the bias is
+subtracted) as a way of encoding null bytes.
@item 252
End of file. This code may or may not appear at the end of the data
{
/* Generate unique temporary file name. */
rf->tmp_name = xasprintf ("%s.tmpXXXXXX", file_name);
- if (gen_tempname (rf->tmp_name, GT_NOCREATE) < 0)
+ if (gen_tempname (rf->tmp_name, 0, 0600, GT_NOCREATE) < 0)
{
msg (ME, _("Creating temporary file to replace %s: %s."),
rf->file_name, strerror (errno));
double bias; /* Compression bias, usually 100.0. */
uint8_t opcodes[8]; /* Current block of opcodes. */
size_t opcode_idx; /* Next opcode to interpret, 8 if none left. */
+ bool corruption_warning; /* Warned about possible corruption? */
};
static const struct casereader_class sys_file_casereader_class;
r->oct_cnt = 0;
r->has_long_var_names = false;
r->opcode_idx = sizeof r->opcodes;
+ r->corruption_warning = false;
/* TRANSLATORS: this fragment will be interpolated into
messages in fh_lock() that identify types of files. */
break;
case 254:
- sys_error (r, _("Compressed data is corrupt."));
+ float_convert (r->float_format, " ", FLOAT_NATIVE_DOUBLE, d);
+ if (!r->corruption_warning)
+ {
+ r->corruption_warning = true;
+ sys_warn (r, _("Possible compressed data corruption: "
+ "compressed spaces appear in numeric field."));
+ }
+ break;
case 255:
*d = SYSMIS;
static bool
read_compressed_string (struct sfm_reader *r, char *dst)
{
- switch (read_opcode (r))
+ int opcode = read_opcode (r);
+ switch (opcode)
{
case -1:
case 252:
break;
default:
- sys_error (r, _("Compressed data is corrupt."));
+ {
+ double value = opcode - r->bias;
+ float_convert (FLOAT_NATIVE_DOUBLE, &value, r->float_format, dst);
+ if (value == 0.0)
+ {
+ /* This has actually been seen "in the wild". The submitter of the
+ file that showed that the contents decoded as spaces, but they
+ were at the end of the field so it's possible that the null
+ bytes just acted as null terminators. */
+ }
+ else if (!r->corruption_warning)
+ {
+ r->corruption_warning = true;
+ sys_warn (r, _("Possible compressed data corruption: "
+ "string contains compressed integer (opcode %d)"),
+ opcode);
+ }
+ }
+ break;
}
return true;
if ( var_has_label (var))
{
- gchar *text = g_strdup_printf (
+ gchar *text = g_markup_printf_escaped (
"<span stretch=\"condensed\">%s</span>",
var_get_label (var));