Implemented support for very long strings a la spss v13/v14
authorJohn Darrington <john@darrington.wattle.id.au>
Tue, 2 May 2006 03:51:42 +0000 (03:51 +0000)
committerJohn Darrington <john@darrington.wattle.id.au>
Tue, 2 May 2006 03:51:42 +0000 (03:51 +0000)
36 files changed:
ChangeLog
NEWS
configure.ac
doc/ChangeLog
doc/data-file-format.texi
po/en_GB.po
po/pspp.pot
src/data/ChangeLog
src/data/data-in.c
src/data/data-out.c
src/data/dictionary.c
src/data/format.def
src/data/format.h
src/data/sfm-private.h
src/data/sys-file-reader.c
src/data/sys-file-writer.c
src/data/value.h
src/data/variable.c
src/data/variable.h
src/language/data-io/ChangeLog
src/language/data-io/list.q
src/language/expressions/evaluate.c
src/language/expressions/operations.def
src/language/expressions/parse.c
src/language/lexer/format-parser.c
src/language/lexer/lexer.h
src/libpspp/str.c
src/libpspp/str.h
tests/automake.mk
tests/bugs/list-overflow.sh [new file with mode: 0755]
tests/command/count.sh
tests/command/print-strings.sh [new file with mode: 0755]
tests/command/very-long-strings.sh [new file with mode: 0755]
tests/expressions/expressions.sh
tests/v13.sav [new file with mode: 0755]
tests/v14.sav [new file with mode: 0644]

index 62eec08a09da0f398a52ef274e917c469f060706..46efad717a7882d310b8e4320f76409b2340faca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+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.
 Mon Apr 24 14:12:25 2006  Ben Pfaff  <blp@gnu.org>
 
        * Smake: Add exit to GNULIB_MODULES.
diff --git a/NEWS b/NEWS
index b2cb211cbcc46963cc77b9debc273faf907a7f16..12f7a23ac350d492a6d862e4055a59ae4212bb17 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,12 @@ See the end for copying conditions.
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
 
 
 Please send PSPP bug reports to bug-gnu-pspp@gnu.org.
 
-Changes since 0.4.1:
+Changes since 0.4.2:
+
+\f
+Changes since 0.4.0 to 0.4.1:
+
+  Added support for very long string variables > 255 bytes.
 
   Output changes:
 
 
   Output changes:
 
@@ -23,8 +28,6 @@ Changes since 0.4.1:
       font used in PostScript output.  "make install" will install AFM
       files for the standard PostScript files, including the ones that
       the PostScript driver uses by default.
       font used in PostScript output.  "make install" will install AFM
       files for the standard PostScript files, including the ones that
       the PostScript driver uses by default.
-\f
-Changes since 0.4.0 to 0.4.1:
 
   Newly implemented commands and statistical features:
 
 
   Newly implemented commands and statistical features:
 
index 6c8820c7bfb51031d115a7f773948b7b131baf97..7e518cbf089170c47c050b9e8e5fdfad0938a36e 100644 (file)
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
 
 dnl Initialize.
 AX_PREREQ(2.57)
 
 dnl Initialize.
 AX_PREREQ(2.57)
-AC_INIT(pspp, 0.4.1,bug-gnu-pspp@gnu.org)
+AC_INIT(pspp, 0.4.2,bug-gnu-pspp@gnu.org)
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE(1.9)
 
 AC_CONFIG_HEADERS([config.h])
 AM_INIT_AUTOMAKE(1.9)
 
index 901cf10275b7f5e376a4428be9764c41b0168bdd..03055447ed9e6b5239b698f914b5b60f59adba70 100644 (file)
@@ -1,3 +1,8 @@
+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
 2006-04-28  Jason Stover  <jhs@math.gcsu.edu>
 
        * regression.texi: Added description of the RESID and PRED
index c6b0c9653aa7e2aa27c95beb074eae1bfe942fa7..4f3518c028d6fdd788a97271d3072b6c86f3dfcd 100644 (file)
@@ -9,7 +9,8 @@ There are three data types used in system files: 32-bit integers, 64-bit
 floating points, and 1-byte characters.  In this document these will
 simply be referred to as @code{int32}, @code{flt64}, and @code{char},
 the names that are used in the PSPP source code.  Every field of type
 floating points, and 1-byte characters.  In this document these will
 simply be referred to as @code{int32}, @code{flt64}, and @code{char},
 the names that are used in the PSPP source code.  Every field of type
-@code{int32} or @code{flt64} is aligned on a 32-bit boundary.
+@code{int32} or @code{flt64} is aligned on a 32-bit boundary relative to 
+the start of the record.
 
 The endianness of data in PSPP system files is not specified.  System
 files output on a computer of a particular endianness will have the
 
 The endianness of data in PSPP system files is not specified.  System
 files output on a computer of a particular endianness will have the
@@ -45,6 +46,7 @@ described below:
 * Machine flt64 Info Record::   
 * Auxiliary Variable Parameter Record::
 * Long Variable Names Record::
 * Machine flt64 Info Record::   
 * Auxiliary Variable Parameter Record::
 * Long Variable Names Record::
+* Very Long String Length Record::
 * Miscellaneous Informational Records::  
 * Dictionary Termination Record::  
 * Data Record::                 
 * Miscellaneous Informational Records::  
 * Dictionary Termination Record::  
 * Data Record::                 
@@ -61,7 +63,7 @@ struct sysfile_header
     char                rec_type[4];
     char                prod_name[60];
     int32               layout_code;
     char                rec_type[4];
     char                prod_name[60];
     int32               layout_code;
-    int32               case_size;
+    int32               nominal_case_size;
     int32               compressed;
     int32               weight_index;
     int32               ncases;
     int32               compressed;
     int32               weight_index;
     int32               ncases;
@@ -90,13 +92,13 @@ with spaces.
 Always set to 2.  PSPP reads this value to determine the
 file's endianness.
 
 Always set to 2.  PSPP reads this value to determine the
 file's endianness.
 
-@item int32 case_size;
+@item int32 nominal_case_size;
 Number of data elements per case.  This is the number of variables,
 except that long string variables add extra data elements (one for every
 Number of data elements per case.  This is the number of variables,
 except that long string variables add extra data elements (one for every
-8 characters after the first 8).
-When reading system files, PSPP will use this value unless it is set
-to -1, in which case it will determine the number of data elements by
-context.  When writing system files PSPP always uses this value.
+8 characters after the first 8).  However, string variables do not 
+contribute to this value beyond the first 255 bytes.   Further, system
+files written by some systems set this value to -1.  In general, it is
+unsafe for systems reading system files to rely upon this value.
 
 @item int32 compressed;
 Set to 1 if the data in the file is compressed, 0 otherwise.
 
 @item int32 compressed;
 Set to 1 if the data in the file is compressed, 0 otherwise.
@@ -133,8 +135,8 @@ format and using 24-hour time.  If the time is not available then this
 field is arbitrarily set to @samp{00:00:00}.
 
 @item char file_label[64];
 field is arbitrarily set to @samp{00:00:00}.
 
 @item char file_label[64];
-Set the the file label declared by the user, if any.  Padded on the
-right with spaces.
+Set the the file label declared by the user, if any @xref{FILE LABEL}.
+Padded on the right with spaces.
 
 @item char padding[3];
 Ignored padding bytes to make the structure a multiple of 32 bits in
 
 @item char padding[3];
 Ignored padding bytes to make the structure a multiple of 32 bits in
@@ -146,9 +148,7 @@ length.  Set to zeros.
 
 Immediately following the header must come the variable records.  There
 must be one variable record for every variable and every 8 characters in
 
 Immediately following the header must come the variable records.  There
 must be one variable record for every variable and every 8 characters in
-a long string beyond the first 8; i.e., there must be exactly as many
-variable records as the value specified for @code{case_size} in the file
-header record.
+a long string beyond the first 8.
 
 @example
 struct sysfile_variable
 
 @example
 struct sysfile_variable
@@ -168,7 +168,7 @@ struct sysfile_variable
 
     /* The following field is present only
        if n_missing_values is not 0. */
 
     /* The following field is present only
        if n_missing_values is not 0. */
-    flt64               missing_values[/* variable length*/];
+    flt64               missing_values[/* variable length */];
   @};
 @end example
 
   @};
 @end example
 
@@ -367,7 +367,7 @@ Record type.  Always set to 4.
 Number of variables that the associated value labels from the value
 label record are to be applied.
 
 Number of variables that the associated value labels from the value
 label record are to be applied.
 
-@item int32 vars[/* variable length];
+@item int32 vars[/* variable length */];
 A list of variables to which to apply the value labels.  There are
 @code{count} elements.
 @end table
 A list of variables to which to apply the value labels.  There are
 @code{count} elements.
 @end table
@@ -600,7 +600,7 @@ Centre aligned
 
 
 
 
 
 
-@node Long Variable Names Record, Miscellaneous Informational Records, Auxiliary Variable Parameter Record,  Data File Format
+@node Long Variable Names Record, Very Long String Length Record, Auxiliary Variable Parameter Record,  Data File Format
 @section Long Variable Names Record
 
 There must be no more than one long variable names record per
 @section Long Variable Names Record
 
 There must be no more than one long variable names record per
@@ -634,7 +634,7 @@ The size of each element in the @code{var_name_pairs} member. Always set to 1.
 @item int32 count;
 The total number of bytes in @code{var_name_pairs}.
 
 @item int32 count;
 The total number of bytes in @code{var_name_pairs}.
 
-@item char var_name_pairs[/* variable length];
+@item char var_name_pairs[/* variable length */];
 A list of @var{key}--@var{value} tuples, where @var{key} is the name
 of a variable, and @var{value} is its long variable name. 
 The @var{key} field is at most 8 bytes long and must match the
 A list of @var{key}--@var{value} tuples, where @var{key} is the name
 of a variable, and @var{value} is its long variable name. 
 The @var{key} field is at most 8 bytes long and must match the
@@ -646,8 +646,58 @@ trailing separator following the last tuple.
 The total length is @code{count} bytes.
 @end table
 
 The total length is @code{count} bytes.
 @end table
 
+@node Very Long String Length Record, Miscellaneous Informational Records, Long Variable Names Record, Data File Format
+@comment  node-name,  next,  previous,  up
+@section Very Long String Length Record
 
 
-@node Miscellaneous Informational Records, Dictionary Termination Record, Long Variable Names Record, Data File Format
+
+There must be no more than one very long string length record per
+system file.  This  record must follow the variable records and precede the 
+dictionary termination record. 
+
+@example
+struct sysfile_very_long_string_lengths
+  @{
+    /* Header. */
+    int32               rec_type;
+    int32               subtype;
+    int32               size;
+    int32               count;
+
+    /* Data. */
+    char                string_lengths[/* variable length */];
+  @};
+@end example
+
+@table @code
+@item int32 rec_type;
+Record type.  Always set to 7.
+
+@item int32 subtype;
+Record subtype.  Always set to 14.
+
+@item int32 size;
+The size of each element in the @code{string_lengths} member. Always set to 1.
+
+@item int32 count;
+The total number of bytes in @code{string_lengths}.
+
+@item char string_lengths[/* variable length */];
+A list of @var{key}--@var{value} tuples, where @var{key} is the name
+of a variable, and @var{value} is its length.
+The @var{key} field is at most 8 bytes long and must match the
+name of a variable which appears in the variable record @xref{Variable Record}.
+The @var{value} field is exactly 5 bytes long. It is a zero padded ascii 
+encoded, string which is the length of the variable.
+The @var{key} and @var{value} fields are separated by a @samp{=} byte.
+Tuples are delimeted  a two byte sequence  @{00, 09@}.  
+After the last tuple, there may be a single byte 00, or by @{00, 09@}.  
+The total length is @code{count} bytes.
+@end table
+
+
+
+@node Miscellaneous Informational Records, Dictionary Termination Record, Very Long String Length Record, Data File Format
 @section Miscellaneous Informational Records
 
 Miscellaneous informational records must follow the variable records and
 @section Miscellaneous Informational Records
 
 Miscellaneous informational records must follow the variable records and
@@ -724,9 +774,8 @@ The format of data records varies depending on whether the data is
 compressed.  Regardless, the data is arranged in a series of 8-byte
 elements.
 
 compressed.  Regardless, the data is arranged in a series of 8-byte
 elements.
 
-When data is not compressed, Every case is composed of @code{case_size}
-of these 8-byte elements, where @code{case_size} comes from the file
-header record (@pxref{File Header Record}).  Each element corresponds to
+When data is not compressed, 
+each element corresponds to
 the variable declared in the respective variable record (@pxref{Variable
 Record}).  Numeric values are given in @code{flt64} format; string
 values are literal characters string, padded on the right when
 the variable declared in the respective variable record (@pxref{Variable
 Record}).  Numeric values are given in @code{flt64} format; string
 values are literal characters string, padded on the right when
index 7ab1299e6c45c45a1c9016336e4822b2b37e907b..177e4b0672da63b60d6916d1d83a8888d4257fdb 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PSPP 0.3.1\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
 msgstr ""
 "Project-Id-Version: PSPP 0.3.1\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-04-26 13:48-0700\n"
+"POT-Creation-Date: 2006-05-02 10:55+0800\n"
 "PO-Revision-Date: 2004-01-23 13:04+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
 "PO-Revision-Date: 2004-01-23 13:04+0800\n"
 "Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
 "Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
@@ -45,32 +45,32 @@ msgstr ""
 msgid "Date %04d-%d-%d is before the earliest acceptable date of 1582-10-15."
 msgstr ""
 
 msgid "Date %04d-%d-%d is before the earliest acceptable date of 1582-10-15."
 msgstr ""
 
-#: src/data/casefile.c:256
+#: src/data/casefile.c:258
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:422
+#: src/data/casefile.c:424
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:571
+#: src/data/casefile.c:573
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:597
+#: src/data/casefile.c:599
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:615
+#: src/data/casefile.c:617
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:618
+#: src/data/casefile.c:620
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
@@ -114,11 +114,11 @@ msgstr ""
 msgid "Unrecognized character in field."
 msgstr ""
 
 msgid "Unrecognized character in field."
 msgstr ""
 
-#: src/data/data-in.c:339 src/data/data-in.c:585
+#: src/data/data-in.c:339 src/data/data-in.c:589
 msgid "Field must have even length."
 msgstr ""
 
 msgid "Field must have even length."
 msgstr ""
 
-#: src/data/data-in.c:349 src/data/data-in.c:595
+#: src/data/data-in.c:349 src/data/data-in.c:599
 msgid "Field must contain only hex digits."
 msgstr ""
 
 msgid "Field must contain only hex digits."
 msgstr ""
 
@@ -145,104 +145,104 @@ msgstr ""
 msgid "Error in syntax of zoned decimal number."
 msgstr ""
 
 msgid "Error in syntax of zoned decimal number."
 msgstr ""
 
-#: src/data/data-in.c:635
+#: src/data/data-in.c:639
 msgid "Unexpected end of field."
 msgstr ""
 
 msgid "Unexpected end of field."
 msgstr ""
 
-#: src/data/data-in.c:661
+#: src/data/data-in.c:665
 msgid "Digit expected in field."
 msgstr ""
 
 msgid "Digit expected in field."
 msgstr ""
 
-#: src/data/data-in.c:686
+#: src/data/data-in.c:690
 #, c-format
 msgid "Day (%ld) must be between 1 and 31."
 msgstr ""
 
 #, c-format
 msgid "Day (%ld) must be between 1 and 31."
 msgstr ""
 
-#: src/data/data-in.c:711
+#: src/data/data-in.c:715
 msgid "Delimiter expected between fields in date."
 msgstr ""
 
 msgid "Delimiter expected between fields in date."
 msgstr ""
 
-#: src/data/data-in.c:744
+#: src/data/data-in.c:748
 #, c-format
 msgid "Parse error at `%c' expecting %s."
 msgstr ""
 
 #, c-format
 msgid "Parse error at `%c' expecting %s."
 msgstr ""
 
-#: src/data/data-in.c:758
+#: src/data/data-in.c:762
 #, c-format
 msgid "Unknown %s `%.*s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown %s `%.*s'."
 msgstr ""
 
-#: src/data/data-in.c:808
+#: src/data/data-in.c:812
 #, c-format
 msgid "Month (%ld) must be between 1 and 12."
 msgstr ""
 
 #, c-format
 msgid "Month (%ld) must be between 1 and 12."
 msgstr ""
 
-#: src/data/data-in.c:812
+#: src/data/data-in.c:816
 msgid "month"
 msgstr ""
 
 msgid "month"
 msgstr ""
 
-#: src/data/data-in.c:826
+#: src/data/data-in.c:830
 #, c-format
 msgid "Year (%ld) must be between 1582 and 19999."
 msgstr ""
 
 #, c-format
 msgid "Year (%ld) must be between 1582 and 19999."
 msgstr ""
 
-#: src/data/data-in.c:837
+#: src/data/data-in.c:841
 #, c-format
 msgid "Trailing garbage \"%s\" following date."
 msgstr ""
 
 #, c-format
 msgid "Trailing garbage \"%s\" following date."
 msgstr ""
 
-#: src/data/data-in.c:852
+#: src/data/data-in.c:856
 #, c-format
 msgid "Julian day (%d) must be between 1 and 366."
 msgstr ""
 
 #, c-format
 msgid "Julian day (%d) must be between 1 and 366."
 msgstr ""
 
-#: src/data/data-in.c:864
+#: src/data/data-in.c:868
 #, c-format
 msgid "Year (%d) must be between 1582 and 19999."
 msgstr ""
 
 #, c-format
 msgid "Year (%d) must be between 1582 and 19999."
 msgstr ""
 
-#: src/data/data-in.c:880
+#: src/data/data-in.c:884
 #, c-format
 msgid "Quarter (%ld) must be between 1 and 4."
 msgstr ""
 
 #, c-format
 msgid "Quarter (%ld) must be between 1 and 4."
 msgstr ""
 
-#: src/data/data-in.c:890
+#: src/data/data-in.c:894
 msgid "`Q' expected between quarter and year."
 msgstr ""
 
 msgid "`Q' expected between quarter and year."
 msgstr ""
 
-#: src/data/data-in.c:906
+#: src/data/data-in.c:910
 #, c-format
 msgid "Week (%ld) must be between 1 and 53."
 msgstr ""
 
 #, c-format
 msgid "Week (%ld) must be between 1 and 53."
 msgstr ""
 
-#: src/data/data-in.c:918
+#: src/data/data-in.c:922
 msgid "`WK' expected between week and year."
 msgstr ""
 
 msgid "`WK' expected between week and year."
 msgstr ""
 
-#: src/data/data-in.c:941
+#: src/data/data-in.c:945
 msgid "Delimiter expected between fields in time."
 msgstr ""
 
 msgid "Delimiter expected between fields in time."
 msgstr ""
 
-#: src/data/data-in.c:953
+#: src/data/data-in.c:957
 #, c-format
 msgid "Hour (%ld) must be positive."
 msgstr ""
 
 #, c-format
 msgid "Hour (%ld) must be positive."
 msgstr ""
 
-#: src/data/data-in.c:965
+#: src/data/data-in.c:969
 #, c-format
 msgid "Minute (%ld) must be between 0 and 59."
 msgstr ""
 
 #, c-format
 msgid "Minute (%ld) must be between 0 and 59."
 msgstr ""
 
-#: src/data/data-in.c:1012
+#: src/data/data-in.c:1016
 #, c-format
 msgid "Hour (%ld) must be between 0 and 23."
 msgstr ""
 
 #, c-format
 msgid "Hour (%ld) must be between 0 and 23."
 msgstr ""
 
-#: src/data/data-in.c:1040
+#: src/data/data-in.c:1044
 msgid "weekday"
 msgstr ""
 
 msgid "weekday"
 msgstr ""
 
-#: src/data/data-in.c:1371
+#: src/data/data-in.c:1375
 #, c-format
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
 #, c-format
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
@@ -290,7 +290,7 @@ msgid ""
 "Year %d cannot be represented in four digits for output formatting purposes."
 msgstr ""
 
 "Year %d cannot be represented in four digits for output formatting purposes."
 msgstr ""
 
-#: src/data/dictionary.c:710
+#: src/data/dictionary.c:711
 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."
 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."
@@ -387,27 +387,27 @@ msgid "%s variables are not compatible with %s format %s."
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
-#: src/data/sys-file-reader.c:997 src/data/sys-file-reader.c:1006
+#: src/data/sys-file-reader.c:1162 src/data/sys-file-reader.c:1171
 #: src/ui/gui/psppire-var-store.c:435
 msgid "String"
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
 #: src/ui/gui/psppire-var-store.c:435
 msgid "String"
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
-#: src/data/sys-file-reader.c:997 src/data/sys-file-reader.c:1006
+#: src/data/sys-file-reader.c:1162 src/data/sys-file-reader.c:1171
 #: src/ui/gui/psppire-var-store.c:428
 msgid "Numeric"
 msgstr ""
 
 #: src/ui/gui/psppire-var-store.c:428
 msgid "Numeric"
 msgstr ""
 
-#: src/data/format.c:198 src/data/sys-file-reader.c:999
-#: src/data/sys-file-reader.c:1144 src/data/sys-file-reader.c:1145
+#: src/data/format.c:198 src/data/sys-file-reader.c:1164
+#: src/data/sys-file-reader.c:1309 src/data/sys-file-reader.c:1310
 #: src/data/variable.c:41 src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/language/xforms/recode.c:465 src/language/xforms/recode.c:466
 msgid "numeric"
 msgstr ""
 
 #: src/data/variable.c:41 src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/language/xforms/recode.c:465 src/language/xforms/recode.c:466
 msgid "numeric"
 msgstr ""
 
-#: src/data/format.c:198 src/data/sys-file-reader.c:999
-#: src/data/sys-file-reader.c:1144 src/data/sys-file-reader.c:1145
+#: src/data/format.c:198 src/data/sys-file-reader.c:1164
+#: src/data/sys-file-reader.c:1309 src/data/sys-file-reader.c:1310
 #: src/data/variable.c:41 src/data/variable.c:49
 #: src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/data/variable.c:41 src/data/variable.c:49
 #: src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
@@ -477,12 +477,12 @@ msgstr ""
 msgid "Bad time string length %d."
 msgstr ""
 
 msgid "Bad time string length %d."
 msgstr ""
 
-#: src/data/por-file-reader.c:473 src/data/sys-file-reader.c:989
+#: src/data/por-file-reader.c:473 src/data/sys-file-reader.c:1154
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
-#: src/data/por-file-reader.c:480 src/data/sys-file-reader.c:1005
+#: src/data/por-file-reader.c:480 src/data/sys-file-reader.c:1170
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
@@ -515,7 +515,7 @@ msgstr ""
 msgid "position %d: Invalid variable name `%s'."
 msgstr ""
 
 msgid "position %d: Invalid variable name `%s'."
 msgstr ""
 
-#: src/data/por-file-reader.c:541 src/language/expressions/evaluate.c:155
+#: src/data/por-file-reader.c:541 src/language/expressions/evaluate.c:158
 #, c-format
 msgid "Duplicate variable name %s."
 msgstr ""
 #, c-format
 msgid "Duplicate variable name %s."
 msgstr ""
@@ -575,135 +575,140 @@ msgstr ""
 msgid "Could not access definition for terminal `%s'."
 msgstr ""
 
 msgid "Could not access definition for terminal `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:130
+#: src/data/sys-file-reader.c:132
 msgid "corrupt system file: "
 msgstr ""
 
 msgid "corrupt system file: "
 msgstr ""
 
-#: src/data/sys-file-reader.c:154
+#: src/data/sys-file-reader.c:156
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:245
+#: src/data/sys-file-reader.c:280
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:262
+#: src/data/sys-file-reader.c:297
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:271
+#: src/data/sys-file-reader.c:306
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:274
+#: src/data/sys-file-reader.c:309
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:299
+#: src/data/sys-file-reader.c:335
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:357
+#: src/data/sys-file-reader.c:394
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
-#: src/data/sys-file-reader.c:411
+#: src/data/sys-file-reader.c:456
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
-#: src/data/sys-file-reader.c:418
+#: src/data/sys-file-reader.c:463
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:428
+#: src/data/sys-file-reader.c:473
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:437
+#: src/data/sys-file-reader.c:482
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:464
+#: src/data/sys-file-reader.c:577
+#, c-format
+msgid "%s: No variable called %s but it is listed in length table."
+msgstr ""
+
+#: src/data/sys-file-reader.c:629
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:489
+#: src/data/sys-file-reader.c:655
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:521
+#: src/data/sys-file-reader.c:691
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/data/sys-file-reader.c:532
+#: src/data/sys-file-reader.c:702
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
-#: src/data/sys-file-reader.c:548
+#: src/data/sys-file-reader.c:718
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:551 src/data/sys-file-reader.c:552
+#: src/data/sys-file-reader.c:721 src/data/sys-file-reader.c:722
 msgid "big-endian"
 msgstr ""
 
 msgid "big-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:551 src/data/sys-file-reader.c:552
+#: src/data/sys-file-reader.c:721 src/data/sys-file-reader.c:722
 msgid "little-endian"
 msgstr ""
 
 msgid "little-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:553
+#: src/data/sys-file-reader.c:723
 msgid "unknown"
 msgstr ""
 
 msgid "unknown"
 msgstr ""
 
-#: src/data/sys-file-reader.c:557
+#: src/data/sys-file-reader.c:727
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
-#: src/data/sys-file-reader.c:561
+#: src/data/sys-file-reader.c:731
 msgid "DEC Kanji"
 msgstr ""
 
 msgid "DEC Kanji"
 msgstr ""
 
-#: src/data/sys-file-reader.c:561 src/language/dictionary/sys-file-info.c:120
+#: src/data/sys-file-reader.c:731 src/language/dictionary/sys-file-info.c:120
 msgid "Unknown"
 msgstr ""
 
 msgid "Unknown"
 msgstr ""
 
-#: src/data/sys-file-reader.c:577
+#: src/data/sys-file-reader.c:747
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/data/sys-file-reader.c:592
+#: src/data/sys-file-reader.c:762
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
@@ -711,213 +716,213 @@ msgid ""
 "%g; LOWEST: %g, %g."
 msgstr ""
 
 "%g; LOWEST: %g, %g."
 msgstr ""
 
-#: src/data/sys-file-reader.c:619
+#: src/data/sys-file-reader.c:789
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
-#: src/data/sys-file-reader.c:661
+#: src/data/sys-file-reader.c:831
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
-#: src/data/sys-file-reader.c:689
+#: src/data/sys-file-reader.c:859
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:694
+#: src/data/sys-file-reader.c:864
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
-#: src/data/sys-file-reader.c:819
+#: src/data/sys-file-reader.c:983
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:830
+#: src/data/sys-file-reader.c:994
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
-#: src/data/sys-file-reader.c:836
+#: src/data/sys-file-reader.c:1000
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:839
+#: src/data/sys-file-reader.c:1003
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
-#: src/data/sys-file-reader.c:843
+#: src/data/sys-file-reader.c:1007
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
-#: src/data/sys-file-reader.c:848
+#: src/data/sys-file-reader.c:1012
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
-#: src/data/sys-file-reader.c:867
+#: src/data/sys-file-reader.c:1031
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:873
+#: src/data/sys-file-reader.c:1037
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:896
+#: src/data/sys-file-reader.c:1061
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:917
+#: src/data/sys-file-reader.c:1082
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
-#: src/data/sys-file-reader.c:938
+#: src/data/sys-file-reader.c:1103
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
-#: src/data/sys-file-reader.c:965
+#: src/data/sys-file-reader.c:1130
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
-#: src/data/sys-file-reader.c:970
+#: src/data/sys-file-reader.c:1135
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:995
+#: src/data/sys-file-reader.c:1160
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1048
+#: src/data/sys-file-reader.c:1213
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1090
+#: src/data/sys-file-reader.c:1255
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1101
+#: src/data/sys-file-reader.c:1266
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1117
+#: src/data/sys-file-reader.c:1282
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1124
+#: src/data/sys-file-reader.c:1289
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1129
+#: src/data/sys-file-reader.c:1294
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1140
+#: src/data/sys-file-reader.c:1305
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1181
+#: src/data/sys-file-reader.c:1346
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1185
+#: src/data/sys-file-reader.c:1350
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1227 src/data/sys-file-reader.c:1510
+#: src/data/sys-file-reader.c:1392 src/data/sys-file-reader.c:1676
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1230 src/data/sys-file-reader.c:1348
-#: src/data/sys-file-reader.c:1389
+#: src/data/sys-file-reader.c:1395 src/data/sys-file-reader.c:1514
+#: src/data/sys-file-reader.c:1555
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1246
+#: src/data/sys-file-reader.c:1412
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1261
+#: src/data/sys-file-reader.c:1427
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1267
+#: src/data/sys-file-reader.c:1433
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1301
+#: src/data/sys-file-reader.c:1467
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1340
+#: src/data/sys-file-reader.c:1506
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1516
+#: src/data/sys-file-reader.c:1682
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
 
-#: src/data/sys-file-writer.c:139
+#: src/data/sys-file-writer.c:175
 #, c-format
 msgid "Unknown system file version %d. Treating as version %d."
 msgstr ""
 
 #, c-format
 msgid "Unknown system file version %d. Treating as version %d."
 msgstr ""
 
-#: src/data/sys-file-writer.c:248
+#: src/data/sys-file-writer.c:326
 #, c-format
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-writer.c:895
+#: src/data/sys-file-writer.c:1046
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
@@ -968,87 +973,91 @@ msgstr ""
 msgid "scratch"
 msgstr ""
 
 msgid "scratch"
 msgstr ""
 
-#: src/language/command.c:159
+#: src/data/variable.c:387
+msgid "Expected a space in very long string"
+msgstr ""
+
+#: src/language/command.c:171
 #, c-format
 msgid "%s may be used only in testing mode."
 msgstr ""
 
 #, c-format
 msgid "%s may be used only in testing mode."
 msgstr ""
 
-#: src/language/command.c:164
+#: src/language/command.c:176
 #, c-format
 msgid "%s may be used only in enhanced syntax mode."
 msgstr ""
 
 #, c-format
 msgid "%s may be used only in enhanced syntax mode."
 msgstr ""
 
-#: src/language/command.c:414
+#: src/language/command.c:427
 msgid "expecting command name"
 msgstr ""
 
 msgid "expecting command name"
 msgstr ""
 
-#: src/language/command.c:428
+#: src/language/command.c:441
 #, c-format
 msgid "Unknown command %s."
 msgstr ""
 
 #, c-format
 msgid "Unknown command %s."
 msgstr ""
 
-#: src/language/command.c:550
+#: src/language/command.c:563
 msgid "before the active file has been defined"
 msgstr ""
 
 msgid "before the active file has been defined"
 msgstr ""
 
-#: src/language/command.c:552
+#: src/language/command.c:565
 msgid "after the active file has been defined"
 msgstr ""
 
 msgid "after the active file has been defined"
 msgstr ""
 
-#: src/language/command.c:554
+#: src/language/command.c:567
 msgid "inside INPUT PROGRAM"
 msgstr ""
 
 msgid "inside INPUT PROGRAM"
 msgstr ""
 
-#: src/language/command.c:556
+#: src/language/command.c:569
 msgid "inside FILE TYPE"
 msgstr ""
 
 msgid "inside FILE TYPE"
 msgstr ""
 
-#: src/language/command.c:561
+#: src/language/command.c:574
 #, c-format
 msgid "%s or %s"
 msgstr ""
 
 #, c-format
 msgid "%s or %s"
 msgstr ""
 
-#: src/language/command.c:563
+#: src/language/command.c:576
 #, c-format
 msgid "%s, %s, or %s"
 msgstr ""
 
 #, c-format
 msgid "%s, %s, or %s"
 msgstr ""
 
-#: src/language/command.c:567
+#: src/language/command.c:580
 #, c-format
 msgid "%s is allowed only %s."
 msgstr ""
 
 #, c-format
 msgid "%s is allowed only %s."
 msgstr ""
 
-#: src/language/command.c:572
+#: src/language/command.c:585
 #, c-format
 msgid "%s is not allowed inside INPUT PROGRAM."
 msgstr ""
 
 #, c-format
 msgid "%s is not allowed inside INPUT PROGRAM."
 msgstr ""
 
-#: src/language/command.c:574
+#: src/language/command.c:587
 #, c-format
 msgid "%s is not allowed inside FILE TYPE."
 msgstr ""
 
 #, c-format
 msgid "%s is not allowed inside FILE TYPE."
 msgstr ""
 
-#: src/language/command.c:666 src/language/command.c:797
+#: src/language/command.c:679 src/language/command.c:810
 #: src/language/utilities/permissions.c:102
 msgid "This command not allowed when the SAFER option is set."
 msgstr ""
 
 #: src/language/utilities/permissions.c:102
 msgid "This command not allowed when the SAFER option is set."
 msgstr ""
 
-#: src/language/command.c:678
+#: src/language/command.c:691
 #, c-format
 msgid "Error removing `%s': %s."
 msgstr ""
 
 #, c-format
 msgid "Error removing `%s': %s."
 msgstr ""
 
-#: src/language/command.c:728
+#: src/language/command.c:741
 #, c-format
 msgid "Couldn't fork: %s."
 msgstr ""
 
 #, c-format
 msgid "Couldn't fork: %s."
 msgstr ""
 
-#: src/language/command.c:770
+#: src/language/command.c:783
 #, c-format
 msgid "Error executing command: %s."
 msgstr ""
 
 #, c-format
 msgid "Error executing command: %s."
 msgstr ""
 
-#: src/language/command.c:779 src/language/data-io/matrix-data.c:532
+#: src/language/command.c:792 src/language/data-io/matrix-data.c:535
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1038
 #: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1038
 #: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
@@ -1056,7 +1065,7 @@ msgstr ""
 msgid "expecting end of command"
 msgstr ""
 
 msgid "expecting end of command"
 msgstr ""
 
-#: src/language/command.c:818
+#: src/language/command.c:831
 msgid "No operating system support for this command."
 msgstr ""
 
 msgid "No operating system support for this command."
 msgstr ""
 
@@ -1114,283 +1123,147 @@ msgid ""
 "commands."
 msgstr ""
 
 "commands."
 msgstr ""
 
-#: src/language/data-io/data-list.c:145
-msgid "DATA LIST must use the same file as the enclosing FILE TYPE."
-msgstr ""
-
-#: src/language/data-io/data-list.c:164
+#: src/language/data-io/data-list.c:149
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
-#: src/language/data-io/data-list.c:199
+#: src/language/data-io/data-list.c:184
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
-#: src/language/data-io/data-list.c:349 src/language/data-io/print.c:297
+#: src/language/data-io/data-list.c:334 src/language/data-io/print.c:297
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/language/data-io/data-list.c:378 src/language/data-io/data-list.c:1729
+#: src/language/data-io/data-list.c:363
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
-#: src/language/data-io/data-list.c:389
+#: src/language/data-io/data-list.c:374
 msgid "At least one variable must be specified."
 msgstr ""
 
 msgid "At least one variable must be specified."
 msgstr ""
 
-#: src/language/data-io/data-list.c:394 src/language/data-io/print.c:329
+#: src/language/data-io/data-list.c:379 src/language/data-io/print.c:329
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
-#: src/language/data-io/data-list.c:427 src/language/data-io/data-list.c:441
+#: src/language/data-io/data-list.c:412 src/language/data-io/data-list.c:426
 #: src/language/data-io/print.c:521 src/language/data-io/print.c:534
 msgid "Column positions for fields must be positive."
 msgstr ""
 
 #: src/language/data-io/print.c:521 src/language/data-io/print.c:534
 msgid "Column positions for fields must be positive."
 msgstr ""
 
-#: src/language/data-io/data-list.c:446
+#: src/language/data-io/data-list.c:431
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
-#: src/language/data-io/data-list.c:460
+#: src/language/data-io/data-list.c:445
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
-#: src/language/data-io/data-list.c:480 src/language/data-io/print.c:562
+#: src/language/data-io/data-list.c:465 src/language/data-io/print.c:562
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
-#: src/language/data-io/data-list.c:495 src/language/data-io/print.c:578
+#: src/language/data-io/data-list.c:480 src/language/data-io/print.c:578
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
-#: src/language/data-io/data-list.c:509 src/language/data-io/print.c:591
+#: src/language/data-io/data-list.c:494 src/language/data-io/print.c:591
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
-#: src/language/data-io/data-list.c:556 src/language/data-io/data-list.c:652
-#: src/language/data-io/data-list.c:860
+#: src/language/data-io/data-list.c:539 src/language/data-io/data-list.c:635
+#: src/language/data-io/data-list.c:840
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
-#: src/language/data-io/data-list.c:561
+#: src/language/data-io/data-list.c:544
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
-#: src/language/data-io/data-list.c:568
+#: src/language/data-io/data-list.c:551
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
-#: src/language/data-io/data-list.c:643
+#: src/language/data-io/data-list.c:626
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
-#: src/language/data-io/data-list.c:756 src/language/data-io/print.c:767
+#: src/language/data-io/data-list.c:736 src/language/data-io/print.c:767
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
-#: src/language/data-io/data-list.c:783 src/language/data-io/data-list.c:901
+#: src/language/data-io/data-list.c:763 src/language/data-io/data-list.c:878
 #: src/language/data-io/print.c:798
 #: src/language/dictionary/sys-file-info.c:140
 #: src/language/dictionary/sys-file-info.c:374
 #: src/language/data-io/print.c:798
 #: src/language/dictionary/sys-file-info.c:140
 #: src/language/dictionary/sys-file-info.c:374
-#: src/language/stats/descriptives.c:887 src/procedure.c:878
+#: src/language/stats/descriptives.c:886 src/procedure.c:678
 msgid "Variable"
 msgstr ""
 
 msgid "Variable"
 msgstr ""
 
-#: src/language/data-io/data-list.c:784 src/language/data-io/print.c:799
+#: src/language/data-io/data-list.c:764 src/language/data-io/print.c:799
 msgid "Record"
 msgstr ""
 
 msgid "Record"
 msgstr ""
 
-#: src/language/data-io/data-list.c:785 src/language/data-io/print.c:800
+#: src/language/data-io/data-list.c:765 src/language/data-io/print.c:800
 #: src/ui/gui/var-sheet.c:74
 msgid "Columns"
 msgstr ""
 
 #: src/ui/gui/var-sheet.c:74
 msgid "Columns"
 msgstr ""
 
-#: src/language/data-io/data-list.c:786 src/language/data-io/data-list.c:902
+#: src/language/data-io/data-list.c:766 src/language/data-io/data-list.c:879
 #: src/language/data-io/print.c:801
 msgid "Format"
 msgstr ""
 
 #: src/language/data-io/print.c:801
 msgid "Format"
 msgstr ""
 
-#: src/language/data-io/data-list.c:801
+#: src/language/data-io/data-list.c:781
 #, c-format
 msgid "Reading %d record from %s."
 msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
 #, c-format
 msgid "Reading %d record from %s."
 msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/language/data-io/data-list.c:917
+#: src/language/data-io/data-list.c:894
 #, c-format
 msgid "Reading free-form data from %s."
 msgstr ""
 
 #, c-format
 msgid "Reading free-form data from %s."
 msgstr ""
 
-#: src/language/data-io/data-list.c:968
+#: src/language/data-io/data-list.c:945
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1083
+#: src/language/data-io/data-list.c:1060
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1136
+#: src/language/data-io/data-list.c:1113
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1179
+#: src/language/data-io/data-list.c:1156
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1392
-msgid ""
-"REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
-"TYPE."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1402 src/language/data-io/data-list.c:1436
-#: src/language/data-io/data-list.c:1449 src/language/data-io/data-list.c:1462
-#: src/language/data-io/data-list.c:1496
-#, c-format
-msgid "%s subcommand given multiple times."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1425
-#, c-format
-msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1482
-#, c-format
-msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1505
-#, c-format
-msgid "ID beginning column (%ld) must be positive."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1520
-#, c-format
-msgid "ID ending column (%ld) must be positive."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1526
-#, c-format
-msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1566
-msgid "Missing required specification STARTS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1568
-msgid "Missing required specification OCCURS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1575
-msgid "ID specified without CONTINUED."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1586
-#, c-format
-msgid ""
-"STARTS beginning column (%d) exceeds default STARTS ending column taken from "
-"file's record width (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1599
-#, c-format
-msgid ""
-"CONTINUED beginning column (%d) exceeds default CONTINUED ending column "
-"taken from file's record width (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1678
-msgid "String variable not allowed here."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1688
-#, c-format
-msgid "%s (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1694
-#, c-format
-msgid "Variable or integer expected for %s."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1819
-#, c-format
-msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1852
-#, c-format
-msgid ""
-"Variable %s starting in column %d extends beyond physical record length of %"
-"d."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1919
-#, c-format
-msgid "Invalid value %d for OCCURS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1925
-#, c-format
-msgid "Beginning column for STARTS (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1932
-#, c-format
-msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1940
-#, c-format
-msgid "Invalid value %d for LENGTH."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1947
-#, c-format
-msgid "Beginning column for CONTINUED (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1955
-#, c-format
-msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1987
-#, c-format
-msgid ""
-"Number of repetitions specified on OCCURS (%d) exceed number of repetitions "
-"available in space on STARTS (%d), and CONTINUED not specified."
-msgstr ""
-
-#: src/language/data-io/data-list.c:2005
-#, c-format
-msgid "Unexpected end of file with %d repetitions remaining out of %d."
-msgstr ""
-
 #: src/language/data-io/data-reader.c:131
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
 #: src/language/data-io/data-reader.c:131
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
@@ -1481,154 +1354,21 @@ msgstr ""
 msgid "Handle for %s not allowed here."
 msgstr ""
 
 msgid "Handle for %s not allowed here."
 msgstr ""
 
-#: src/language/data-io/file-type.c:149
-msgid "MIXED, GROUPED, or NESTED expected."
-msgstr ""
-
-#: src/language/data-io/file-type.c:172
-msgid "The CASE subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:190
-msgid "WARN or NOWARN expected after WILD."
-msgstr ""
-
-#: src/language/data-io/file-type.c:198
-msgid "The DUPLICATE subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:212
-msgid "DUPLICATE=CASE is only valid on FILE TYPE NESTED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:221
-#, c-format
-msgid "WARN%s expected after DUPLICATE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:222
-msgid ", NOWARN, or CASE"
-msgstr ""
-
-#: src/language/data-io/file-type.c:223
-msgid " or NOWARN"
-msgstr ""
-
-#: src/language/data-io/file-type.c:231
-msgid "The MISSING subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:243
-msgid "WARN or NOWARN after MISSING."
-msgstr ""
-
-#: src/language/data-io/file-type.c:251
-msgid "ORDERED is only valid on FILE TYPE GROUPED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:262
-msgid "YES or NO expected after ORDERED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:268 src/language/data-io/file-type.c:554
-msgid "while expecting a valid subcommand"
-msgstr ""
-
-#: src/language/data-io/file-type.c:275
-msgid "The required RECORD subcommand was not present."
-msgstr ""
-
-#: src/language/data-io/file-type.c:283
-msgid "The required CASE subcommand was not present."
-msgstr ""
-
-#: src/language/data-io/file-type.c:289
-msgid "CASE and RECORD must specify different variable names."
-msgstr ""
-
-#: src/language/data-io/file-type.c:347
-msgid "Column value must be positive."
-msgstr ""
-
-#: src/language/data-io/file-type.c:363
-msgid "Ending column precedes beginning column."
-msgstr ""
-
-#: src/language/data-io/file-type.c:383
-msgid "Bad format specifier name."
-msgstr ""
-
-#: src/language/data-io/file-type.c:426
-msgid "OTHER may appear only on the last RECORD TYPE command."
-msgstr ""
-
-#: src/language/data-io/file-type.c:436
-msgid "No input commands (DATA LIST, REPEATING DATA) for above RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:487
-msgid ""
-"The CASE subcommand is not allowed on the RECORD TYPE command for FILE TYPE "
-"MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:497
-msgid ""
-"No variable name may be specified for the CASE subcommand on RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:505
-msgid ""
-"The CASE column specification on RECORD TYPE must give a format specifier "
-"that is the same type as that of the CASE column specification given on FILE "
-"TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:521
-msgid "WARN or NOWARN expected on DUPLICATE subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:535
-msgid "WARN or NOWARN expected on MISSING subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:548
-msgid "YES or NO expected on SPREAD subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:598
-msgid "No input commands (DATA LIST, REPEATING DATA) on above RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:605
-msgid "No commands between FILE TYPE and END FILE TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:674
-#, c-format
-msgid "Unknown record type \"%.*s\"."
-msgstr ""
-
-#: src/language/data-io/file-type.c:698
-#, c-format
-msgid "Unknown record type %g."
-msgstr ""
-
-#: src/language/data-io/get.c:106
+#: src/language/data-io/get.c:111
 msgid "expecting COMM or TAPE"
 msgstr ""
 
 msgid "expecting COMM or TAPE"
 msgstr ""
 
-#: src/language/data-io/get.c:348 src/language/data-io/get.c:362
-#: src/language/data-io/get.c:387
+#: src/language/data-io/get.c:353 src/language/data-io/get.c:367
+#: src/language/data-io/get.c:392
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
-#: src/language/data-io/get.c:594 src/language/data-io/print.c:180
+#: src/language/data-io/get.c:599 src/language/data-io/print.c:180
 msgid "expecting a valid subcommand"
 msgstr ""
 
 msgid "expecting a valid subcommand"
 msgstr ""
 
-#: src/language/data-io/get.c:627
+#: src/language/data-io/get.c:632
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
@@ -1636,96 +1376,94 @@ msgid ""
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
-#: src/language/data-io/get.c:652
+#: src/language/data-io/get.c:657
 msgid "`=' expected after variable list."
 msgstr ""
 
 msgid "`=' expected after variable list."
 msgstr ""
 
-#: src/language/data-io/get.c:659
+#: src/language/data-io/get.c:664
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
-#: src/language/data-io/get.c:672
+#: src/language/data-io/get.c:677
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
-#: src/language/data-io/get.c:702
+#: src/language/data-io/get.c:707
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
-#: src/language/data-io/get.c:879
+#: src/language/data-io/get.c:884
 msgid "The active file may not be specified more than once."
 msgstr ""
 
 msgid "The active file may not be specified more than once."
 msgstr ""
 
-#: src/language/data-io/get.c:887
+#: src/language/data-io/get.c:892
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
-#: src/language/data-io/get.c:895
+#: src/language/data-io/get.c:900
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/language/data-io/get.c:933
+#: src/language/data-io/get.c:938
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
-#: src/language/data-io/get.c:953
+#: src/language/data-io/get.c:958
 msgid "BY may appear at most once."
 msgstr ""
 
 msgid "BY may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:973
+#: src/language/data-io/get.c:978
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
-#: src/language/data-io/get.c:987
+#: src/language/data-io/get.c:992
 msgid "FIRST may appear at most once."
 msgstr ""
 
 msgid "FIRST may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:1001
+#: src/language/data-io/get.c:1006
 msgid "LAST may appear at most once."
 msgstr ""
 
 msgid "LAST may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:1042
+#: src/language/data-io/get.c:1047
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
-#: src/language/data-io/get.c:1047
+#: src/language/data-io/get.c:1052
 msgid "BY is required when IN is specified."
 msgstr ""
 
 msgid "BY is required when IN is specified."
 msgstr ""
 
-#: src/language/data-io/get.c:1075
+#: src/language/data-io/get.c:1080
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
-#: src/language/data-io/get.c:1530
+#: src/language/data-io/get.c:1535
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:98
+#: src/language/data-io/inpt-pgm.c:131
 msgid "Unexpected end-of-file within INPUT PROGRAM."
 msgstr ""
 
 msgid "Unexpected end-of-file within INPUT PROGRAM."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:107
-msgid ""
-"No data-input or transformation commands specified between INPUT PROGRAM and "
-"END INPUT PROGRAM."
+#: src/language/data-io/inpt-pgm.c:144
+msgid "Input program did not create any variables."
 msgstr ""
 
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:354
+#: src/language/data-io/inpt-pgm.c:361
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:402
+#: src/language/data-io/inpt-pgm.c:409
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
@@ -1766,183 +1504,183 @@ msgstr ""
 msgid "Line"
 msgstr ""
 
 msgid "Line"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:211
+#: src/language/data-io/matrix-data.c:214
 msgid "VARIABLES subcommand multiply specified."
 msgstr ""
 
 msgid "VARIABLES subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:226
+#: src/language/data-io/matrix-data.c:229
 msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
 msgstr ""
 
 msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:287
+#: src/language/data-io/matrix-data.c:290
 msgid "in FORMAT subcommand"
 msgstr ""
 
 msgid "in FORMAT subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:298
+#: src/language/data-io/matrix-data.c:301
 msgid "SPLIT subcommand multiply specified."
 msgstr ""
 
 msgid "SPLIT subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:305
+#: src/language/data-io/matrix-data.c:308
 msgid "in SPLIT subcommand"
 msgstr ""
 
 msgid "in SPLIT subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:315
+#: src/language/data-io/matrix-data.c:318
 msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
 msgstr ""
 
 msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:349
+#: src/language/data-io/matrix-data.c:352
 #, c-format
 msgid "Split variable %s is already another type."
 msgstr ""
 
 #, c-format
 msgid "Split variable %s is already another type."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:364
+#: src/language/data-io/matrix-data.c:367
 msgid "FACTORS subcommand multiply specified."
 msgstr ""
 
 msgid "FACTORS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:383
+#: src/language/data-io/matrix-data.c:386
 #, c-format
 msgid "Factor variable %s is already another type."
 msgstr ""
 
 #, c-format
 msgid "Factor variable %s is already another type."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:398
+#: src/language/data-io/matrix-data.c:401
 msgid "CELLS subcommand multiply specified."
 msgstr ""
 
 msgid "CELLS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:404
-#: src/language/data-io/matrix-data.c:423
+#: src/language/data-io/matrix-data.c:407
+#: src/language/data-io/matrix-data.c:426
 msgid "expecting positive integer"
 msgstr ""
 
 msgid "expecting positive integer"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:417
+#: src/language/data-io/matrix-data.c:420
 msgid "N subcommand multiply specified."
 msgstr ""
 
 msgid "N subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:438
+#: src/language/data-io/matrix-data.c:441
 msgid "CONTENTS subcommand multiply specified."
 msgstr ""
 
 msgid "CONTENTS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:458
+#: src/language/data-io/matrix-data.c:461
 msgid "Nested parentheses not allowed."
 msgstr ""
 
 msgid "Nested parentheses not allowed."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:468
+#: src/language/data-io/matrix-data.c:471
 msgid "Mismatched right parenthesis (`(')."
 msgstr ""
 
 msgid "Mismatched right parenthesis (`(')."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:473
+#: src/language/data-io/matrix-data.c:476
 msgid "Empty parentheses not allowed."
 msgstr ""
 
 msgid "Empty parentheses not allowed."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:486
-#: src/language/data-io/matrix-data.c:494
+#: src/language/data-io/matrix-data.c:489
+#: src/language/data-io/matrix-data.c:497
 msgid "in CONTENTS subcommand"
 msgstr ""
 
 msgid "in CONTENTS subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:501
+#: src/language/data-io/matrix-data.c:504
 #, c-format
 msgid "Content multiply specified for %s."
 msgstr ""
 
 #, c-format
 msgid "Content multiply specified for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:518
+#: src/language/data-io/matrix-data.c:521
 msgid "Missing right parenthesis."
 msgstr ""
 
 msgid "Missing right parenthesis."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:538
+#: src/language/data-io/matrix-data.c:541
 msgid "Missing VARIABLES subcommand."
 msgstr ""
 
 msgid "Missing VARIABLES subcommand."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:544
+#: src/language/data-io/matrix-data.c:547
 msgid ""
 "CONTENTS subcommand not specified: assuming file contains only CORR matrix."
 msgstr ""
 
 msgid ""
 "CONTENTS subcommand not specified: assuming file contains only CORR matrix."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:554
+#: src/language/data-io/matrix-data.c:557
 msgid ""
 "Missing CELLS subcommand.  CELLS is required when ROWTYPE_ is not given in "
 "the data and factors are present."
 msgstr ""
 
 msgid ""
 "Missing CELLS subcommand.  CELLS is required when ROWTYPE_ is not given in "
 "the data and factors are present."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:562
+#: src/language/data-io/matrix-data.c:565
 msgid "Split file values must be present in the data when ROWTYPE_ is present."
 msgstr ""
 
 msgid "Split file values must be present in the data when ROWTYPE_ is present."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:615
+#: src/language/data-io/matrix-data.c:618
 msgid "No continuous variables specified."
 msgstr ""
 
 msgid "No continuous variables specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:858
+#: src/language/data-io/matrix-data.c:861
 msgid "Scope of string exceeds line."
 msgstr ""
 
 msgid "Scope of string exceeds line."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:923
+#: src/language/data-io/matrix-data.c:926
 #, c-format
 msgid "End of line expected %s while reading %s."
 msgstr ""
 
 #, c-format
 msgid "End of line expected %s while reading %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1113
+#: src/language/data-io/matrix-data.c:1116
 #, c-format
 msgid "expecting value for %s %s"
 msgstr ""
 
 #, c-format
 msgid "expecting value for %s %s"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1278
+#: src/language/data-io/matrix-data.c:1281
 #, c-format
 msgid "Syntax error expecting SPLIT FILE value %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting SPLIT FILE value %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1287
+#: src/language/data-io/matrix-data.c:1290
 #, c-format
 msgid "Expecting value %g for %s."
 msgstr ""
 
 #, c-format
 msgid "Expecting value %g for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1328
-#: src/language/data-io/matrix-data.c:1805
+#: src/language/data-io/matrix-data.c:1331
+#: src/language/data-io/matrix-data.c:1808
 #, c-format
 msgid "Syntax error expecting factor value %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting factor value %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1337
+#: src/language/data-io/matrix-data.c:1340
 #, c-format
 msgid "Syntax error expecting value %g for %s %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting value %g for %s %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1581
+#: src/language/data-io/matrix-data.c:1584
 #, c-format
 msgid "Syntax error %s expecting SPLIT FILE value."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s expecting SPLIT FILE value."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1710
+#: src/language/data-io/matrix-data.c:1713
 #, c-format
 msgid ""
 "Expected %d lines of data for %s content; actually saw %d lines.  No data "
 "will be output for this content."
 msgstr ""
 
 #, c-format
 msgid ""
 "Expected %d lines of data for %s content; actually saw %d lines.  No data "
 "will be output for this content."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1747
+#: src/language/data-io/matrix-data.c:1750
 #, c-format
 msgid "Multiply specified ROWTYPE_ %s."
 msgstr ""
 
 #, c-format
 msgid "Multiply specified ROWTYPE_ %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1752
+#: src/language/data-io/matrix-data.c:1755
 #, c-format
 msgid "Syntax error %s expecting ROWTYPE_ string."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s expecting ROWTYPE_ string."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1772
+#: src/language/data-io/matrix-data.c:1775
 #, c-format
 msgid "Syntax error %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1923
+#: src/language/data-io/matrix-data.c:1926
 #, c-format
 msgid "Duplicate specification for %s."
 msgstr ""
 
 #, c-format
 msgid "Duplicate specification for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1935
+#: src/language/data-io/matrix-data.c:1938
 #, c-format
 msgid "Too many rows of matrix data for %s."
 msgstr ""
 
 #, c-format
 msgid "Too many rows of matrix data for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1981
+#: src/language/data-io/matrix-data.c:1984
 #, c-format
 msgid "Syntax error expecting value for %s %s."
 msgstr ""
 #, c-format
 msgid "Syntax error expecting value for %s %s."
 msgstr ""
@@ -2045,7 +1783,7 @@ msgid "`)' expected after output format."
 msgstr ""
 
 #: src/language/dictionary/missing-values.c:53
 msgstr ""
 
 #: src/language/dictionary/missing-values.c:53
-#: src/language/stats/aggregate.c:434
+#: src/language/stats/aggregate.c:438
 msgid "expecting `('"
 msgstr ""
 
 msgid "expecting `('"
 msgstr ""
 
@@ -2288,7 +2026,7 @@ msgid "Documents in the active file:"
 msgstr ""
 
 #: src/language/dictionary/sys-file-info.c:381
 msgstr ""
 
 #: src/language/dictionary/sys-file-info.c:381
-#: src/language/dictionary/sys-file-info.c:520 src/procedure.c:880
+#: src/language/dictionary/sys-file-info.c:520 src/procedure.c:680
 #: src/ui/gui/var-sheet.c:71
 msgid "Label"
 msgstr ""
 #: src/ui/gui/var-sheet.c:71
 msgid "Label"
 msgstr ""
@@ -2316,7 +2054,7 @@ msgstr ""
 #: src/language/stats/crosstabs.q:1109 src/language/stats/crosstabs.q:1136
 #: src/language/stats/crosstabs.q:1156 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1141 src/language/stats/frequencies.q:1145
 #: src/language/stats/crosstabs.q:1109 src/language/stats/crosstabs.q:1136
 #: src/language/stats/crosstabs.q:1156 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1141 src/language/stats/frequencies.q:1145
-#: src/language/stats/frequencies.q:1266 src/procedure.c:879
+#: src/language/stats/frequencies.q:1266 src/procedure.c:679
 msgid "Value"
 msgstr ""
 
 msgid "Value"
 msgstr ""
 
@@ -2399,7 +2137,7 @@ msgstr ""
 msgid "The weighting variable may not be scratch."
 msgstr ""
 
 msgid "The weighting variable may not be scratch."
 msgstr ""
 
-#: src/language/expressions/evaluate.c:144
+#: src/language/expressions/evaluate.c:147
 msgid "expecting number or string"
 msgstr ""
 
 msgid "expecting number or string"
 msgstr ""
 
@@ -2481,7 +2219,7 @@ msgstr ""
 msgid "Unknown identifier %s."
 msgstr ""
 
 msgid "Unknown identifier %s."
 msgstr ""
 
-#: src/language/expressions/parse.c:846 src/language/stats/aggregate.c:490
+#: src/language/expressions/parse.c:846 src/language/stats/aggregate.c:494
 msgid "expecting `)'"
 msgstr ""
 
 msgid "expecting `)'"
 msgstr ""
 
@@ -2555,6 +2293,11 @@ msgstr ""
 msgid "%s is not yet implemented."
 msgstr ""
 
 msgid "%s is not yet implemented."
 msgstr ""
 
+#: src/language/expressions/parse.c:1227
+#, c-format
+msgid "%s may not appear after TEMPORARY."
+msgstr ""
+
 #: src/language/lexer/format-parser.c:66
 msgid "X and T format specifiers not allowed here."
 msgstr ""
 #: src/language/lexer/format-parser.c:66
 msgid "X and T format specifiers not allowed here."
 msgstr ""
@@ -2573,7 +2316,12 @@ msgstr ""
 msgid "Data format %s does not specify a width."
 msgstr ""
 
 msgid "Data format %s does not specify a width."
 msgstr ""
 
-#: src/language/lexer/format-parser.c:145
+#: src/language/lexer/format-parser.c:133
+#, c-format
+msgid "String variable width may not exceed %d"
+msgstr ""
+
+#: src/language/lexer/format-parser.c:150
 #, c-format
 msgid "Data format %s is not valid."
 msgstr ""
 #, c-format
 msgid "Data format %s is not valid."
 msgstr ""
@@ -2791,54 +2539,54 @@ msgstr ""
 msgid "Reading `%s': %s."
 msgstr ""
 
 msgid "Reading `%s': %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:200
+#: src/language/stats/aggregate.c:204
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
-#: src/language/stats/aggregate.c:229
+#: src/language/stats/aggregate.c:233
 msgid "expecting BREAK"
 msgstr ""
 
 msgid "expecting BREAK"
 msgstr ""
 
-#: src/language/stats/aggregate.c:234
+#: src/language/stats/aggregate.c:238
 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 ""
 
 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:403
+#: src/language/stats/aggregate.c:407
 msgid "expecting aggregation function"
 msgstr ""
 
 msgid "expecting aggregation function"
 msgstr ""
 
-#: src/language/stats/aggregate.c:419
+#: src/language/stats/aggregate.c:423
 #, c-format
 msgid "Unknown aggregation function %s."
 msgstr ""
 
 #, c-format
 msgid "Unknown aggregation function %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:471
+#: src/language/stats/aggregate.c:475
 #, c-format
 msgid "Missing argument %d to %s."
 msgstr ""
 
 #, c-format
 msgid "Missing argument %d to %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:480
+#: src/language/stats/aggregate.c:484
 #, c-format
 msgid "Arguments to %s must be of same type as source variables."
 msgstr ""
 
 #, c-format
 msgid "Arguments to %s must be of same type as source variables."
 msgstr ""
 
-#: src/language/stats/aggregate.c:502
+#: src/language/stats/aggregate.c:506
 #, c-format
 msgid ""
 "Number of source variables (%u) does not match number of target variables (%"
 "u)."
 msgstr ""
 
 #, c-format
 msgid ""
 "Number of source variables (%u) does not match number of target variables (%"
 "u)."
 msgstr ""
 
-#: src/language/stats/aggregate.c:518
+#: src/language/stats/aggregate.c:522
 #, 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 ""
 
 #, 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:585
+#: src/language/stats/aggregate.c:589
 #, c-format
 msgid ""
 "Variable name %s is not unique within the aggregate file dictionary, which "
 #, c-format
 msgid ""
 "Variable name %s is not unique within the aggregate file dictionary, which "
@@ -3247,19 +2995,19 @@ msgstr ""
 msgid "Target"
 msgstr ""
 
 msgid "Target"
 msgstr ""
 
-#: src/language/stats/descriptives.c:668 src/language/stats/descriptives.c:674
+#: src/language/stats/descriptives.c:667 src/language/stats/descriptives.c:673
 msgid "Z-score of "
 msgstr ""
 
 msgid "Z-score of "
 msgstr ""
 
-#: src/language/stats/descriptives.c:890
+#: src/language/stats/descriptives.c:889
 msgid "Valid N"
 msgstr ""
 
 msgid "Valid N"
 msgstr ""
 
-#: src/language/stats/descriptives.c:891
+#: src/language/stats/descriptives.c:890
 msgid "Missing N"
 msgstr ""
 
 msgid "Missing N"
 msgstr ""
 
-#: src/language/stats/descriptives.c:918
+#: src/language/stats/descriptives.c:917
 #, c-format
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
 #, c-format
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
@@ -3370,64 +3118,64 @@ msgstr ""
 msgid "Tukey's Hinges"
 msgstr ""
 
 msgid "Tukey's Hinges"
 msgstr ""
 
-#: src/language/stats/flip.c:94
+#: src/language/stats/flip.c:98
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
 msgstr ""
 
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/language/stats/flip.c:237
+#: src/language/stats/flip.c:241
 #, c-format
 msgid "Could not create acceptable variant for variable %s."
 msgstr ""
 
 #, c-format
 msgid "Could not create acceptable variant for variable %s."
 msgstr ""
 
-#: src/language/stats/flip.c:253
+#: src/language/stats/flip.c:257
 msgid "Cannot create more than 99999 variable names."
 msgstr ""
 
 msgid "Cannot create more than 99999 variable names."
 msgstr ""
 
-#: src/language/stats/flip.c:290
+#: src/language/stats/flip.c:294
 msgid "Could not create temporary file for FLIP."
 msgstr ""
 
 msgid "Could not create temporary file for FLIP."
 msgstr ""
 
-#: src/language/stats/flip.c:301 src/language/stats/flip.c:367
+#: src/language/stats/flip.c:305 src/language/stats/flip.c:371
 #, c-format
 msgid "Error writing FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:414
+#: src/language/stats/flip.c:418
 #, c-format
 msgid "Error rewinding FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error rewinding FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:421
+#: src/language/stats/flip.c:425
 msgid "Error creating FLIP source file."
 msgstr ""
 
 msgid "Error creating FLIP source file."
 msgstr ""
 
-#: src/language/stats/flip.c:433
+#: src/language/stats/flip.c:437
 #, c-format
 msgid "Error reading FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error reading FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:457
+#: src/language/stats/flip.c:461
 #, c-format
 msgid "Error seeking FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error seeking FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:465
+#: src/language/stats/flip.c:469
 #, c-format
 msgid "Error writing FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:480
+#: src/language/stats/flip.c:484
 #, c-format
 msgid "Error rewinding FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error rewinding FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:528
+#: src/language/stats/flip.c:532
 #, c-format
 msgid "Error reading FLIP temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error reading FLIP temporary file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:531
+#: src/language/stats/flip.c:535
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
@@ -3684,7 +3432,7 @@ msgstr ""
 msgid "Coefficient Correlations"
 msgstr ""
 
 msgid "Coefficient Correlations"
 msgstr ""
 
-#: src/language/stats/regression.q:1157
+#: src/language/stats/regression.q:1104
 msgid "Dependent variable must be numeric."
 msgstr ""
 
 msgid "Dependent variable must be numeric."
 msgstr ""
 
@@ -4098,7 +3846,7 @@ msgstr ""
 msgid "Empirical with averaging"
 msgstr ""
 
 msgid "Empirical with averaging"
 msgstr ""
 
-#: src/math/sort.c:430
+#: src/math/sort.c:432
 #, c-format
 msgid ""
 "Out of memory.  Could not allocate room for minimum of %d cases of %d bytes "
 #, c-format
 msgid ""
 "Out of memory.  Could not allocate room for minimum of %d cases of %d bytes "
@@ -4684,6 +4432,28 @@ msgid ""
 "failures."
 msgstr ""
 
 "failures."
 msgstr ""
 
+#: src/ui/terminal/msg-ui.c:61
+msgid "Terminating execution of syntax file due to error."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:63
+#, c-format
+msgid "Errors (%d) exceeds limit (%d)."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:66
+#, c-format
+msgid "Warnings (%d) exceed limit (%d)."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:115
+msgid "error"
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:116
+msgid "warning"
+msgstr ""
+
 #~ msgid "Text color must be in range 0-15."
 #~ msgstr "Text colour must be in range 0-15."
 
 #~ msgid "Text color must be in range 0-15."
 #~ msgstr "Text colour must be in range 0-15."
 
index 592b3c2a3485d363bb93da9d632c391b61828d9d..5c5f4f1b1ec61e981e381ad28bbaad87d2a76f14 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2006-04-26 13:48-0700\n"
+"POT-Creation-Date: 2006-05-02 10:55+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -46,32 +46,32 @@ msgstr ""
 msgid "Date %04d-%d-%d is before the earliest acceptable date of 1582-10-15."
 msgstr ""
 
 msgid "Date %04d-%d-%d is before the earliest acceptable date of 1582-10-15."
 msgstr ""
 
-#: src/data/casefile.c:256
+#: src/data/casefile.c:258
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Removing temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:422
+#: src/data/casefile.c:424
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:571
+#: src/data/casefile.c:573
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Opening temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:597
+#: src/data/casefile.c:599
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Seeking temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:615
+#: src/data/casefile.c:617
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Reading temporary file: %s."
 msgstr ""
 
-#: src/data/casefile.c:618
+#: src/data/casefile.c:620
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
 #, c-format
 msgid "%s: Temporary file ended unexpectedly."
 msgstr ""
@@ -115,11 +115,11 @@ msgstr ""
 msgid "Unrecognized character in field."
 msgstr ""
 
 msgid "Unrecognized character in field."
 msgstr ""
 
-#: src/data/data-in.c:339 src/data/data-in.c:585
+#: src/data/data-in.c:339 src/data/data-in.c:589
 msgid "Field must have even length."
 msgstr ""
 
 msgid "Field must have even length."
 msgstr ""
 
-#: src/data/data-in.c:349 src/data/data-in.c:595
+#: src/data/data-in.c:349 src/data/data-in.c:599
 msgid "Field must contain only hex digits."
 msgstr ""
 
 msgid "Field must contain only hex digits."
 msgstr ""
 
@@ -146,104 +146,104 @@ msgstr ""
 msgid "Error in syntax of zoned decimal number."
 msgstr ""
 
 msgid "Error in syntax of zoned decimal number."
 msgstr ""
 
-#: src/data/data-in.c:635
+#: src/data/data-in.c:639
 msgid "Unexpected end of field."
 msgstr ""
 
 msgid "Unexpected end of field."
 msgstr ""
 
-#: src/data/data-in.c:661
+#: src/data/data-in.c:665
 msgid "Digit expected in field."
 msgstr ""
 
 msgid "Digit expected in field."
 msgstr ""
 
-#: src/data/data-in.c:686
+#: src/data/data-in.c:690
 #, c-format
 msgid "Day (%ld) must be between 1 and 31."
 msgstr ""
 
 #, c-format
 msgid "Day (%ld) must be between 1 and 31."
 msgstr ""
 
-#: src/data/data-in.c:711
+#: src/data/data-in.c:715
 msgid "Delimiter expected between fields in date."
 msgstr ""
 
 msgid "Delimiter expected between fields in date."
 msgstr ""
 
-#: src/data/data-in.c:744
+#: src/data/data-in.c:748
 #, c-format
 msgid "Parse error at `%c' expecting %s."
 msgstr ""
 
 #, c-format
 msgid "Parse error at `%c' expecting %s."
 msgstr ""
 
-#: src/data/data-in.c:758
+#: src/data/data-in.c:762
 #, c-format
 msgid "Unknown %s `%.*s'."
 msgstr ""
 
 #, c-format
 msgid "Unknown %s `%.*s'."
 msgstr ""
 
-#: src/data/data-in.c:808
+#: src/data/data-in.c:812
 #, c-format
 msgid "Month (%ld) must be between 1 and 12."
 msgstr ""
 
 #, c-format
 msgid "Month (%ld) must be between 1 and 12."
 msgstr ""
 
-#: src/data/data-in.c:812
+#: src/data/data-in.c:816
 msgid "month"
 msgstr ""
 
 msgid "month"
 msgstr ""
 
-#: src/data/data-in.c:826
+#: src/data/data-in.c:830
 #, c-format
 msgid "Year (%ld) must be between 1582 and 19999."
 msgstr ""
 
 #, c-format
 msgid "Year (%ld) must be between 1582 and 19999."
 msgstr ""
 
-#: src/data/data-in.c:837
+#: src/data/data-in.c:841
 #, c-format
 msgid "Trailing garbage \"%s\" following date."
 msgstr ""
 
 #, c-format
 msgid "Trailing garbage \"%s\" following date."
 msgstr ""
 
-#: src/data/data-in.c:852
+#: src/data/data-in.c:856
 #, c-format
 msgid "Julian day (%d) must be between 1 and 366."
 msgstr ""
 
 #, c-format
 msgid "Julian day (%d) must be between 1 and 366."
 msgstr ""
 
-#: src/data/data-in.c:864
+#: src/data/data-in.c:868
 #, c-format
 msgid "Year (%d) must be between 1582 and 19999."
 msgstr ""
 
 #, c-format
 msgid "Year (%d) must be between 1582 and 19999."
 msgstr ""
 
-#: src/data/data-in.c:880
+#: src/data/data-in.c:884
 #, c-format
 msgid "Quarter (%ld) must be between 1 and 4."
 msgstr ""
 
 #, c-format
 msgid "Quarter (%ld) must be between 1 and 4."
 msgstr ""
 
-#: src/data/data-in.c:890
+#: src/data/data-in.c:894
 msgid "`Q' expected between quarter and year."
 msgstr ""
 
 msgid "`Q' expected between quarter and year."
 msgstr ""
 
-#: src/data/data-in.c:906
+#: src/data/data-in.c:910
 #, c-format
 msgid "Week (%ld) must be between 1 and 53."
 msgstr ""
 
 #, c-format
 msgid "Week (%ld) must be between 1 and 53."
 msgstr ""
 
-#: src/data/data-in.c:918
+#: src/data/data-in.c:922
 msgid "`WK' expected between week and year."
 msgstr ""
 
 msgid "`WK' expected between week and year."
 msgstr ""
 
-#: src/data/data-in.c:941
+#: src/data/data-in.c:945
 msgid "Delimiter expected between fields in time."
 msgstr ""
 
 msgid "Delimiter expected between fields in time."
 msgstr ""
 
-#: src/data/data-in.c:953
+#: src/data/data-in.c:957
 #, c-format
 msgid "Hour (%ld) must be positive."
 msgstr ""
 
 #, c-format
 msgid "Hour (%ld) must be positive."
 msgstr ""
 
-#: src/data/data-in.c:965
+#: src/data/data-in.c:969
 #, c-format
 msgid "Minute (%ld) must be between 0 and 59."
 msgstr ""
 
 #, c-format
 msgid "Minute (%ld) must be between 0 and 59."
 msgstr ""
 
-#: src/data/data-in.c:1012
+#: src/data/data-in.c:1016
 #, c-format
 msgid "Hour (%ld) must be between 0 and 23."
 msgstr ""
 
 #, c-format
 msgid "Hour (%ld) must be between 0 and 23."
 msgstr ""
 
-#: src/data/data-in.c:1040
+#: src/data/data-in.c:1044
 msgid "weekday"
 msgstr ""
 
 msgid "weekday"
 msgstr ""
 
-#: src/data/data-in.c:1371
+#: src/data/data-in.c:1375
 #, c-format
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
 #, c-format
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
@@ -291,7 +291,7 @@ msgid ""
 "Year %d cannot be represented in four digits for output formatting purposes."
 msgstr ""
 
 "Year %d cannot be represented in four digits for output formatting purposes."
 msgstr ""
 
-#: src/data/dictionary.c:710
+#: src/data/dictionary.c:711
 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."
 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."
@@ -388,27 +388,27 @@ msgid "%s variables are not compatible with %s format %s."
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
-#: src/data/sys-file-reader.c:997 src/data/sys-file-reader.c:1006
+#: src/data/sys-file-reader.c:1162 src/data/sys-file-reader.c:1171
 #: src/ui/gui/psppire-var-store.c:435
 msgid "String"
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
 #: src/ui/gui/psppire-var-store.c:435
 msgid "String"
 msgstr ""
 
 #: src/data/format.c:197 src/data/por-file-reader.c:481
-#: src/data/sys-file-reader.c:997 src/data/sys-file-reader.c:1006
+#: src/data/sys-file-reader.c:1162 src/data/sys-file-reader.c:1171
 #: src/ui/gui/psppire-var-store.c:428
 msgid "Numeric"
 msgstr ""
 
 #: src/ui/gui/psppire-var-store.c:428
 msgid "Numeric"
 msgstr ""
 
-#: src/data/format.c:198 src/data/sys-file-reader.c:999
-#: src/data/sys-file-reader.c:1144 src/data/sys-file-reader.c:1145
+#: src/data/format.c:198 src/data/sys-file-reader.c:1164
+#: src/data/sys-file-reader.c:1309 src/data/sys-file-reader.c:1310
 #: src/data/variable.c:41 src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/language/xforms/recode.c:465 src/language/xforms/recode.c:466
 msgid "numeric"
 msgstr ""
 
 #: src/data/variable.c:41 src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/language/xforms/recode.c:465 src/language/xforms/recode.c:466
 msgid "numeric"
 msgstr ""
 
-#: src/data/format.c:198 src/data/sys-file-reader.c:999
-#: src/data/sys-file-reader.c:1144 src/data/sys-file-reader.c:1145
+#: src/data/format.c:198 src/data/sys-file-reader.c:1164
+#: src/data/sys-file-reader.c:1309 src/data/sys-file-reader.c:1310
 #: src/data/variable.c:41 src/data/variable.c:49
 #: src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
 #: src/data/variable.c:41 src/data/variable.c:49
 #: src/language/dictionary/apply-dictionary.c:73
 #: src/language/dictionary/apply-dictionary.c:74
@@ -478,12 +478,12 @@ msgstr ""
 msgid "Bad time string length %d."
 msgstr ""
 
 msgid "Bad time string length %d."
 msgstr ""
 
-#: src/data/por-file-reader.c:473 src/data/sys-file-reader.c:989
+#: src/data/por-file-reader.c:473 src/data/sys-file-reader.c:1154
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
-#: src/data/por-file-reader.c:480 src/data/sys-file-reader.c:1005
+#: src/data/por-file-reader.c:480 src/data/sys-file-reader.c:1170
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
@@ -516,7 +516,7 @@ msgstr ""
 msgid "position %d: Invalid variable name `%s'."
 msgstr ""
 
 msgid "position %d: Invalid variable name `%s'."
 msgstr ""
 
-#: src/data/por-file-reader.c:541 src/language/expressions/evaluate.c:155
+#: src/data/por-file-reader.c:541 src/language/expressions/evaluate.c:158
 #, c-format
 msgid "Duplicate variable name %s."
 msgstr ""
 #, c-format
 msgid "Duplicate variable name %s."
 msgstr ""
@@ -576,135 +576,140 @@ msgstr ""
 msgid "Could not access definition for terminal `%s'."
 msgstr ""
 
 msgid "Could not access definition for terminal `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:130
+#: src/data/sys-file-reader.c:132
 msgid "corrupt system file: "
 msgstr ""
 
 msgid "corrupt system file: "
 msgstr ""
 
-#: src/data/sys-file-reader.c:154
+#: src/data/sys-file-reader.c:156
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:245
+#: src/data/sys-file-reader.c:280
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:262
+#: src/data/sys-file-reader.c:297
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:271
+#: src/data/sys-file-reader.c:306
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:274
+#: src/data/sys-file-reader.c:309
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:299
+#: src/data/sys-file-reader.c:335
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:357
+#: src/data/sys-file-reader.c:394
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
-#: src/data/sys-file-reader.c:411
+#: src/data/sys-file-reader.c:456
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
-#: src/data/sys-file-reader.c:418
+#: src/data/sys-file-reader.c:463
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
-#: src/data/sys-file-reader.c:428
+#: src/data/sys-file-reader.c:473
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:437
+#: src/data/sys-file-reader.c:482
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:464
+#: src/data/sys-file-reader.c:577
+#, c-format
+msgid "%s: No variable called %s but it is listed in length table."
+msgstr ""
+
+#: src/data/sys-file-reader.c:629
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:489
+#: src/data/sys-file-reader.c:655
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:521
+#: src/data/sys-file-reader.c:691
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/data/sys-file-reader.c:532
+#: src/data/sys-file-reader.c:702
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
-#: src/data/sys-file-reader.c:548
+#: src/data/sys-file-reader.c:718
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:551 src/data/sys-file-reader.c:552
+#: src/data/sys-file-reader.c:721 src/data/sys-file-reader.c:722
 msgid "big-endian"
 msgstr ""
 
 msgid "big-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:551 src/data/sys-file-reader.c:552
+#: src/data/sys-file-reader.c:721 src/data/sys-file-reader.c:722
 msgid "little-endian"
 msgstr ""
 
 msgid "little-endian"
 msgstr ""
 
-#: src/data/sys-file-reader.c:553
+#: src/data/sys-file-reader.c:723
 msgid "unknown"
 msgstr ""
 
 msgid "unknown"
 msgstr ""
 
-#: src/data/sys-file-reader.c:557
+#: src/data/sys-file-reader.c:727
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
-#: src/data/sys-file-reader.c:561
+#: src/data/sys-file-reader.c:731
 msgid "DEC Kanji"
 msgstr ""
 
 msgid "DEC Kanji"
 msgstr ""
 
-#: src/data/sys-file-reader.c:561 src/language/dictionary/sys-file-info.c:120
+#: src/data/sys-file-reader.c:731 src/language/dictionary/sys-file-info.c:120
 msgid "Unknown"
 msgstr ""
 
 msgid "Unknown"
 msgstr ""
 
-#: src/data/sys-file-reader.c:577
+#: src/data/sys-file-reader.c:747
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/data/sys-file-reader.c:592
+#: src/data/sys-file-reader.c:762
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
@@ -712,213 +717,213 @@ msgid ""
 "%g; LOWEST: %g, %g."
 msgstr ""
 
 "%g; LOWEST: %g, %g."
 msgstr ""
 
-#: src/data/sys-file-reader.c:619
+#: src/data/sys-file-reader.c:789
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
-#: src/data/sys-file-reader.c:661
+#: src/data/sys-file-reader.c:831
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
-#: src/data/sys-file-reader.c:689
+#: src/data/sys-file-reader.c:859
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:694
+#: src/data/sys-file-reader.c:864
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
-#: src/data/sys-file-reader.c:819
+#: src/data/sys-file-reader.c:983
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:830
+#: src/data/sys-file-reader.c:994
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
-#: src/data/sys-file-reader.c:836
+#: src/data/sys-file-reader.c:1000
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:839
+#: src/data/sys-file-reader.c:1003
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
-#: src/data/sys-file-reader.c:843
+#: src/data/sys-file-reader.c:1007
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
-#: src/data/sys-file-reader.c:848
+#: src/data/sys-file-reader.c:1012
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
-#: src/data/sys-file-reader.c:867
+#: src/data/sys-file-reader.c:1031
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:873
+#: src/data/sys-file-reader.c:1037
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:896
+#: src/data/sys-file-reader.c:1061
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
-#: src/data/sys-file-reader.c:917
+#: src/data/sys-file-reader.c:1082
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
-#: src/data/sys-file-reader.c:938
+#: src/data/sys-file-reader.c:1103
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
-#: src/data/sys-file-reader.c:965
+#: src/data/sys-file-reader.c:1130
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
-#: src/data/sys-file-reader.c:970
+#: src/data/sys-file-reader.c:1135
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:995
+#: src/data/sys-file-reader.c:1160
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1048
+#: src/data/sys-file-reader.c:1213
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1090
+#: src/data/sys-file-reader.c:1255
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1101
+#: src/data/sys-file-reader.c:1266
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1117
+#: src/data/sys-file-reader.c:1282
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1124
+#: src/data/sys-file-reader.c:1289
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1129
+#: src/data/sys-file-reader.c:1294
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1140
+#: src/data/sys-file-reader.c:1305
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1181
+#: src/data/sys-file-reader.c:1346
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1185
+#: src/data/sys-file-reader.c:1350
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1227 src/data/sys-file-reader.c:1510
+#: src/data/sys-file-reader.c:1392 src/data/sys-file-reader.c:1676
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1230 src/data/sys-file-reader.c:1348
-#: src/data/sys-file-reader.c:1389
+#: src/data/sys-file-reader.c:1395 src/data/sys-file-reader.c:1514
+#: src/data/sys-file-reader.c:1555
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1246
+#: src/data/sys-file-reader.c:1412
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1261
+#: src/data/sys-file-reader.c:1427
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1267
+#: src/data/sys-file-reader.c:1433
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1301
+#: src/data/sys-file-reader.c:1467
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1340
+#: src/data/sys-file-reader.c:1506
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
-#: src/data/sys-file-reader.c:1516
+#: src/data/sys-file-reader.c:1682
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
 
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
 
-#: src/data/sys-file-writer.c:139
+#: src/data/sys-file-writer.c:175
 #, c-format
 msgid "Unknown system file version %d. Treating as version %d."
 msgstr ""
 
 #, c-format
 msgid "Unknown system file version %d. Treating as version %d."
 msgstr ""
 
-#: src/data/sys-file-writer.c:248
+#: src/data/sys-file-writer.c:326
 #, c-format
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error opening \"%s\" for writing as a system file: %s."
 msgstr ""
 
-#: src/data/sys-file-writer.c:895
+#: src/data/sys-file-writer.c:1046
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
 #, c-format
 msgid "An I/O error occurred writing system file \"%s\"."
 msgstr ""
@@ -969,87 +974,91 @@ msgstr ""
 msgid "scratch"
 msgstr ""
 
 msgid "scratch"
 msgstr ""
 
-#: src/language/command.c:159
+#: src/data/variable.c:387
+msgid "Expected a space in very long string"
+msgstr ""
+
+#: src/language/command.c:171
 #, c-format
 msgid "%s may be used only in testing mode."
 msgstr ""
 
 #, c-format
 msgid "%s may be used only in testing mode."
 msgstr ""
 
-#: src/language/command.c:164
+#: src/language/command.c:176
 #, c-format
 msgid "%s may be used only in enhanced syntax mode."
 msgstr ""
 
 #, c-format
 msgid "%s may be used only in enhanced syntax mode."
 msgstr ""
 
-#: src/language/command.c:414
+#: src/language/command.c:427
 msgid "expecting command name"
 msgstr ""
 
 msgid "expecting command name"
 msgstr ""
 
-#: src/language/command.c:428
+#: src/language/command.c:441
 #, c-format
 msgid "Unknown command %s."
 msgstr ""
 
 #, c-format
 msgid "Unknown command %s."
 msgstr ""
 
-#: src/language/command.c:550
+#: src/language/command.c:563
 msgid "before the active file has been defined"
 msgstr ""
 
 msgid "before the active file has been defined"
 msgstr ""
 
-#: src/language/command.c:552
+#: src/language/command.c:565
 msgid "after the active file has been defined"
 msgstr ""
 
 msgid "after the active file has been defined"
 msgstr ""
 
-#: src/language/command.c:554
+#: src/language/command.c:567
 msgid "inside INPUT PROGRAM"
 msgstr ""
 
 msgid "inside INPUT PROGRAM"
 msgstr ""
 
-#: src/language/command.c:556
+#: src/language/command.c:569
 msgid "inside FILE TYPE"
 msgstr ""
 
 msgid "inside FILE TYPE"
 msgstr ""
 
-#: src/language/command.c:561
+#: src/language/command.c:574
 #, c-format
 msgid "%s or %s"
 msgstr ""
 
 #, c-format
 msgid "%s or %s"
 msgstr ""
 
-#: src/language/command.c:563
+#: src/language/command.c:576
 #, c-format
 msgid "%s, %s, or %s"
 msgstr ""
 
 #, c-format
 msgid "%s, %s, or %s"
 msgstr ""
 
-#: src/language/command.c:567
+#: src/language/command.c:580
 #, c-format
 msgid "%s is allowed only %s."
 msgstr ""
 
 #, c-format
 msgid "%s is allowed only %s."
 msgstr ""
 
-#: src/language/command.c:572
+#: src/language/command.c:585
 #, c-format
 msgid "%s is not allowed inside INPUT PROGRAM."
 msgstr ""
 
 #, c-format
 msgid "%s is not allowed inside INPUT PROGRAM."
 msgstr ""
 
-#: src/language/command.c:574
+#: src/language/command.c:587
 #, c-format
 msgid "%s is not allowed inside FILE TYPE."
 msgstr ""
 
 #, c-format
 msgid "%s is not allowed inside FILE TYPE."
 msgstr ""
 
-#: src/language/command.c:666 src/language/command.c:797
+#: src/language/command.c:679 src/language/command.c:810
 #: src/language/utilities/permissions.c:102
 msgid "This command not allowed when the SAFER option is set."
 msgstr ""
 
 #: src/language/utilities/permissions.c:102
 msgid "This command not allowed when the SAFER option is set."
 msgstr ""
 
-#: src/language/command.c:678
+#: src/language/command.c:691
 #, c-format
 msgid "Error removing `%s': %s."
 msgstr ""
 
 #, c-format
 msgid "Error removing `%s': %s."
 msgstr ""
 
-#: src/language/command.c:728
+#: src/language/command.c:741
 #, c-format
 msgid "Couldn't fork: %s."
 msgstr ""
 
 #, c-format
 msgid "Couldn't fork: %s."
 msgstr ""
 
-#: src/language/command.c:770
+#: src/language/command.c:783
 #, c-format
 msgid "Error executing command: %s."
 msgstr ""
 
 #, c-format
 msgid "Error executing command: %s."
 msgstr ""
 
-#: src/language/command.c:779 src/language/data-io/matrix-data.c:532
+#: src/language/command.c:792 src/language/data-io/matrix-data.c:535
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1038
 #: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
 #: src/language/data-io/print.c:336 src/language/data-io/print.c:1038
 #: src/language/dictionary/vector.c:197 src/language/lexer/lexer.c:453
 #: src/language/stats/autorecode.c:144 src/language/xforms/select-if.c:57
@@ -1057,7 +1066,7 @@ msgstr ""
 msgid "expecting end of command"
 msgstr ""
 
 msgid "expecting end of command"
 msgstr ""
 
-#: src/language/command.c:818
+#: src/language/command.c:831
 msgid "No operating system support for this command."
 msgstr ""
 
 msgid "No operating system support for this command."
 msgstr ""
 
@@ -1115,283 +1124,147 @@ msgid ""
 "commands."
 msgstr ""
 
 "commands."
 msgstr ""
 
-#: src/language/data-io/data-list.c:145
-msgid "DATA LIST must use the same file as the enclosing FILE TYPE."
-msgstr ""
-
-#: src/language/data-io/data-list.c:164
+#: src/language/data-io/data-list.c:149
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
-#: src/language/data-io/data-list.c:199
+#: src/language/data-io/data-list.c:184
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
-#: src/language/data-io/data-list.c:349 src/language/data-io/print.c:297
+#: src/language/data-io/data-list.c:334 src/language/data-io/print.c:297
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/language/data-io/data-list.c:378 src/language/data-io/data-list.c:1729
+#: src/language/data-io/data-list.c:363
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
-#: src/language/data-io/data-list.c:389
+#: src/language/data-io/data-list.c:374
 msgid "At least one variable must be specified."
 msgstr ""
 
 msgid "At least one variable must be specified."
 msgstr ""
 
-#: src/language/data-io/data-list.c:394 src/language/data-io/print.c:329
+#: src/language/data-io/data-list.c:379 src/language/data-io/print.c:329
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
-#: src/language/data-io/data-list.c:427 src/language/data-io/data-list.c:441
+#: src/language/data-io/data-list.c:412 src/language/data-io/data-list.c:426
 #: src/language/data-io/print.c:521 src/language/data-io/print.c:534
 msgid "Column positions for fields must be positive."
 msgstr ""
 
 #: src/language/data-io/print.c:521 src/language/data-io/print.c:534
 msgid "Column positions for fields must be positive."
 msgstr ""
 
-#: src/language/data-io/data-list.c:446
+#: src/language/data-io/data-list.c:431
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
-#: src/language/data-io/data-list.c:460
+#: src/language/data-io/data-list.c:445
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
-#: src/language/data-io/data-list.c:480 src/language/data-io/print.c:562
+#: src/language/data-io/data-list.c:465 src/language/data-io/print.c:562
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
-#: src/language/data-io/data-list.c:495 src/language/data-io/print.c:578
+#: src/language/data-io/data-list.c:480 src/language/data-io/print.c:578
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
-#: src/language/data-io/data-list.c:509 src/language/data-io/print.c:591
+#: src/language/data-io/data-list.c:494 src/language/data-io/print.c:591
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
-#: src/language/data-io/data-list.c:556 src/language/data-io/data-list.c:652
-#: src/language/data-io/data-list.c:860
+#: src/language/data-io/data-list.c:539 src/language/data-io/data-list.c:635
+#: src/language/data-io/data-list.c:840
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
-#: src/language/data-io/data-list.c:561
+#: src/language/data-io/data-list.c:544
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
-#: src/language/data-io/data-list.c:568
+#: src/language/data-io/data-list.c:551
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
-#: src/language/data-io/data-list.c:643
+#: src/language/data-io/data-list.c:626
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
-#: src/language/data-io/data-list.c:756 src/language/data-io/print.c:767
+#: src/language/data-io/data-list.c:736 src/language/data-io/print.c:767
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
-#: src/language/data-io/data-list.c:783 src/language/data-io/data-list.c:901
+#: src/language/data-io/data-list.c:763 src/language/data-io/data-list.c:878
 #: src/language/data-io/print.c:798
 #: src/language/dictionary/sys-file-info.c:140
 #: src/language/dictionary/sys-file-info.c:374
 #: src/language/data-io/print.c:798
 #: src/language/dictionary/sys-file-info.c:140
 #: src/language/dictionary/sys-file-info.c:374
-#: src/language/stats/descriptives.c:887 src/procedure.c:878
+#: src/language/stats/descriptives.c:886 src/procedure.c:678
 msgid "Variable"
 msgstr ""
 
 msgid "Variable"
 msgstr ""
 
-#: src/language/data-io/data-list.c:784 src/language/data-io/print.c:799
+#: src/language/data-io/data-list.c:764 src/language/data-io/print.c:799
 msgid "Record"
 msgstr ""
 
 msgid "Record"
 msgstr ""
 
-#: src/language/data-io/data-list.c:785 src/language/data-io/print.c:800
+#: src/language/data-io/data-list.c:765 src/language/data-io/print.c:800
 #: src/ui/gui/var-sheet.c:74
 msgid "Columns"
 msgstr ""
 
 #: src/ui/gui/var-sheet.c:74
 msgid "Columns"
 msgstr ""
 
-#: src/language/data-io/data-list.c:786 src/language/data-io/data-list.c:902
+#: src/language/data-io/data-list.c:766 src/language/data-io/data-list.c:879
 #: src/language/data-io/print.c:801
 msgid "Format"
 msgstr ""
 
 #: src/language/data-io/print.c:801
 msgid "Format"
 msgstr ""
 
-#: src/language/data-io/data-list.c:801
+#: src/language/data-io/data-list.c:781
 #, c-format
 msgid "Reading %d record from %s."
 msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
 #, c-format
 msgid "Reading %d record from %s."
 msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/language/data-io/data-list.c:917
+#: src/language/data-io/data-list.c:894
 #, c-format
 msgid "Reading free-form data from %s."
 msgstr ""
 
 #, c-format
 msgid "Reading free-form data from %s."
 msgstr ""
 
-#: src/language/data-io/data-list.c:968
+#: src/language/data-io/data-list.c:945
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1083
+#: src/language/data-io/data-list.c:1060
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1136
+#: src/language/data-io/data-list.c:1113
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1179
+#: src/language/data-io/data-list.c:1156
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
-#: src/language/data-io/data-list.c:1392
-msgid ""
-"REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
-"TYPE."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1402 src/language/data-io/data-list.c:1436
-#: src/language/data-io/data-list.c:1449 src/language/data-io/data-list.c:1462
-#: src/language/data-io/data-list.c:1496
-#, c-format
-msgid "%s subcommand given multiple times."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1425
-#, c-format
-msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1482
-#, c-format
-msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1505
-#, c-format
-msgid "ID beginning column (%ld) must be positive."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1520
-#, c-format
-msgid "ID ending column (%ld) must be positive."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1526
-#, c-format
-msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1566
-msgid "Missing required specification STARTS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1568
-msgid "Missing required specification OCCURS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1575
-msgid "ID specified without CONTINUED."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1586
-#, c-format
-msgid ""
-"STARTS beginning column (%d) exceeds default STARTS ending column taken from "
-"file's record width (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1599
-#, c-format
-msgid ""
-"CONTINUED beginning column (%d) exceeds default CONTINUED ending column "
-"taken from file's record width (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1678
-msgid "String variable not allowed here."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1688
-#, c-format
-msgid "%s (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1694
-#, c-format
-msgid "Variable or integer expected for %s."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1819
-#, c-format
-msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1852
-#, c-format
-msgid ""
-"Variable %s starting in column %d extends beyond physical record length of %"
-"d."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1919
-#, c-format
-msgid "Invalid value %d for OCCURS."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1925
-#, c-format
-msgid "Beginning column for STARTS (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1932
-#, c-format
-msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1940
-#, c-format
-msgid "Invalid value %d for LENGTH."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1947
-#, c-format
-msgid "Beginning column for CONTINUED (%d) must be at least 1."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1955
-#, c-format
-msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
-msgstr ""
-
-#: src/language/data-io/data-list.c:1987
-#, c-format
-msgid ""
-"Number of repetitions specified on OCCURS (%d) exceed number of repetitions "
-"available in space on STARTS (%d), and CONTINUED not specified."
-msgstr ""
-
-#: src/language/data-io/data-list.c:2005
-#, c-format
-msgid "Unexpected end of file with %d repetitions remaining out of %d."
-msgstr ""
-
 #: src/language/data-io/data-reader.c:131
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
 #: src/language/data-io/data-reader.c:131
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
@@ -1482,154 +1355,21 @@ msgstr ""
 msgid "Handle for %s not allowed here."
 msgstr ""
 
 msgid "Handle for %s not allowed here."
 msgstr ""
 
-#: src/language/data-io/file-type.c:149
-msgid "MIXED, GROUPED, or NESTED expected."
-msgstr ""
-
-#: src/language/data-io/file-type.c:172
-msgid "The CASE subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:190
-msgid "WARN or NOWARN expected after WILD."
-msgstr ""
-
-#: src/language/data-io/file-type.c:198
-msgid "The DUPLICATE subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:212
-msgid "DUPLICATE=CASE is only valid on FILE TYPE NESTED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:221
-#, c-format
-msgid "WARN%s expected after DUPLICATE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:222
-msgid ", NOWARN, or CASE"
-msgstr ""
-
-#: src/language/data-io/file-type.c:223
-msgid " or NOWARN"
-msgstr ""
-
-#: src/language/data-io/file-type.c:231
-msgid "The MISSING subcommand is not valid on FILE TYPE MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:243
-msgid "WARN or NOWARN after MISSING."
-msgstr ""
-
-#: src/language/data-io/file-type.c:251
-msgid "ORDERED is only valid on FILE TYPE GROUPED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:262
-msgid "YES or NO expected after ORDERED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:268 src/language/data-io/file-type.c:554
-msgid "while expecting a valid subcommand"
-msgstr ""
-
-#: src/language/data-io/file-type.c:275
-msgid "The required RECORD subcommand was not present."
-msgstr ""
-
-#: src/language/data-io/file-type.c:283
-msgid "The required CASE subcommand was not present."
-msgstr ""
-
-#: src/language/data-io/file-type.c:289
-msgid "CASE and RECORD must specify different variable names."
-msgstr ""
-
-#: src/language/data-io/file-type.c:347
-msgid "Column value must be positive."
-msgstr ""
-
-#: src/language/data-io/file-type.c:363
-msgid "Ending column precedes beginning column."
-msgstr ""
-
-#: src/language/data-io/file-type.c:383
-msgid "Bad format specifier name."
-msgstr ""
-
-#: src/language/data-io/file-type.c:426
-msgid "OTHER may appear only on the last RECORD TYPE command."
-msgstr ""
-
-#: src/language/data-io/file-type.c:436
-msgid "No input commands (DATA LIST, REPEATING DATA) for above RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:487
-msgid ""
-"The CASE subcommand is not allowed on the RECORD TYPE command for FILE TYPE "
-"MIXED."
-msgstr ""
-
-#: src/language/data-io/file-type.c:497
-msgid ""
-"No variable name may be specified for the CASE subcommand on RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:505
-msgid ""
-"The CASE column specification on RECORD TYPE must give a format specifier "
-"that is the same type as that of the CASE column specification given on FILE "
-"TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:521
-msgid "WARN or NOWARN expected on DUPLICATE subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:535
-msgid "WARN or NOWARN expected on MISSING subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:548
-msgid "YES or NO expected on SPREAD subcommand."
-msgstr ""
-
-#: src/language/data-io/file-type.c:598
-msgid "No input commands (DATA LIST, REPEATING DATA) on above RECORD TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:605
-msgid "No commands between FILE TYPE and END FILE TYPE."
-msgstr ""
-
-#: src/language/data-io/file-type.c:674
-#, c-format
-msgid "Unknown record type \"%.*s\"."
-msgstr ""
-
-#: src/language/data-io/file-type.c:698
-#, c-format
-msgid "Unknown record type %g."
-msgstr ""
-
-#: src/language/data-io/get.c:106
+#: src/language/data-io/get.c:111
 msgid "expecting COMM or TAPE"
 msgstr ""
 
 msgid "expecting COMM or TAPE"
 msgstr ""
 
-#: src/language/data-io/get.c:348 src/language/data-io/get.c:362
-#: src/language/data-io/get.c:387
+#: src/language/data-io/get.c:353 src/language/data-io/get.c:367
+#: src/language/data-io/get.c:392
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
-#: src/language/data-io/get.c:594 src/language/data-io/print.c:180
+#: src/language/data-io/get.c:599 src/language/data-io/print.c:180
 msgid "expecting a valid subcommand"
 msgstr ""
 
 msgid "expecting a valid subcommand"
 msgstr ""
 
-#: src/language/data-io/get.c:627
+#: src/language/data-io/get.c:632
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
@@ -1637,96 +1377,94 @@ msgid ""
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
-#: src/language/data-io/get.c:652
+#: src/language/data-io/get.c:657
 msgid "`=' expected after variable list."
 msgstr ""
 
 msgid "`=' expected after variable list."
 msgstr ""
 
-#: src/language/data-io/get.c:659
+#: src/language/data-io/get.c:664
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
-#: src/language/data-io/get.c:672
+#: src/language/data-io/get.c:677
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
-#: src/language/data-io/get.c:702
+#: src/language/data-io/get.c:707
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
-#: src/language/data-io/get.c:879
+#: src/language/data-io/get.c:884
 msgid "The active file may not be specified more than once."
 msgstr ""
 
 msgid "The active file may not be specified more than once."
 msgstr ""
 
-#: src/language/data-io/get.c:887
+#: src/language/data-io/get.c:892
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
-#: src/language/data-io/get.c:895
+#: src/language/data-io/get.c:900
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/language/data-io/get.c:933
+#: src/language/data-io/get.c:938
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
-#: src/language/data-io/get.c:953
+#: src/language/data-io/get.c:958
 msgid "BY may appear at most once."
 msgstr ""
 
 msgid "BY may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:973
+#: src/language/data-io/get.c:978
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
-#: src/language/data-io/get.c:987
+#: src/language/data-io/get.c:992
 msgid "FIRST may appear at most once."
 msgstr ""
 
 msgid "FIRST may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:1001
+#: src/language/data-io/get.c:1006
 msgid "LAST may appear at most once."
 msgstr ""
 
 msgid "LAST may appear at most once."
 msgstr ""
 
-#: src/language/data-io/get.c:1042
+#: src/language/data-io/get.c:1047
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
-#: src/language/data-io/get.c:1047
+#: src/language/data-io/get.c:1052
 msgid "BY is required when IN is specified."
 msgstr ""
 
 msgid "BY is required when IN is specified."
 msgstr ""
 
-#: src/language/data-io/get.c:1075
+#: src/language/data-io/get.c:1080
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
-#: src/language/data-io/get.c:1530
+#: src/language/data-io/get.c:1535
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:98
+#: src/language/data-io/inpt-pgm.c:131
 msgid "Unexpected end-of-file within INPUT PROGRAM."
 msgstr ""
 
 msgid "Unexpected end-of-file within INPUT PROGRAM."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:107
-msgid ""
-"No data-input or transformation commands specified between INPUT PROGRAM and "
-"END INPUT PROGRAM."
+#: src/language/data-io/inpt-pgm.c:144
+msgid "Input program did not create any variables."
 msgstr ""
 
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:354
+#: src/language/data-io/inpt-pgm.c:361
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
 msgid "COLUMN subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/inpt-pgm.c:402
+#: src/language/data-io/inpt-pgm.c:409
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
 msgid ""
 "REREAD: Column numbers must be positive finite numbers.  Column set to 1."
 msgstr ""
@@ -1767,183 +1505,183 @@ msgstr ""
 msgid "Line"
 msgstr ""
 
 msgid "Line"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:211
+#: src/language/data-io/matrix-data.c:214
 msgid "VARIABLES subcommand multiply specified."
 msgstr ""
 
 msgid "VARIABLES subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:226
+#: src/language/data-io/matrix-data.c:229
 msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
 msgstr ""
 
 msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:287
+#: src/language/data-io/matrix-data.c:290
 msgid "in FORMAT subcommand"
 msgstr ""
 
 msgid "in FORMAT subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:298
+#: src/language/data-io/matrix-data.c:301
 msgid "SPLIT subcommand multiply specified."
 msgstr ""
 
 msgid "SPLIT subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:305
+#: src/language/data-io/matrix-data.c:308
 msgid "in SPLIT subcommand"
 msgstr ""
 
 msgid "in SPLIT subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:315
+#: src/language/data-io/matrix-data.c:318
 msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
 msgstr ""
 
 msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:349
+#: src/language/data-io/matrix-data.c:352
 #, c-format
 msgid "Split variable %s is already another type."
 msgstr ""
 
 #, c-format
 msgid "Split variable %s is already another type."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:364
+#: src/language/data-io/matrix-data.c:367
 msgid "FACTORS subcommand multiply specified."
 msgstr ""
 
 msgid "FACTORS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:383
+#: src/language/data-io/matrix-data.c:386
 #, c-format
 msgid "Factor variable %s is already another type."
 msgstr ""
 
 #, c-format
 msgid "Factor variable %s is already another type."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:398
+#: src/language/data-io/matrix-data.c:401
 msgid "CELLS subcommand multiply specified."
 msgstr ""
 
 msgid "CELLS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:404
-#: src/language/data-io/matrix-data.c:423
+#: src/language/data-io/matrix-data.c:407
+#: src/language/data-io/matrix-data.c:426
 msgid "expecting positive integer"
 msgstr ""
 
 msgid "expecting positive integer"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:417
+#: src/language/data-io/matrix-data.c:420
 msgid "N subcommand multiply specified."
 msgstr ""
 
 msgid "N subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:438
+#: src/language/data-io/matrix-data.c:441
 msgid "CONTENTS subcommand multiply specified."
 msgstr ""
 
 msgid "CONTENTS subcommand multiply specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:458
+#: src/language/data-io/matrix-data.c:461
 msgid "Nested parentheses not allowed."
 msgstr ""
 
 msgid "Nested parentheses not allowed."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:468
+#: src/language/data-io/matrix-data.c:471
 msgid "Mismatched right parenthesis (`(')."
 msgstr ""
 
 msgid "Mismatched right parenthesis (`(')."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:473
+#: src/language/data-io/matrix-data.c:476
 msgid "Empty parentheses not allowed."
 msgstr ""
 
 msgid "Empty parentheses not allowed."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:486
-#: src/language/data-io/matrix-data.c:494
+#: src/language/data-io/matrix-data.c:489
+#: src/language/data-io/matrix-data.c:497
 msgid "in CONTENTS subcommand"
 msgstr ""
 
 msgid "in CONTENTS subcommand"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:501
+#: src/language/data-io/matrix-data.c:504
 #, c-format
 msgid "Content multiply specified for %s."
 msgstr ""
 
 #, c-format
 msgid "Content multiply specified for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:518
+#: src/language/data-io/matrix-data.c:521
 msgid "Missing right parenthesis."
 msgstr ""
 
 msgid "Missing right parenthesis."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:538
+#: src/language/data-io/matrix-data.c:541
 msgid "Missing VARIABLES subcommand."
 msgstr ""
 
 msgid "Missing VARIABLES subcommand."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:544
+#: src/language/data-io/matrix-data.c:547
 msgid ""
 "CONTENTS subcommand not specified: assuming file contains only CORR matrix."
 msgstr ""
 
 msgid ""
 "CONTENTS subcommand not specified: assuming file contains only CORR matrix."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:554
+#: src/language/data-io/matrix-data.c:557
 msgid ""
 "Missing CELLS subcommand.  CELLS is required when ROWTYPE_ is not given in "
 "the data and factors are present."
 msgstr ""
 
 msgid ""
 "Missing CELLS subcommand.  CELLS is required when ROWTYPE_ is not given in "
 "the data and factors are present."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:562
+#: src/language/data-io/matrix-data.c:565
 msgid "Split file values must be present in the data when ROWTYPE_ is present."
 msgstr ""
 
 msgid "Split file values must be present in the data when ROWTYPE_ is present."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:615
+#: src/language/data-io/matrix-data.c:618
 msgid "No continuous variables specified."
 msgstr ""
 
 msgid "No continuous variables specified."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:858
+#: src/language/data-io/matrix-data.c:861
 msgid "Scope of string exceeds line."
 msgstr ""
 
 msgid "Scope of string exceeds line."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:923
+#: src/language/data-io/matrix-data.c:926
 #, c-format
 msgid "End of line expected %s while reading %s."
 msgstr ""
 
 #, c-format
 msgid "End of line expected %s while reading %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1113
+#: src/language/data-io/matrix-data.c:1116
 #, c-format
 msgid "expecting value for %s %s"
 msgstr ""
 
 #, c-format
 msgid "expecting value for %s %s"
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1278
+#: src/language/data-io/matrix-data.c:1281
 #, c-format
 msgid "Syntax error expecting SPLIT FILE value %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting SPLIT FILE value %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1287
+#: src/language/data-io/matrix-data.c:1290
 #, c-format
 msgid "Expecting value %g for %s."
 msgstr ""
 
 #, c-format
 msgid "Expecting value %g for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1328
-#: src/language/data-io/matrix-data.c:1805
+#: src/language/data-io/matrix-data.c:1331
+#: src/language/data-io/matrix-data.c:1808
 #, c-format
 msgid "Syntax error expecting factor value %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting factor value %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1337
+#: src/language/data-io/matrix-data.c:1340
 #, c-format
 msgid "Syntax error expecting value %g for %s %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error expecting value %g for %s %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1581
+#: src/language/data-io/matrix-data.c:1584
 #, c-format
 msgid "Syntax error %s expecting SPLIT FILE value."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s expecting SPLIT FILE value."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1710
+#: src/language/data-io/matrix-data.c:1713
 #, c-format
 msgid ""
 "Expected %d lines of data for %s content; actually saw %d lines.  No data "
 "will be output for this content."
 msgstr ""
 
 #, c-format
 msgid ""
 "Expected %d lines of data for %s content; actually saw %d lines.  No data "
 "will be output for this content."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1747
+#: src/language/data-io/matrix-data.c:1750
 #, c-format
 msgid "Multiply specified ROWTYPE_ %s."
 msgstr ""
 
 #, c-format
 msgid "Multiply specified ROWTYPE_ %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1752
+#: src/language/data-io/matrix-data.c:1755
 #, c-format
 msgid "Syntax error %s expecting ROWTYPE_ string."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s expecting ROWTYPE_ string."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1772
+#: src/language/data-io/matrix-data.c:1775
 #, c-format
 msgid "Syntax error %s."
 msgstr ""
 
 #, c-format
 msgid "Syntax error %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1923
+#: src/language/data-io/matrix-data.c:1926
 #, c-format
 msgid "Duplicate specification for %s."
 msgstr ""
 
 #, c-format
 msgid "Duplicate specification for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1935
+#: src/language/data-io/matrix-data.c:1938
 #, c-format
 msgid "Too many rows of matrix data for %s."
 msgstr ""
 
 #, c-format
 msgid "Too many rows of matrix data for %s."
 msgstr ""
 
-#: src/language/data-io/matrix-data.c:1981
+#: src/language/data-io/matrix-data.c:1984
 #, c-format
 msgid "Syntax error expecting value for %s %s."
 msgstr ""
 #, c-format
 msgid "Syntax error expecting value for %s %s."
 msgstr ""
@@ -2046,7 +1784,7 @@ msgid "`)' expected after output format."
 msgstr ""
 
 #: src/language/dictionary/missing-values.c:53
 msgstr ""
 
 #: src/language/dictionary/missing-values.c:53
-#: src/language/stats/aggregate.c:434
+#: src/language/stats/aggregate.c:438
 msgid "expecting `('"
 msgstr ""
 
 msgid "expecting `('"
 msgstr ""
 
@@ -2289,7 +2027,7 @@ msgid "Documents in the active file:"
 msgstr ""
 
 #: src/language/dictionary/sys-file-info.c:381
 msgstr ""
 
 #: src/language/dictionary/sys-file-info.c:381
-#: src/language/dictionary/sys-file-info.c:520 src/procedure.c:880
+#: src/language/dictionary/sys-file-info.c:520 src/procedure.c:680
 #: src/ui/gui/var-sheet.c:71
 msgid "Label"
 msgstr ""
 #: src/ui/gui/var-sheet.c:71
 msgid "Label"
 msgstr ""
@@ -2317,7 +2055,7 @@ msgstr ""
 #: src/language/stats/crosstabs.q:1109 src/language/stats/crosstabs.q:1136
 #: src/language/stats/crosstabs.q:1156 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1141 src/language/stats/frequencies.q:1145
 #: src/language/stats/crosstabs.q:1109 src/language/stats/crosstabs.q:1136
 #: src/language/stats/crosstabs.q:1156 src/language/stats/crosstabs.q:1178
 #: src/language/stats/examine.q:1141 src/language/stats/frequencies.q:1145
-#: src/language/stats/frequencies.q:1266 src/procedure.c:879
+#: src/language/stats/frequencies.q:1266 src/procedure.c:679
 msgid "Value"
 msgstr ""
 
 msgid "Value"
 msgstr ""
 
@@ -2400,7 +2138,7 @@ msgstr ""
 msgid "The weighting variable may not be scratch."
 msgstr ""
 
 msgid "The weighting variable may not be scratch."
 msgstr ""
 
-#: src/language/expressions/evaluate.c:144
+#: src/language/expressions/evaluate.c:147
 msgid "expecting number or string"
 msgstr ""
 
 msgid "expecting number or string"
 msgstr ""
 
@@ -2482,7 +2220,7 @@ msgstr ""
 msgid "Unknown identifier %s."
 msgstr ""
 
 msgid "Unknown identifier %s."
 msgstr ""
 
-#: src/language/expressions/parse.c:846 src/language/stats/aggregate.c:490
+#: src/language/expressions/parse.c:846 src/language/stats/aggregate.c:494
 msgid "expecting `)'"
 msgstr ""
 
 msgid "expecting `)'"
 msgstr ""
 
@@ -2556,6 +2294,11 @@ msgstr ""
 msgid "%s is not yet implemented."
 msgstr ""
 
 msgid "%s is not yet implemented."
 msgstr ""
 
+#: src/language/expressions/parse.c:1227
+#, c-format
+msgid "%s may not appear after TEMPORARY."
+msgstr ""
+
 #: src/language/lexer/format-parser.c:66
 msgid "X and T format specifiers not allowed here."
 msgstr ""
 #: src/language/lexer/format-parser.c:66
 msgid "X and T format specifiers not allowed here."
 msgstr ""
@@ -2574,7 +2317,12 @@ msgstr ""
 msgid "Data format %s does not specify a width."
 msgstr ""
 
 msgid "Data format %s does not specify a width."
 msgstr ""
 
-#: src/language/lexer/format-parser.c:145
+#: src/language/lexer/format-parser.c:133
+#, c-format
+msgid "String variable width may not exceed %d"
+msgstr ""
+
+#: src/language/lexer/format-parser.c:150
 #, c-format
 msgid "Data format %s is not valid."
 msgstr ""
 #, c-format
 msgid "Data format %s is not valid."
 msgstr ""
@@ -2792,54 +2540,54 @@ msgstr ""
 msgid "Reading `%s': %s."
 msgstr ""
 
 msgid "Reading `%s': %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:200
+#: src/language/stats/aggregate.c:204
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
-#: src/language/stats/aggregate.c:229
+#: src/language/stats/aggregate.c:233
 msgid "expecting BREAK"
 msgstr ""
 
 msgid "expecting BREAK"
 msgstr ""
 
-#: src/language/stats/aggregate.c:234
+#: src/language/stats/aggregate.c:238
 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 ""
 
 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:403
+#: src/language/stats/aggregate.c:407
 msgid "expecting aggregation function"
 msgstr ""
 
 msgid "expecting aggregation function"
 msgstr ""
 
-#: src/language/stats/aggregate.c:419
+#: src/language/stats/aggregate.c:423
 #, c-format
 msgid "Unknown aggregation function %s."
 msgstr ""
 
 #, c-format
 msgid "Unknown aggregation function %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:471
+#: src/language/stats/aggregate.c:475
 #, c-format
 msgid "Missing argument %d to %s."
 msgstr ""
 
 #, c-format
 msgid "Missing argument %d to %s."
 msgstr ""
 
-#: src/language/stats/aggregate.c:480
+#: src/language/stats/aggregate.c:484
 #, c-format
 msgid "Arguments to %s must be of same type as source variables."
 msgstr ""
 
 #, c-format
 msgid "Arguments to %s must be of same type as source variables."
 msgstr ""
 
-#: src/language/stats/aggregate.c:502
+#: src/language/stats/aggregate.c:506
 #, c-format
 msgid ""
 "Number of source variables (%u) does not match number of target variables (%"
 "u)."
 msgstr ""
 
 #, c-format
 msgid ""
 "Number of source variables (%u) does not match number of target variables (%"
 "u)."
 msgstr ""
 
-#: src/language/stats/aggregate.c:518
+#: src/language/stats/aggregate.c:522
 #, 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 ""
 
 #, 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:585
+#: src/language/stats/aggregate.c:589
 #, c-format
 msgid ""
 "Variable name %s is not unique within the aggregate file dictionary, which "
 #, c-format
 msgid ""
 "Variable name %s is not unique within the aggregate file dictionary, which "
@@ -3248,19 +2996,19 @@ msgstr ""
 msgid "Target"
 msgstr ""
 
 msgid "Target"
 msgstr ""
 
-#: src/language/stats/descriptives.c:668 src/language/stats/descriptives.c:674
+#: src/language/stats/descriptives.c:667 src/language/stats/descriptives.c:673
 msgid "Z-score of "
 msgstr ""
 
 msgid "Z-score of "
 msgstr ""
 
-#: src/language/stats/descriptives.c:890
+#: src/language/stats/descriptives.c:889
 msgid "Valid N"
 msgstr ""
 
 msgid "Valid N"
 msgstr ""
 
-#: src/language/stats/descriptives.c:891
+#: src/language/stats/descriptives.c:890
 msgid "Missing N"
 msgstr ""
 
 msgid "Missing N"
 msgstr ""
 
-#: src/language/stats/descriptives.c:918
+#: src/language/stats/descriptives.c:917
 #, c-format
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
 #, c-format
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
@@ -3371,64 +3119,64 @@ msgstr ""
 msgid "Tukey's Hinges"
 msgstr ""
 
 msgid "Tukey's Hinges"
 msgstr ""
 
-#: src/language/stats/flip.c:94
+#: src/language/stats/flip.c:98
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
 msgstr ""
 
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/language/stats/flip.c:237
+#: src/language/stats/flip.c:241
 #, c-format
 msgid "Could not create acceptable variant for variable %s."
 msgstr ""
 
 #, c-format
 msgid "Could not create acceptable variant for variable %s."
 msgstr ""
 
-#: src/language/stats/flip.c:253
+#: src/language/stats/flip.c:257
 msgid "Cannot create more than 99999 variable names."
 msgstr ""
 
 msgid "Cannot create more than 99999 variable names."
 msgstr ""
 
-#: src/language/stats/flip.c:290
+#: src/language/stats/flip.c:294
 msgid "Could not create temporary file for FLIP."
 msgstr ""
 
 msgid "Could not create temporary file for FLIP."
 msgstr ""
 
-#: src/language/stats/flip.c:301 src/language/stats/flip.c:367
+#: src/language/stats/flip.c:305 src/language/stats/flip.c:371
 #, c-format
 msgid "Error writing FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:414
+#: src/language/stats/flip.c:418
 #, c-format
 msgid "Error rewinding FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error rewinding FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:421
+#: src/language/stats/flip.c:425
 msgid "Error creating FLIP source file."
 msgstr ""
 
 msgid "Error creating FLIP source file."
 msgstr ""
 
-#: src/language/stats/flip.c:433
+#: src/language/stats/flip.c:437
 #, c-format
 msgid "Error reading FLIP file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error reading FLIP file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:457
+#: src/language/stats/flip.c:461
 #, c-format
 msgid "Error seeking FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error seeking FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:465
+#: src/language/stats/flip.c:469
 #, c-format
 msgid "Error writing FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error writing FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:480
+#: src/language/stats/flip.c:484
 #, c-format
 msgid "Error rewinding FLIP source file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error rewinding FLIP source file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:528
+#: src/language/stats/flip.c:532
 #, c-format
 msgid "Error reading FLIP temporary file: %s."
 msgstr ""
 
 #, c-format
 msgid "Error reading FLIP temporary file: %s."
 msgstr ""
 
-#: src/language/stats/flip.c:531
+#: src/language/stats/flip.c:535
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
@@ -3685,7 +3433,7 @@ msgstr ""
 msgid "Coefficient Correlations"
 msgstr ""
 
 msgid "Coefficient Correlations"
 msgstr ""
 
-#: src/language/stats/regression.q:1157
+#: src/language/stats/regression.q:1104
 msgid "Dependent variable must be numeric."
 msgstr ""
 
 msgid "Dependent variable must be numeric."
 msgstr ""
 
@@ -4099,7 +3847,7 @@ msgstr ""
 msgid "Empirical with averaging"
 msgstr ""
 
 msgid "Empirical with averaging"
 msgstr ""
 
-#: src/math/sort.c:430
+#: src/math/sort.c:432
 #, c-format
 msgid ""
 "Out of memory.  Could not allocate room for minimum of %d cases of %d bytes "
 #, c-format
 msgid ""
 "Out of memory.  Could not allocate room for minimum of %d cases of %d bytes "
@@ -4684,3 +4432,25 @@ msgid ""
 "Stopping syntax file processing here to avoid a cascade of dependent command "
 "failures."
 msgstr ""
 "Stopping syntax file processing here to avoid a cascade of dependent command "
 "failures."
 msgstr ""
+
+#: src/ui/terminal/msg-ui.c:61
+msgid "Terminating execution of syntax file due to error."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:63
+#, c-format
+msgid "Errors (%d) exceeds limit (%d)."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:66
+#, c-format
+msgid "Warnings (%d) exceed limit (%d)."
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:115
+msgid "error"
+msgstr ""
+
+#: src/ui/terminal/msg-ui.c:116
+msgid "warning"
+msgstr ""
index d9cb36ce9237f84aa32eff09760878db851860d4..5369faa8b7e9318c057a4a8edf064c8a155c2183 100644 (file)
@@ -1,3 +1,20 @@
+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.
 Mon May  1 15:45:42 2006  Ben Pfaff  <blp@gnu.org>
 
        Change case limit type from int to size_t.
index 45b20a0cede3e93e5173a56073096273b4e64fab..1e8fe67983350fefb5ae4ce117b312bbb0711f9f 100644 (file)
@@ -568,10 +568,14 @@ parse_RB (struct data_in *i)
   return true;
 }
 
   return true;
 }
 
+
 static inline bool
 parse_A (struct data_in *i)
 {
 static inline bool
 parse_A (struct data_in *i)
 {
-  buf_copy_rpad (i->v->s, i->format.w, i->s, i->e - i->s);
+  const int bytes = width_to_bytes(i->format.w);
+
+  copy_mangle (i->v->s, bytes, i->s, i->e - i->s);
+  
   return true;
 }
 
   return true;
 }
 
index 78668b7aed96685b52b6934f277239e36dd92dab..b7ee5314d93c095993429de721d187b72d4f439e 100644 (file)
@@ -395,7 +395,7 @@ convert_Z (char *dst, const struct fmt_spec *fp, double number)
 static int
 convert_A (char *dst, const struct fmt_spec *fp, const char *string)
 {
 static int
 convert_A (char *dst, const struct fmt_spec *fp, const char *string)
 {
-  memcpy (dst, string, fp->w);
+  copy_demangle(dst, fp->w, string, fp->w);
   return 1;
 }
 
   return 1;
 }
 
@@ -1063,6 +1063,7 @@ try_F (char *dst, const struct fmt_spec *fp, double number)
                  avoids wasting too much time formatting more
                  decimal places on the first try. */
               int result = format_and_round (dst, number, fp, fp->d + 2);
                  avoids wasting too much time formatting more
                  decimal places on the first try. */
               int result = format_and_round (dst, number, fp, fp->d + 2);
+
               if (result >= 0)
                 return result;
 
               if (result >= 0)
                 return result;
 
@@ -1143,7 +1144,7 @@ format_and_round (char *dst, double number, const struct fmt_spec *fp,
          digits of the fraction.
          Right-justify the integer part and sign. */
       dst[0] = ' ';
          digits of the fraction.
          Right-justify the integer part and sign. */
       dst[0] = ' ';
-      memcpy (dst + 1, buf, fp->w);
+      memcpy (dst + 1, buf, fp->w - 1);
       return 1;
     }
 
       return 1;
     }
 
index 161071ec159a038555da3467ef8586a07a143fa3..c8840f302beebc06d8ccc0ec8abc37aeb502550e 100644 (file)
@@ -270,7 +270,7 @@ dict_create_var (struct dictionary *d, const char *name, int width)
   assert (d != NULL);
   assert (name != NULL);
 
   assert (d != NULL);
   assert (name != NULL);
 
-  assert (width >= 0 && width < 256);
+  assert (width >= 0 && width <= MAX_STRING);
 
   assert (var_is_plausible_name(name,0));
     
 
   assert (var_is_plausible_name(name,0));
     
@@ -284,7 +284,7 @@ dict_create_var (struct dictionary *d, const char *name, int width)
   v->type = width == 0 ? NUMERIC : ALPHA;
   v->width = width;
   v->fv = d->next_value_idx;
   v->type = width == 0 ? NUMERIC : ALPHA;
   v->width = width;
   v->fv = d->next_value_idx;
-  v->nv = width == 0 ? 1 : DIV_RND_UP (width, 8);
+  v->nv = width_to_bytes(width) / MAX_SHORT_STRING ;
   v->leave = dict_class_from_id (v->name) == DC_SCRATCH;
   v->index = d->var_cnt;
   mv_init (&v->miss, width);
   v->leave = dict_class_from_id (v->name) == DC_SCRATCH;
   v->index = d->var_cnt;
   mv_init (&v->miss, width);
index 0dfc21c08bd386efffb5c1551ddaec4c10418c92..6ca17211560e4224e86b78be9318d9c9ce7026a2 100644 (file)
@@ -26,7 +26,7 @@ DEFFMT (FMT_DOT,        "DOT",       2,  1,  40,  1,   40, 0001, FMT_DOT, 32)
 DEFFMT (FMT_DOLLAR,      "DOLLAR",    2,  1,  40,  2,   40, 0001, FMT_DOLLAR, 4)
 DEFFMT (FMT_PCT,         "PCT",       2,  1,  40,  2,   40, 0001, FMT_PCT, 31)
 DEFFMT (FMT_Z,           "Z",         2,  1,  40,  1,   40, 0011, FMT_F, 15)
 DEFFMT (FMT_DOLLAR,      "DOLLAR",    2,  1,  40,  2,   40, 0001, FMT_DOLLAR, 4)
 DEFFMT (FMT_PCT,         "PCT",       2,  1,  40,  2,   40, 0001, FMT_PCT, 31)
 DEFFMT (FMT_Z,           "Z",         2,  1,  40,  1,   40, 0011, FMT_F, 15)
-DEFFMT (FMT_A,           "A",         1,  1, 255,  1,  255, 0004, FMT_A, 1)
+DEFFMT (FMT_A,           "A",         1,  1, MAX_STRING,  1,  MAX_STRING, 0004, FMT_A, 1)
 DEFFMT (FMT_AHEX,        "AHEX",      1,  2, 510,  2,  510, 0006, FMT_A, 2)
 DEFFMT (FMT_IB,                  "IB",        2,  1,   8,  1,    8, 0010, FMT_F, 6)
 DEFFMT (FMT_P,           "P",         2,  1,  16,  1,   16, 0011, FMT_F, 8)
 DEFFMT (FMT_AHEX,        "AHEX",      1,  2, 510,  2,  510, 0006, FMT_A, 2)
 DEFFMT (FMT_IB,                  "IB",        2,  1,   8,  1,    8, 0010, FMT_F, 6)
 DEFFMT (FMT_P,           "P",         2,  1,  16,  1,   16, 0011, FMT_F, 8)
index edf7f64860fb04dcba27b5213dca347a875f3229..9a7179129e684eabd62c05236de73476872fbf75 100644 (file)
@@ -107,8 +107,6 @@ enum fmt_parse_flags
 /* Common formats. */
 extern const struct fmt_spec f8_2;      /* F8.2. */
 
 /* Common formats. */
 extern const struct fmt_spec f8_2;      /* F8.2. */
 
-int parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags);
-int parse_format_specifier_name (const char **cp, enum fmt_parse_flags);
 int check_input_specifier (const struct fmt_spec *spec, int emit_error);
 int check_output_specifier (const struct fmt_spec *spec, int emit_error);
 bool check_specifier_type (const struct fmt_spec *, int type, bool emit_error);
 int check_input_specifier (const struct fmt_spec *spec, int emit_error);
 int check_output_specifier (const struct fmt_spec *spec, int emit_error);
 bool check_specifier_type (const struct fmt_spec *, int type, bool emit_error);
index 1c951d8ecbea2d974a573c3ff6a3db2b037fcc4a..7ed15adfacee03c48325fd1e032c809c4f680efa 100644 (file)
@@ -59,7 +59,7 @@ struct sysfile_header
     char rec_type[4] P;                /* 00: Record-type code, "$FL2". */
     char prod_name[60] P;      /* 04: Product identification. */
     int32_t layout_code P;     /* 40: 2. */
     char rec_type[4] P;                /* 00: Record-type code, "$FL2". */
     char prod_name[60] P;      /* 04: Product identification. */
     int32_t layout_code P;     /* 40: 2. */
-    int32_t case_size P;       /* 44: Number of `value's per case. 
+    int32_t nominal_case_size P;       /* 44: Number of `value's per case. 
                                   Note: some systems set this to -1 */
     int32_t compress P;                /* 48: 1=compressed, 0=not compressed. */
     int32_t weight_idx P;         /* 4c: 1-based index of weighting var, or 0. */
                                   Note: some systems set this to -1 */
     int32_t compress P;                /* 48: 1=compressed, 0=not compressed. */
     int32_t weight_idx P;         /* 4c: 1-based index of weighting var, or 0. */
index 4c69d2bfa295cec42b33b347c032ffbfabe988fb..feca9498610065a018b85e5fdb19c551cb8e0ab9 100644 (file)
@@ -30,6 +30,7 @@
 #include <libpspp/magic.h>
 #include <libpspp/misc.h>
 #include <libpspp/str.h>
 #include <libpspp/magic.h>
 #include <libpspp/misc.h>
 #include <libpspp/str.h>
+#include <libpspp/hash.h>
 
 #include "sys-file-reader.h"
 #include "sfm-private.h"
 
 #include "sys-file-reader.h"
 #include "sfm-private.h"
 #include "format.h"
 #include "value-labels.h"
 #include "variable.h"
 #include "format.h"
 #include "value-labels.h"
 #include "variable.h"
+#include "value.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 /* System file reader. */
 struct sfm_reader
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
 /* System file reader. */
 struct sfm_reader
-  {
-    struct file_handle *fh;     /* File handle. */
-    FILE *file;                        /* File stream. */
-
-    int reverse_endian;                /* 1=file has endianness opposite us. */
-    int fix_specials;           /* 1=SYSMIS/HIGHEST/LOWEST differs from us. */
-    int value_cnt;             /* Number of `union values's per case. */
-    long case_cnt;             /* Number of cases, -1 if unknown. */
-    int compressed;            /* 1=compressed, 0=not compressed. */
-    double bias;               /* Compression bias, usually 100.0. */
-    int weight_idx;            /* 0-based index of weighting variable, or -1. */
-    bool ok;                    /* False after an I/O error or corrupt data. */
-
-    /* Variables. */
-    struct sfm_var *vars;       /* Variables. */
-
-    /* File's special constants. */
-    flt64 sysmis;
-    flt64 highest;
-    flt64 lowest;
-
-    /* Decompression buffer. */
-    flt64 *buf;                        /* Buffer data. */
-    flt64 *ptr;                        /* Current location in buffer. */
-    flt64 *end;                        /* End of buffer data. */
-
-    /* Compression instruction octet. */
-    unsigned char x[8];         /* Current instruction octet. */
-    unsigned char *y;          /* Location in current instruction octet. */
-  };
+{
+  struct file_handle *fh;     /* File handle. */
+  FILE *file;                  /* File stream. */
+
+  int reverse_endian;          /* 1=file has endianness opposite us. */
+  int fix_specials;           /* 1=SYSMIS/HIGHEST/LOWEST differs from us. */
+  int value_cnt;               /* Number of `union values's per case. */
+  long case_cnt;               /* Number of cases, -1 if unknown. */
+  int compressed;              /* 1=compressed, 0=not compressed. */
+  double bias;         /* Compression bias, usually 100.0. */
+  int weight_idx;              /* 0-based index of weighting variable, or -1. */
+  bool ok;                    /* False after an I/O error or corrupt data. */
+
+  /* Variables. */
+  struct sfm_var *vars;       /* Variables. */
+
+  /* File's special constants. */
+  flt64 sysmis;
+  flt64 highest;
+  flt64 lowest;
+
+  /* Decompression buffer. */
+  flt64 *buf;                  /* Buffer data. */
+  flt64 *ptr;                  /* Current location in buffer. */
+  flt64 *end;                  /* End of buffer data. */
+
+  /* Compression instruction octet. */
+  unsigned char x[8];         /* Current instruction octet. */
+  unsigned char *y;            /* Location in current instruction octet. */
+};
 
 /* A variable in a system file. */
 struct sfm_var 
 
 /* A variable in a system file. */
 struct sfm_var 
-  {
-    int width;                  /* 0=numeric, otherwise string width. */
-    int fv;                     /* Index into case. */
-  };
+{
+  int width;                  /* 0=numeric, otherwise string width. */
+  int fv;                     /* Index into case. */
+};
 \f
 /* Utilities. */
 
 \f
 /* Utilities. */
 
@@ -119,9 +121,9 @@ static void
 corrupt_msg (int class, const char *format,...)
      PRINTF_FORMAT (2, 3);
 
 corrupt_msg (int class, const char *format,...)
      PRINTF_FORMAT (2, 3);
 
-/* Displays a corrupt sysfile error. */
-static void
-corrupt_msg (int class, const char *format,...)
+     /* Displays a corrupt sysfile error. */
+     static void
+     corrupt_msg (int class, const char *format,...)
 {
   struct msg m;
   va_list args;
 {
   struct msg m;
   va_list args;
@@ -158,7 +160,7 @@ sfm_close_reader (struct sfm_reader *r)
 
   if (r->fh != NULL)
     fh_close (r->fh, "system file", "rs");
 
   if (r->fh != NULL)
     fh_close (r->fh, "system file", "rs");
-  
+
   free (r->vars);
   free (r->buf);
   free (r);
   free (r->vars);
   free (r->buf);
   free (r);
@@ -201,6 +203,36 @@ static int fread_ok (struct sfm_reader *, void *, size_t);
              goto error;                       \
        } while (0)
 
              goto error;                       \
        } while (0)
 
+
+struct name_pair
+{
+  char *shortname;
+  char *longname;
+};
+
+static int
+pair_sn_compare(const void *_p1, const void *_p2, void *aux UNUSED)
+{
+  const struct name_pair *p1 = _p1;
+  const struct name_pair *p2 = _p2;
+  
+  return strcmp(p1->shortname, p2->shortname);
+}
+
+static unsigned
+pair_sn_hash(const void *_p, void *aux UNUSED)
+{
+  const struct name_pair *p = _p;
+  return hsh_hash_bytes(p->shortname, strlen(p->shortname));
+}
+
+static void
+pair_sn_free(void *p, void *aux UNUSED)
+{
+  free(p);
+}
+
+
 /* Opens the system file designated by file handle FH for
    reading.  Reads the system file's dictionary into *DICT.
    If INFO is non-null, then it receives additional info about the
 /* Opens the system file designated by file handle FH for
    reading.  Reads the system file's dictionary into *DICT.
    If INFO is non-null, then it receives additional info about the
@@ -212,6 +244,9 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
   struct sfm_reader *r = NULL;
   struct variable **var_by_idx = NULL;
 
   struct sfm_reader *r = NULL;
   struct variable **var_by_idx = NULL;
 
+  /* A hash table of long variable names indexed by short name */
+  struct hsh_table *short_to_long = NULL;
+
   *dict = dict_create ();
   if (!fh_open (fh, FH_REF_FILE, "system file", "rs"))
     goto error;
   *dict = dict_create ();
   if (!fh_open (fh, FH_REF_FILE, "system file", "rs"))
     goto error;
@@ -269,7 +304,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
       if (weight_var == NULL)
        lose ((ME,
                _("%s: Weighting variable may not be a continuation of "
       if (weight_var == NULL)
        lose ((ME,
                _("%s: Weighting variable may not be a continuation of "
-              "a long string variable."), fh_get_file_name (fh)));
+                "a long string variable."), fh_get_file_name (fh)));
       else if (weight_var->type == ALPHA)
        lose ((ME, _("%s: Weighting variable may not be a string variable."),
               fh_get_file_name (fh)));
       else if (weight_var->type == ALPHA)
        lose ((ME, _("%s: Weighting variable may not be a string variable."),
               fh_get_file_name (fh)));
@@ -288,6 +323,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
       if (r->reverse_endian)
        bswap_int32 (&rec_type);
 
       if (r->reverse_endian)
        bswap_int32 (&rec_type);
 
+
       switch (rec_type)
        {
        case 3:
       switch (rec_type)
        {
        case 3:
@@ -309,11 +345,11 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
        case 7:
          {
            struct
        case 7:
          {
            struct
-             {
-               int32_t subtype P;
-               int32_t size P;
-               int32_t count P;
-             }
+           {
+             int32_t subtype P;
+             int32_t size P;
+             int32_t count P;
+           }
            data;
             unsigned long bytes;
 
            data;
             unsigned long bytes;
 
@@ -327,6 +363,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                bswap_int32 (&data.count);
              }
             bytes = data.size * data.count;
                bswap_int32 (&data.count);
              }
             bytes = data.size * data.count;
+
             if (bytes < data.size || bytes < data.count)
               lose ((ME, "%s: Record type %d subtype %d too large.",
                      fh_get_file_name (r->fh), rec_type, data.subtype));
             if (bytes < data.size || bytes < data.count)
               lose ((ME, "%s: Record type %d subtype %d too large.",
                      fh_get_file_name (r->fh), rec_type, data.subtype));
@@ -352,12 +389,13 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                {
                  const int  n_vars = data.count / 3 ;
                  int i;
                {
                  const int  n_vars = data.count / 3 ;
                  int i;
-                 if ( data.count % 3 || n_vars > dict_get_var_cnt(*dict) ) 
+                 if ( data.count % 3 || n_vars != dict_get_var_cnt(*dict) ) 
                    {
                      msg (MW, _("%s: Invalid subrecord length. "
                                 "Record: 7; Subrecord: 11"), 
                           fh_get_file_name (r->fh));
                      skip = 1;
                    {
                      msg (MW, _("%s: Invalid subrecord length. "
                                 "Record: 7; Subrecord: 11"), 
                           fh_get_file_name (r->fh));
                      skip = 1;
+                     break;
                    }
 
                  for ( i = 0 ; i < min(n_vars, dict_get_var_cnt(*dict)) ; ++i ) 
                    }
 
                  for ( i = 0 ; i < min(n_vars, dict_get_var_cnt(*dict)) ; ++i ) 
@@ -397,11 +435,18 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                     }
                  buf[bytes] = '\0';
 
                     }
                  buf[bytes] = '\0';
 
+                 short_to_long = hsh_create(4, 
+                                            pair_sn_compare,
+                                            pair_sn_hash,
+                                            pair_sn_free, 
+                                            0);
+
                   /* Parse data. */
                  for (short_name = strtok_r (buf, "=", &save_ptr), idx = 0;
                        short_name != NULL;
                        short_name = strtok_r (NULL, "=", &save_ptr), idx++)
                    {
                   /* Parse data. */
                  for (short_name = strtok_r (buf, "=", &save_ptr), idx = 0;
                        short_name != NULL;
                        short_name = strtok_r (NULL, "=", &save_ptr), idx++)
                    {
+                     struct name_pair *pair ;
                       char *long_name = strtok_r (NULL, "\t", &save_ptr);
                       struct variable *v;
 
                       char *long_name = strtok_r (NULL, "\t", &save_ptr);
                       struct variable *v;
 
@@ -433,7 +478,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
 
                       /* Identify any duplicates. */
                      if ( compare_var_names(short_name, long_name, 0) &&
 
                       /* Identify any duplicates. */
                      if ( compare_var_names(short_name, long_name, 0) &&
-                         NULL != dict_lookup_var (*dict, long_name))
+                          NULL != dict_lookup_var (*dict, long_name))
                         lose ((ME, _("%s: Duplicate long variable name `%s' "
                                      "within system file."),
                                fh_get_file_name (r->fh), long_name));
                         lose ((ME, _("%s: Duplicate long variable name `%s' "
                                      "within system file."),
                                fh_get_file_name (r->fh), long_name));
@@ -446,6 +491,17 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                       dict_rename_var (*dict, v, long_name);
                       var_set_short_name (v, short_name);
 
                       dict_rename_var (*dict, v, long_name);
                       var_set_short_name (v, short_name);
 
+                     pair = xmalloc(sizeof *pair);
+                     pair->shortname = short_name;
+                     pair->longname = long_name;
+                     hsh_insert(short_to_long, pair);
+#if 0 
+      /* This messes up the processing of subtype 14 (below).
+        I'm not sure if it is needed anyway, so I'm removing it for
+        now.  If it's needed, then it will need to be done after all the
+        records have been processed. --- JMD 27 April 2006
+      */
+                     
                       /* For compatability, make sure dictionary
                          is in long variable name map order.  In
                          the common case, this has no effect,
                       /* For compatability, make sure dictionary
                          is in long variable name map order.  In
                          the common case, this has no effect,
@@ -453,13 +509,122 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
                          variable name map are already in the
                          same order. */
                       dict_reorder_var (*dict, v, idx);
                          variable name map are already in the
                          same order. */
                       dict_reorder_var (*dict, v, idx);
+#endif
                    }
                    }
+                 
 
                  /* Free data. */
                  free (buf);
                }
                break;
 
 
                  /* Free data. */
                  free (buf);
                }
                break;
 
+             case 14:
+               {
+                 int j = 0;
+                 bool eq_seen = false;
+                 int i;
+
+                  /* Read data. */
+                  char *buf = xmalloc (bytes + 1);
+                 if (!buf_read (r, buf, bytes, 0)) 
+                    {
+                      free (buf);
+                      goto error;
+                    }
+                 buf[bytes] = '\0';
+
+
+                 /* Note:  SPSS v13 terminates this record with 00,
+                    whereas SPSS v14 terminates it with 00 09. We must
+                    accept either */ 
+                 for(i = 0; i < bytes ; ++i)
+                   {
+                     long int length;
+                     static char name[SHORT_NAME_LEN + 1];
+                     static char len_str[6];
+
+                     switch( buf[i] )
+                       {
+                       case '=':
+                         eq_seen = true;
+                         j = 0;
+                         break;
+                       case '\0':
+                         length = strtol(len_str, 0, 10);
+                         if ( length != LONG_MAX && length != LONG_MIN) 
+                           {
+                             char *lookup_name = name;
+                             int l;
+                             int idx;
+                             struct variable *v;
+
+                             if ( short_to_long ) 
+                               {
+                                 struct name_pair pair;
+                                 struct name_pair *p;
+
+                                 pair.shortname = name;
+                                 p = hsh_find(short_to_long, &pair);
+                                 if ( p ) 
+                                   lookup_name = p->longname;
+                               }
+                               
+                             
+                             v = dict_lookup_var(*dict, lookup_name);
+                             if ( !v ) 
+                               {
+                                 corrupt_msg(MW, 
+                                             _("%s: No variable called %s but it is listed in length table."),
+                                             fh_get_file_name (r->fh), lookup_name);
+
+                                 goto error;
+
+                               }
+                             
+                             l = length;
+                             if ( v->width > EFFECTIVE_LONG_STRING_LENGTH ) 
+                               l -= EFFECTIVE_LONG_STRING_LENGTH;
+                             else
+                               l -= v->width;
+
+                             idx = v->index;
+                             while ( l > 0 ) 
+                               {
+                                 struct variable *v_next;
+                                 v_next = dict_get_var(*dict, idx + 1);
+
+                                 if ( v_next->width > EFFECTIVE_LONG_STRING_LENGTH ) 
+                                   l -= EFFECTIVE_LONG_STRING_LENGTH;
+                                 else
+                                   l -= v_next->width;
+
+                                 dict_delete_var(*dict, v_next);
+                               }
+                             
+                             v->width = length;
+                             v->print.w = v->width;
+                             v->write.w = v->width;
+                           }
+                         eq_seen = false;
+                         memset(name, 0, SHORT_NAME_LEN+1); 
+                         memset(len_str, 0, 6); 
+                         j = 0;
+                         break;
+                       case '\t':
+                         break;
+                       default:
+                         if ( eq_seen ) 
+                           len_str[j] = buf[i];
+                         else
+                           name[j] = buf[i];
+                         j++;
+                         break;
+                       }
+                   }
+                 free(buf);
+               }
+               break;
+
              default:
                msg (MW, _("%s: Unrecognized record type 7, subtype %d "
                            "encountered in system file."),
              default:
                msg (MW, _("%s: Unrecognized record type 7, subtype %d "
                            "encountered in system file."),
@@ -482,24 +647,29 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
            int32_t filler;
 
            assertive_buf_read (r, &filler, sizeof filler, 0);
            int32_t filler;
 
            assertive_buf_read (r, &filler, sizeof filler, 0);
+
            goto success;
          }
 
        default:
          corrupt_msg(MW, _("%s: Unrecognized record type %d."),
            goto success;
          }
 
        default:
          corrupt_msg(MW, _("%s: Unrecognized record type %d."),
-                 fh_get_file_name (r->fh), rec_type);
+                     fh_get_file_name (r->fh), rec_type);
        }
     }
 
        }
     }
 
-success:
+ success:
   /* Come here on successful completion. */
   /* Come here on successful completion. */
+
+
   free (var_by_idx);
   free (var_by_idx);
+  hsh_destroy(short_to_long);
   return r;
 
   return r;
 
-error:
+ error:
   /* Come here on unsuccessful completion. */
   sfm_close_reader (r);
   free (var_by_idx);
   /* Come here on unsuccessful completion. */
   sfm_close_reader (r);
   free (var_by_idx);
+  hsh_destroy(short_to_long);
   if (*dict != NULL) 
     {
       dict_destroy (*dict);
   if (*dict != NULL) 
     {
       dict_destroy (*dict);
@@ -550,7 +720,7 @@ read_machine_int32_info (struct sfm_reader *r, int size, int count)
           fh_get_file_name (r->fh),
            file_bigendian ? _("big-endian") : _("little-endian"),
           data[6] == 1 ? _("big-endian") : (data[6] == 2 ? _("little-endian")
           fh_get_file_name (r->fh),
            file_bigendian ? _("big-endian") : _("little-endian"),
           data[6] == 1 ? _("big-endian") : (data[6] == 2 ? _("little-endian")
-                                         : _("unknown"))));
+                                            : _("unknown"))));
 
   /* PORTME: Character representation code. */
   if (data[7] != 2 && data[7] != 3) 
 
   /* PORTME: Character representation code. */
   if (data[7] != 2 && data[7] != 3) 
@@ -562,7 +732,7 @@ read_machine_int32_info (struct sfm_reader *r, int size, int count)
 
   return 1;
 
 
   return 1;
 
-error:
+ error:
   return 0;
 }
 
   return 0;
 }
 
@@ -600,7 +770,7 @@ read_machine_flt64_info (struct sfm_reader *r, int size, int count)
   
   return 1;
 
   
   return 1;
 
-error:
+ error:
   return 0;
 }
 
   return 0;
 }
 
@@ -663,7 +833,7 @@ read_header (struct sfm_reader *r,
               fh_get_file_name (r->fh), hdr.layout_code));
 
       r->reverse_endian = 1;
               fh_get_file_name (r->fh), hdr.layout_code));
 
       r->reverse_endian = 1;
-      bswap_int32 (&hdr.case_size);
+      bswap_int32 (&hdr.nominal_case_size);
       bswap_int32 (&hdr.compress);
       bswap_int32 (&hdr.weight_idx);
       bswap_int32 (&hdr.case_cnt);
       bswap_int32 (&hdr.compress);
       bswap_int32 (&hdr.weight_idx);
       bswap_int32 (&hdr.case_cnt);
@@ -672,7 +842,7 @@ read_header (struct sfm_reader *r,
 
 
   /* Copy basic info and verify correctness. */
 
 
   /* Copy basic info and verify correctness. */
-  r->value_cnt = hdr.case_size;
+  r->value_cnt = hdr.nominal_case_size;
 
   /* If value count is rediculous, then force it to -1 (a sentinel value) */
   if ( r->value_cnt < 0 || 
 
   /* If value count is rediculous, then force it to -1 (a sentinel value) */
   if ( r->value_cnt < 0 || 
@@ -743,7 +913,7 @@ read_header (struct sfm_reader *r,
 
   return 1;
 
 
   return 1;
 
-error:
+ error:
   return 0;
 }
 
   return 0;
 }
 
@@ -781,9 +951,6 @@ read_variables (struct sfm_reader *r,
       int nv;
       int j;
 
       int nv;
       int j;
 
-      if ( r->value_cnt != -1  && i >= r->value_cnt ) 
-       break;
-
       assertive_buf_read (r, &sv, sizeof sv, 0);
 
       if (r->reverse_endian)
       assertive_buf_read (r, &sv, sizeof sv, 0);
 
       if (r->reverse_endian)
@@ -804,11 +971,8 @@ read_variables (struct sfm_reader *r,
          break;
        }
 
          break;
        }
 
-      if ( -1 == r->value_cnt ) 
-       {
-         *var_by_idx = xnrealloc (*var_by_idx, i + 1, sizeof **var_by_idx);
-         r->vars = xnrealloc (r->vars, i + 1, sizeof *r->vars);
-       }
+      *var_by_idx = xnrealloc (*var_by_idx, i + 1, sizeof **var_by_idx);
+      r->vars = xnrealloc (r->vars, i + 1, sizeof *r->vars);
 
       /* If there was a long string previously, make sure that the
         continuations are present; otherwise make sure there aren't
 
       /* If there was a long string previously, make sure that the
         continuations are present; otherwise make sure there aren't
@@ -837,7 +1001,7 @@ read_variables (struct sfm_reader *r,
               fh_get_file_name (r->fh), i, sv.type));
       if (sv.has_var_label != 0 && sv.has_var_label != 1)
        lose ((ME, _("%s: position %d: Variable label indicator field is not "
               fh_get_file_name (r->fh), i, sv.type));
       if (sv.has_var_label != 0 && sv.has_var_label != 1)
        lose ((ME, _("%s: position %d: Variable label indicator field is not "
-              "0 or 1."), fh_get_file_name (r->fh), i));
+                    "0 or 1."), fh_get_file_name (r->fh), i));
       if (sv.n_missing_values < -3 || sv.n_missing_values > 3
          || sv.n_missing_values == -1)
        lose ((ME, _("%s: position %d: Missing value indicator field is not "
       if (sv.n_missing_values < -3 || sv.n_missing_values > 3
          || sv.n_missing_values == -1)
        lose ((ME, _("%s: position %d: Missing value indicator field is not "
@@ -873,6 +1037,7 @@ read_variables (struct sfm_reader *r,
         lose ((ME, _("%s: Duplicate variable name `%s' within system file."),
                fh_get_file_name (r->fh), name));
 
         lose ((ME, _("%s: Duplicate variable name `%s' within system file."),
                fh_get_file_name (r->fh), name));
 
+      /* Set the short name the same as the long name */
       var_set_short_name (vv, vv->name);
 
       /* Case reading data. */
       var_set_short_name (vv, vv->name);
 
       /* Case reading data. */
@@ -968,13 +1133,13 @@ read_variables (struct sfm_reader *r,
 
   if (next_value != r->value_cnt)
     corrupt_msg(MW, _("%s: System file header indicates %d variable positions but "
 
   if (next_value != r->value_cnt)
     corrupt_msg(MW, _("%s: System file header indicates %d variable positions but "
-                 "%d were read from file."),
-           fh_get_file_name (r->fh), r->value_cnt, next_value);
+                     "%d were read from file."),
+               fh_get_file_name (r->fh), r->value_cnt, next_value);
 
 
   return 1;
 
 
 
   return 1;
 
-error:
+ error:
   return 0;
 }
 
   return 0;
 }
 
@@ -1009,7 +1174,7 @@ parse_format_spec (struct sfm_reader *r, int32_t s,
     }
   return 1;
 
     }
   return 1;
 
-error:
+ error:
   return 0;
 }
 
   return 0;
 }
 
@@ -1020,11 +1185,11 @@ read_value_labels (struct sfm_reader *r,
                    struct dictionary *dict, struct variable **var_by_idx)
 {
   struct label 
                    struct dictionary *dict, struct variable **var_by_idx)
 {
   struct label 
-    {
-      char raw_value[8];        /* Value as uninterpreted bytes. */
-      union value value;        /* Value. */
-      char *label;              /* Null-terminated label string. */
-    };
+  {
+    char raw_value[8];        /* Value as uninterpreted bytes. */
+    union value value;        /* Value. */
+    char *label;              /* Null-terminated label string. */
+  };
 
   struct label *labels = NULL;
   int32_t n_labels;            /* Number of labels. */
 
   struct label *labels = NULL;
   int32_t n_labels;            /* Number of labels. */
@@ -1194,7 +1359,7 @@ read_value_labels (struct sfm_reader *r,
   free (var);
   return 1;
 
   free (var);
   return 1;
 
-error:
+ error:
   if (labels) 
     {
       for (i = 0; i < n_labels; i++)
   if (labels) 
     {
       for (i = 0; i < n_labels; i++)
@@ -1232,6 +1397,7 @@ buf_read (struct sfm_reader *r, void *buf, size_t byte_cnt, size_t min_alloc)
       r->ok = false;
       return NULL;
     }
       r->ok = false;
       return NULL;
     }
+
   return buf;
 }
 
   return buf;
 }
 
@@ -1277,7 +1443,7 @@ read_documents (struct sfm_reader *r, struct dictionary *dict)
   free (documents);
   return 1;
 
   free (documents);
   return 1;
 
-error:
+ error:
   return 0;
 }
 \f
   return 0;
 }
 \f
@@ -1398,13 +1564,13 @@ read_compressed_data (struct sfm_reader *r, flt64 *buf)
 
   abort ();
 
 
   abort ();
 
-success:
+ success:
   /* We have filled up an entire record.  Update state and return
      successfully. */
   r->y = ++p;
   return 1;
 
   /* We have filled up an entire record.  Update state and return
      successfully. */
   r->y = ++p;
   return 1;
 
-error:
+ error:
   /* I/O error. */
   r->ok = false;
   return 0;
   /* I/O error. */
   r->ok = false;
   return 0;
index 690a485909d25dfb0304575f0fd89f1f88114855..89a513d03b6539b6bd6dbd1d2fd588a35b314e67 100644 (file)
@@ -72,6 +72,8 @@ struct sfm_writer
     /* Variables. */
     struct sfm_var *vars;       /* Variables. */
     size_t var_cnt;             /* Number of variables. */
     /* Variables. */
     struct sfm_var *vars;       /* Variables. */
     size_t var_cnt;             /* Number of variables. */
+    size_t var_cnt_vls;         /* Number of variables including 
+                                  very long string components. */
   };
 
 /* A variable in a system file. */
   };
 
 /* A variable in a system file. */
@@ -85,7 +87,7 @@ struct sfm_var
 static char *append_string_max (char *, const char *, const char *);
 static void write_header (struct sfm_writer *, const struct dictionary *);
 static void buf_write (struct sfm_writer *, const void *, size_t);
 static char *append_string_max (char *, const char *, const char *);
 static void write_header (struct sfm_writer *, const struct dictionary *);
 static void buf_write (struct sfm_writer *, const void *, size_t);
-static void write_variable (struct sfm_writer *, struct variable *);
+static void write_variable (struct sfm_writer *, const struct variable *);
 static void write_value_labels (struct sfm_writer *,
                                 struct variable *, int idx);
 static void write_rec_7_34 (struct sfm_writer *);
 static void write_value_labels (struct sfm_writer *,
                                 struct variable *, int idx);
 static void write_rec_7_34 (struct sfm_writer *);
@@ -93,6 +95,10 @@ static void write_rec_7_34 (struct sfm_writer *);
 static void write_longvar_table (struct sfm_writer *w, 
                                  const struct dictionary *dict);
 
 static void write_longvar_table (struct sfm_writer *w, 
                                  const struct dictionary *dict);
 
+static void write_vls_length_table (struct sfm_writer *w, 
+                             const struct dictionary *dict);
+
+
 static void write_variable_display_parameters (struct sfm_writer *w, 
                                                const struct dictionary *dict);
 
 static void write_variable_display_parameters (struct sfm_writer *w, 
                                                const struct dictionary *dict);
 
@@ -101,10 +107,18 @@ static int does_dict_need_translation (const struct dictionary *);
 
 static inline int
 var_flt64_cnt (const struct variable *v) 
 
 static inline int
 var_flt64_cnt (const struct variable *v) 
+{
+  assert(sizeof(flt64) == MAX_SHORT_STRING);
+  return width_to_bytes(v->width) / MAX_SHORT_STRING ;
+}
+
+static inline int
+var_flt64_cnt_nom (const struct variable *v) 
 {
   return v->type == NUMERIC ? 1 : DIV_RND_UP (v->width, sizeof (flt64));
 }
 
 {
   return v->type == NUMERIC ? 1 : DIV_RND_UP (v->width, sizeof (flt64));
 }
 
+
 /* Returns default options for writing a system file. */
 struct sfm_write_options
 sfm_writer_default_options (void) 
 /* Returns default options for writing a system file. */
 struct sfm_write_options
 sfm_writer_default_options (void) 
@@ -116,6 +130,28 @@ sfm_writer_default_options (void)
   return opts;
 }
 
   return opts;
 }
 
+
+/* Return a short variable name to be used as the continuation of the
+   variable with the short name SN.
+
+   FIXME: Need to resolve clashes somehow.
+
+ */
+static const char *
+cont_var_name(const char *sn, int idx)
+{
+  static char s[SHORT_NAME_LEN + 1];
+
+  char abb[SHORT_NAME_LEN + 1 - 3]= {0}; 
+
+  strncpy(abb, sn, SHORT_NAME_LEN - 3);
+
+  snprintf(s, SHORT_NAME_LEN + 1, "%s%03d", abb, idx);
+
+  return s;
+}
+
+
 /* Opens the system file designated by file handle FH for writing
    cases from dictionary D according to the given OPTS.  If
    COMPRESS is nonzero, the system file will be compressed.
 /* Opens the system file designated by file handle FH for writing
    cases from dictionary D according to the given OPTS.  If
    COMPRESS is nonzero, the system file will be compressed.
@@ -167,12 +203,17 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d,
   w->x = w->y = NULL;
 
   w->var_cnt = dict_get_var_cnt (d);
   w->x = w->y = NULL;
 
   w->var_cnt = dict_get_var_cnt (d);
+  w->var_cnt_vls = w->var_cnt;
   w->vars = xnmalloc (w->var_cnt, sizeof *w->vars);
   for (i = 0; i < w->var_cnt; i++) 
     {
       const struct variable *dv = dict_get_var (d, i);
       struct sfm_var *sv = &w->vars[i];
       sv->width = dv->width;
   w->vars = xnmalloc (w->var_cnt, sizeof *w->vars);
   for (i = 0; i < w->var_cnt; i++) 
     {
       const struct variable *dv = dict_get_var (d, i);
       struct sfm_var *sv = &w->vars[i];
       sv->width = dv->width;
+      /* spss compatibility nonsense */
+      if ( dv->width > MAX_LONG_STRING ) 
+       sv->width = (dv->width / MAX_LONG_STRING) * (MAX_LONG_STRING + 1)
+         + (dv->width % MAX_LONG_STRING) ;
       sv->fv = dv->fv;
       sv->flt64_cnt = var_flt64_cnt (dv);
     }
       sv->fv = dv->fv;
       sv->flt64_cnt = var_flt64_cnt (dv);
     }
@@ -190,7 +231,42 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d,
   /* Write basic variable info. */
   dict_assign_short_names (d);
   for (i = 0; i < dict_get_var_cnt (d); i++)
   /* Write basic variable info. */
   dict_assign_short_names (d);
   for (i = 0; i < dict_get_var_cnt (d); i++)
-    write_variable (w, dict_get_var (d, i));
+    {
+      int count = 0;
+      const struct variable *v = dict_get_var(d, i);
+      int wcount = v->width;
+
+      do {
+       struct variable var_cont = *v;
+       if ( v->type == ALPHA) 
+         {
+           if ( 0 != count ) 
+             {
+               mv_init(&var_cont.miss, 0);
+               strcpy(var_cont.short_name,
+                      cont_var_name(v->short_name, count));
+               var_cont.label = NULL;
+               w->var_cnt_vls++;
+             }
+           count++;
+           if ( wcount > MAX_LONG_STRING ) 
+             {
+               var_cont.width = MAX_LONG_STRING;
+               wcount -= EFFECTIVE_LONG_STRING_LENGTH;
+             }
+           else
+             {
+               var_cont.width = wcount;
+               wcount -= var_cont.width;
+             }
+       
+           var_cont.write.w = var_cont.width;
+           var_cont.print.w = var_cont.width;
+         }
+
+       write_variable (w, &var_cont);
+      } while(wcount > 0);
+    }
 
   /* Write out value labels. */
   for (idx = i = 0; i < dict_get_var_cnt (d); i++)
 
   /* Write out value labels. */
   for (idx = i = 0; i < dict_get_var_cnt (d); i++)
@@ -211,6 +287,8 @@ sfm_open_writer (struct file_handle *fh, struct dictionary *d,
   if (opts.version >= 3) 
     write_longvar_table (w, d);
 
   if (opts.version >= 3) 
     write_longvar_table (w, d);
 
+  write_vls_length_table(w, d);
+
   /* Write end-of-headers record. */
   {
     struct
   /* Write end-of-headers record. */
   {
     struct
@@ -300,8 +378,10 @@ write_header (struct sfm_writer *w, const struct dictionary *d)
 
   w->flt64_cnt = 0;
   for (i = 0; i < dict_get_var_cnt (d); i++)
 
   w->flt64_cnt = 0;
   for (i = 0; i < dict_get_var_cnt (d); i++)
-    w->flt64_cnt += var_flt64_cnt (dict_get_var (d, i));
-  hdr.case_size = w->flt64_cnt;
+    {
+      w->flt64_cnt += var_flt64_cnt (dict_get_var (d, i));
+    }
+  hdr.nominal_case_size = w->flt64_cnt;
 
   hdr.compress = w->compress;
 
 
   hdr.compress = w->compress;
 
@@ -370,15 +450,16 @@ write_header (struct sfm_writer *w, const struct dictionary *d)
 /* Translates format spec from internal form in SRC to system file
    format in DEST. */
 static inline void
 /* Translates format spec from internal form in SRC to system file
    format in DEST. */
 static inline void
-write_format_spec (struct fmt_spec *src, int32_t *dest)
+write_format_spec (const struct fmt_spec *src, int32_t *dest)
 {
 {
+  assert(check_output_specifier(src, true));
   *dest = (formats[src->type].spss << 16) | (src->w << 8) | src->d;
 }
 
 /* Write the variable record(s) for primary variable P and secondary
    variable S to system file W. */
 static void
   *dest = (formats[src->type].spss << 16) | (src->w << 8) | src->d;
 }
 
 /* Write the variable record(s) for primary variable P and secondary
    variable S to system file W. */
 static void
-write_variable (struct sfm_writer *w, struct variable *v)
+write_variable (struct sfm_writer *w, const struct variable *v)
 {
   struct sysfile_variable sv;
 
 {
   struct sysfile_variable sv;
 
@@ -388,7 +469,7 @@ write_variable (struct sfm_writer *w, struct variable *v)
   int nm;               /* Number of missing values, possibly negative. */
 
   sv.rec_type = 2;
   int nm;               /* Number of missing values, possibly negative. */
 
   sv.rec_type = 2;
-  sv.type = v->width;
+  sv.type = min(v->width, MAX_LONG_STRING);
   sv.has_var_label = (v->label != NULL);
 
   mv_copy (&mv, &v->miss);
   sv.has_var_label = (v->label != NULL);
 
   mv_copy (&mv, &v->miss);
@@ -453,7 +534,8 @@ write_variable (struct sfm_writer *w, struct variable *v)
       memset (&sv.write, 0, sizeof sv.write);
       memset (&sv.name, 0, sizeof sv.name);
 
       memset (&sv.write, 0, sizeof sv.write);
       memset (&sv.name, 0, sizeof sv.name);
 
-      pad_count = DIV_RND_UP (v->width, (int) sizeof (flt64)) - 1;
+      pad_count = DIV_RND_UP (min(v->width, MAX_LONG_STRING),
+                             (int) sizeof (flt64)) - 1;
       for (i = 0; i < pad_count; i++)
        buf_write (w, &sv, sizeof sv);
     }
       for (i = 0; i < pad_count; i++)
        buf_write (w, &sv, sizeof sv);
     }
@@ -563,7 +645,7 @@ write_variable_display_parameters (struct sfm_writer *w,
   vdp_hdr.rec_type = 7;
   vdp_hdr.subtype = 11;
   vdp_hdr.elem_size = 4;
   vdp_hdr.rec_type = 7;
   vdp_hdr.subtype = 11;
   vdp_hdr.elem_size = 4;
-  vdp_hdr.n_elem = w->var_cnt * 3;
+  vdp_hdr.n_elem = w->var_cnt_vls * 3;
 
   buf_write (w, &vdp_hdr, sizeof vdp_hdr);
 
 
   buf_write (w, &vdp_hdr, sizeof vdp_hdr);
 
@@ -585,9 +667,70 @@ write_variable_display_parameters (struct sfm_writer *w,
       params.align = v->alignment;
       
       buf_write (w, &params, sizeof(params));
       params.align = v->alignment;
       
       buf_write (w, &params, sizeof(params));
+
+      if ( v->width > MAX_LONG_STRING ) 
+       {
+         int wcount = v->width - EFFECTIVE_LONG_STRING_LENGTH ;
+
+         while (wcount > 0) 
+           {
+             params.width = wcount > MAX_LONG_STRING ? 32 : wcount;
+           
+             buf_write (w, &params, sizeof(params));
+
+             wcount -= EFFECTIVE_LONG_STRING_LENGTH ;
+           } 
+       }
     }
 }
 
     }
 }
 
+/* Writes the table of lengths for Very Long String Variables */
+static void 
+write_vls_length_table (struct sfm_writer *w, 
+                       const struct dictionary *dict)
+{
+  int i;
+  struct
+    {
+      int32_t rec_type P;
+      int32_t subtype P;
+      int32_t elem_size P;
+      int32_t n_elem P;
+    }
+  vls_hdr;
+
+  struct string vls_length_map;
+
+  ds_init (&vls_length_map, 12 * dict_get_var_cnt (dict));
+
+  vls_hdr.rec_type = 7;
+  vls_hdr.subtype = 14;
+  vls_hdr.elem_size = 1;
+
+
+  for (i = 0; i < dict_get_var_cnt (dict); ++i)
+    {
+      const struct variable *v = dict_get_var (dict, i);
+      
+      if ( v->width <=  MAX_LONG_STRING ) 
+       continue;
+
+      ds_printf (&vls_length_map, "%s=%05d", v->short_name, v->width);
+      ds_putc (&vls_length_map, '\0');
+      ds_putc (&vls_length_map, '\t');
+    }
+
+  vls_hdr.n_elem = ds_length (&vls_length_map);
+
+  if ( vls_hdr.n_elem > 0 ) 
+    {
+      buf_write (w, &vls_hdr, sizeof vls_hdr);
+      buf_write (w, ds_data (&vls_length_map), ds_length (&vls_length_map));
+    }
+
+  ds_destroy (&vls_length_map);
+}
+
 /* Writes the long variable name table */
 static void
 write_longvar_table (struct sfm_writer *w, const struct dictionary *dict)
 /* Writes the long variable name table */
 static void
 write_longvar_table (struct sfm_writer *w, const struct dictionary *dict)
@@ -758,20 +901,28 @@ sfm_write_case (struct sfm_writer *w, const struct ccase *c)
          Write into a bounce buffer, then write to W. */
       flt64 *bounce;
       flt64 *bounce_cur;
          Write into a bounce buffer, then write to W. */
       flt64 *bounce;
       flt64 *bounce_cur;
+      flt64 *bounce_end;
       size_t bounce_size;
       size_t i;
 
       bounce_size = sizeof *bounce * w->flt64_cnt;
       bounce = bounce_cur = local_alloc (bounce_size);
       size_t bounce_size;
       size_t i;
 
       bounce_size = sizeof *bounce * w->flt64_cnt;
       bounce = bounce_cur = local_alloc (bounce_size);
+      bounce_end = bounce + bounce_size;
 
       for (i = 0; i < w->var_cnt; i++) 
         {
           struct sfm_var *v = &w->vars[i];
 
 
       for (i = 0; i < w->var_cnt; i++) 
         {
           struct sfm_var *v = &w->vars[i];
 
+         memset(bounce_cur, ' ', v->flt64_cnt * sizeof (flt64));
+
           if (v->width == 0) 
             *bounce_cur = case_num (c, v->fv);
           else 
           if (v->width == 0) 
             *bounce_cur = case_num (c, v->fv);
           else 
-            memcpy (bounce_cur, case_data (c, v->fv)->s, v->width);
+           {
+             buf_copy_rpad((char*)bounce_cur, v->flt64_cnt * sizeof (flt64),
+                           case_data(c, v->fv)->s, 
+                           v->width);
+           }
           bounce_cur += v->flt64_cnt;
         }
 
           bounce_cur += v->flt64_cnt;
         }
 
index 1fac59966657a8709b2811e967df99c7edd9a0f2..17f60bbd01bc40dd908dd2114fa3a6c983439968 100644 (file)
 /* Values. */
 
 /* Max length of a short string value, generally 8 chars. */
 /* Values. */
 
 /* Max length of a short string value, generally 8 chars. */
-#define MAX_SHORT_STRING ((SIZEOF_DOUBLE)>=8 ? ((SIZEOF_DOUBLE)+1)/2*2 : 8)
-#define MIN_LONG_STRING (MAX_SHORT_STRING+1)
+#define MAX_SHORT_STRING ( (SIZEOF_DOUBLE)>=8 ? (SIZEOF_DOUBLE + 1)/2 * 2 : 8 )
+
+#define MIN_LONG_STRING (MAX_SHORT_STRING + 1)
 
 /* Max string length. */
 
 /* Max string length. */
-#define MAX_STRING 255
+#define MAX_LONG_STRING 255
+
+/* This nonsense is required for SPSS compatibility */
+#define EFFECTIVE_LONG_STRING_LENGTH (MAX_LONG_STRING - 3)
+
+#define MAX_VERY_LONG_STRING 32767
+
+#define MAX_STRING MAX_VERY_LONG_STRING
+
 
 /* Special values. */
 #define SYSMIS (-DBL_MAX)
 
 /* Special values. */
 #define SYSMIS (-DBL_MAX)
index 6c1414832b7c992fe5301940a80e33aca794b29d..56993e461c5d43998105123767037bba1a9be16d 100644 (file)
@@ -350,3 +350,112 @@ dict_class_to_name (enum dict_class dict_class)
       abort ();
     }
 }
       abort ();
     }
 }
+
+
+/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
+   Each 256th byte, which is expected to be a ' ', is deleted.
+   DST is then truncated to DST_SIZE bytes or padded on the right with
+   spaces as needed. */
+void
+copy_demangle (char *dst, size_t dst_size,
+           const char *src, size_t src_size)
+{
+  int src_bytes_left = src_size;
+  int dst_bytes_left = dst_size;
+  const char *s = src;
+  char *d = dst;
+
+
+  while( src_bytes_left > 0 ) 
+    {
+      const size_t s_chunk = min(MAX_LONG_STRING, src_bytes_left);
+      const size_t d_chunk = min(MAX_LONG_STRING, dst_bytes_left);
+
+      assert ( d < dst + dst_size);
+
+      buf_copy_rpad (d, d_chunk,
+                    s, s_chunk);
+
+      d += d_chunk;
+      s += s_chunk;
+      src_bytes_left -= s_chunk;
+      dst_bytes_left -= d_chunk;
+
+      if ( src_bytes_left > 0 && ! (++s - src) % (MAX_LONG_STRING+1) )
+       {
+         if ( *s != ' ') 
+           msg(MW, _("Expected a space in very long string"));
+         src_bytes_left--;
+       }
+    }
+}
+
+/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes.
+   DST is rounded up to the nearest 8 byte boundary.
+   A space is inserted at each 256th byte.
+   DST is then truncated to DST_SIZE bytes or padded on the right with
+   spaces as needed. */
+void
+copy_mangle (char *dst, size_t dst_size,
+           const char *src, size_t src_size)
+{
+  int src_bytes_left = src_size;
+  int dst_bytes_left = dst_size;
+  const char *s = src;
+  char *d = dst;
+
+  memset(dst, ' ', dst_size);
+
+  while( src_bytes_left > 0 ) 
+    {
+      const size_t s_chunk = min(MAX_LONG_STRING, src_bytes_left);
+      const size_t d_chunk = min(MAX_LONG_STRING, dst_bytes_left);
+
+      buf_copy_rpad (d, d_chunk, s, s_chunk);
+
+      d += d_chunk;
+      s += s_chunk;
+      src_bytes_left -= s_chunk;
+      dst_bytes_left -= d_chunk;
+
+      if ( dst_bytes_left > 0 && 0 == ( d + 1 - dst ) % (MAX_LONG_STRING + 1) )
+       {
+         memset(d, ' ', 1);
+         d++;
+         dst_bytes_left--;
+       }
+    }
+}
+
+/* Return the number of bytes used when writing case_data for a variable 
+   of WIDTH */
+int
+width_to_bytes(int width)
+{
+  int bytes, mod8;
+
+  assert (width >= 0);
+
+  if ( width == 0 ) 
+    return MAX_SHORT_STRING ;
+
+  if ( width <= MAX_LONG_STRING) 
+    return MAX_SHORT_STRING * DIV_RND_UP(width, MAX_SHORT_STRING);
+
+  const int chunks = width / EFFECTIVE_LONG_STRING_LENGTH ;
+
+  const int remainder = width - (chunks * EFFECTIVE_LONG_STRING_LENGTH) ;
+
+  bytes =  remainder + (chunks * (MAX_LONG_STRING + 1) );
+
+  /* Round up to the nearest 8 */
+  mod8 = bytes % MAX_SHORT_STRING;
+
+  if ( mod8 ) 
+    bytes += MAX_SHORT_STRING - mod8;
+
+  assert( bytes % MAX_SHORT_STRING == 0 );
+
+  return bytes;
+}
+
index fa7c0d6df0dff6410e1e7f0d0aece0c959171a96..2dfe56482b4224b3ad79953a63af6c28ca709d47 100644 (file)
@@ -240,4 +240,16 @@ int parse_mixed_vars_pool (struct pool *,
 const char * var_to_string(const struct variable *var);
 
 
 const char * var_to_string(const struct variable *var);
 
 
+/* Two complementary functions for dealing with 
+   Very Long String variables */
+
+void copy_demangle (char *dst, size_t dst_size,
+                   const char *src, size_t src_size);
+
+void copy_mangle (char *dst, size_t dst_size,
+                 const char *src, size_t src_size);
+
+int width_to_bytes(int width);
+
+
 #endif /* !variable.h */
 #endif /* !variable.h */
index 7c486bc3553999bc1854972f92d87fe805a9efc2..ee9949b24529a5dab29137dd691c3c15cc8000f6 100644 (file)
@@ -1,3 +1,8 @@
+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.
 Mon May  1 18:21:19 2006  Ben Pfaff  <blp@gnu.org>
 
        Further clean up the CMD_* command result codes.
index 4e1f8a18c3b65efb25606e6e5926aa9e76e97cc6..a79c51ada6f452e7f21baa45225377bb7ba96fec 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
    Written by Ben Pfaff <blp@gnu.org>.
 
    This program is free software; you can redistribute it and/or
@@ -72,12 +72,12 @@ static struct cmd_list cmd;
 static int case_idx;
 
 /* Line buffer. */
 static int case_idx;
 
 /* Line buffer. */
-static char *line_buf;
+static struct string line_buffer;
 
 /* TTY-style output functions. */
 static unsigned n_lines_remaining (struct outp_driver *d);
 static unsigned n_chars_width (struct outp_driver *d);
 
 /* TTY-style output functions. */
 static unsigned n_lines_remaining (struct outp_driver *d);
 static unsigned n_chars_width (struct outp_driver *d);
-static void write_line (struct outp_driver *d, char *s);
+static void write_line (struct outp_driver *d, const char *s);
 
 /* Other functions. */
 static bool list_cases (struct ccase *, void *);
 
 /* Other functions. */
 static bool list_cases (struct ccase *, void *);
@@ -108,7 +108,7 @@ n_chars_width (struct outp_driver *d)
 /* Writes the line S at the current position and advances to the next
    line.  */
 static void
 /* Writes the line S at the current position and advances to the next
    line.  */
 static void
-write_line (struct outp_driver *d, char *s)
+write_line (struct outp_driver *d, const char *s)
 {
   struct outp_text text;
   
 {
   struct outp_text text;
   
@@ -227,7 +227,7 @@ cmd_list (void)
 
   case_idx = 0;
   ok = procedure_with_splits (write_all_headers, list_cases, NULL, NULL);
 
   case_idx = 0;
   ok = procedure_with_splits (write_all_headers, list_cases, NULL, NULL);
-  free (line_buf);
+  ds_destroy(&line_buffer);
 
   clean_up ();
 
 
   clean_up ();
 
@@ -597,7 +597,7 @@ determine_layout (void)
       d->cp_y += d->font_height;
     }
 
       d->cp_y += d->font_height;
     }
 
-  line_buf = xmalloc (max (1022, largest_page_width) + 2);
+  ds_init(&line_buffer, largest_page_width + 2);
 }
 
 /* Writes case C to output. */
 }
 
 /* Writes case C to output. */
@@ -617,10 +617,12 @@ list_cases (struct ccase *c, void *aux UNUSED)
        const struct list_ext *prc = d->prc;
        const int max_width = n_chars_width (d);
        int column;
        const struct list_ext *prc = d->prc;
        const int max_width = n_chars_width (d);
        int column;
-       int x = 0;
 
        if (!prc->header_rows)
 
        if (!prc->header_rows)
-         x = nsprintf (line_buf, "%8s: ", cmd.v_variables[0]->name);
+         {
+           ds_printf(&line_buffer, "%8s: ", cmd.v_variables[0]->name);
+         }
+       
       
        for (column = 0; column < cmd.n_variables; column++)
          {
       
        for (column = 0; column < cmd.n_variables; column++)
          {
@@ -632,7 +634,8 @@ list_cases (struct ccase *c, void *aux UNUSED)
            else
              width = v->print.w;
 
            else
              width = v->print.w;
 
-           if (width + x > max_width && x != 0)
+           if (width + ds_length(&line_buffer) > max_width && 
+               ds_length(&line_buffer) != 0)
              {
                if (!n_lines_remaining (d))
                  {
              {
                if (!n_lines_remaining (d))
                  {
@@ -640,31 +643,34 @@ list_cases (struct ccase *c, void *aux UNUSED)
                    write_header (d);
                  }
              
                    write_header (d);
                  }
              
-               line_buf[x] = 0;
-               write_line (d, line_buf);
+               write_line (d, ds_c_str(&line_buffer));
+               ds_clear(&line_buffer);
 
 
-               x = 0;
                if (!prc->header_rows)
                if (!prc->header_rows)
-                 x = nsprintf (line_buf, "%8s: ", v->name);
+                 {
+                   ds_printf (&line_buffer, "%8s: ", v->name);
+                 }
              }
 
            if (width > v->print.w)
              {
              }
 
            if (width > v->print.w)
              {
-               memset(&line_buf[x], ' ', width - v->print.w);
-               x += width - v->print.w;
+               ds_putc_multiple(&line_buffer, ' ', width - v->print.w);
              }
 
             if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
              }
 
             if ((formats[v->print.type].cat & FCAT_STRING) || v->fv != -1)
-             data_out (&line_buf[x], &v->print, case_data (c, v->fv));
+             {
+                data_out (ds_append_uninit(&line_buffer, v->print.w),
+                         &v->print, case_data (c, v->fv));
+             }
             else 
               {
                 union value case_idx_value;
                 case_idx_value.f = case_idx;
             else 
               {
                 union value case_idx_value;
                 case_idx_value.f = case_idx;
-                data_out (&line_buf[x], &v->print, &case_idx_value); 
+                data_out (ds_append_uninit(&line_buffer,v->print.w), 
+                         &v->print,   &case_idx_value); 
               }
               }
-           x += v->print.w;
-         
-           line_buf[x++] = ' ';
+
+           ds_putc(&line_buffer, ' ');
          }
       
        if (!n_lines_remaining (d))
          }
       
        if (!n_lines_remaining (d))
@@ -673,8 +679,8 @@ list_cases (struct ccase *c, void *aux UNUSED)
            write_header (d);
          }
              
            write_header (d);
          }
              
-       line_buf[x] = 0;
-       write_line (d, line_buf);
+       write_line (d, ds_c_str(&line_buffer));
+       ds_clear(&line_buffer);
       }
     else if (d->class == &html_class)
       {
       }
     else if (d->class == &html_class)
       {
index cd84482462e4e10d6610e494a3d68c9a750fb2b5..4283af25184ea858e42c617c48773a1ca550823b 100644 (file)
@@ -82,6 +82,8 @@ expr_evaluate_num (struct expression *e, const struct ccase *c, int case_idx)
   return d;
 }
 
   return d;
 }
 
+
+
 void
 expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx,
                    char *dst, size_t dst_size) 
 void
 expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx,
                    char *dst, size_t dst_size) 
@@ -91,7 +93,8 @@ expr_evaluate_str (struct expression *e, const struct ccase *c, int case_idx,
   assert (e->type == OP_string);
   assert ((dst == NULL) == (dst_size == 0));
   expr_evaluate (e, c, case_idx, &s);
   assert (e->type == OP_string);
   assert ((dst == NULL) == (dst_size == 0));
   expr_evaluate (e, c, case_idx, &s);
-  buf_copy_rpad (dst, dst_size, s.string, s.length);
+  
+  copy_mangle (dst, dst_size, s.string, s.length);
 }
 \f
 #include <language/lexer/lexer.h>
 }
 \f
 #include <language/lexer/lexer.h>
index 95ac1e0b53ab2c14fdf86c8d4412e840f7335283..717bc15ef39fd105175f28e5625f9873522f9855 100644 (file)
@@ -306,7 +306,7 @@ string function CONCAT (string a[n])
   struct fixed_string dst;
   size_t i;
 
   struct fixed_string dst;
   size_t i;
 
-  dst = alloc_string (e, 255);
+  dst = alloc_string (e, MAX_STRING);
   dst.length = 0;
   for (i = 0; i < n; i++)
     {
   dst.length = 0;
   for (i = 0; i < n; i++)
     {
@@ -314,8 +314,8 @@ string function CONCAT (string a[n])
       size_t copy_len;
 
       copy_len = src->length;
       size_t copy_len;
 
       copy_len = src->length;
-      if (dst.length + copy_len > 255)
-        copy_len = 255 - dst.length;
+      if (dst.length + copy_len > MAX_STRING)
+        copy_len = MAX_STRING - dst.length;
       memcpy (&dst.string[dst.length], src->string, copy_len);
       dst.length += copy_len;
     }
       memcpy (&dst.string[dst.length], src->string, copy_len);
       dst.length += copy_len;
     }
@@ -440,7 +440,7 @@ string function UPCASE (string s)
 absorb_miss string function LPAD (string s, n)
      expression e;
 {
 absorb_miss string function LPAD (string s, n)
      expression e;
 {
-  if (n < 0 || n > 255 || (int) n != n)
+  if (n < 0 || n > MAX_STRING || (int) n != n)
     return empty_string;
   else if (s.length >= n)
     return s;
     return empty_string;
   else if (s.length >= n)
     return s;
@@ -456,7 +456,7 @@ absorb_miss string function LPAD (string s, n)
 absorb_miss string function LPAD (string s, n, string c)
      expression e;
 {
 absorb_miss string function LPAD (string s, n, string c)
      expression e;
 {
-  if (n < 0 || n > 255 || (int) n != n || c.length != 1)
+  if (n < 0 || n > MAX_STRING || (int) n != n || c.length != 1)
     return empty_string;
   else if (s.length >= n)
     return s;
     return empty_string;
   else if (s.length >= n)
     return s;
@@ -472,7 +472,7 @@ absorb_miss string function LPAD (string s, n, string c)
 absorb_miss string function RPAD (string s, n)
      expression e;
 {
 absorb_miss string function RPAD (string s, n)
      expression e;
 {
-  if (n < 0 || n > 255 || (int) n != n)
+  if (n < 0 || n > MAX_STRING || (int) n != n)
     return empty_string;
   else if (s.length >= n)
     return s;
     return empty_string;
   else if (s.length >= n)
     return s;
@@ -488,7 +488,7 @@ absorb_miss string function RPAD (string s, n)
 absorb_miss string function RPAD (string s, n, string c)
      expression e;
 {
 absorb_miss string function RPAD (string s, n, string c)
      expression e;
 {
-  if (n < 0 || n > 255 || (int) n != n || c.length != 1)
+  if (n < 0 || n > MAX_STRING || (int) n != n || c.length != 1)
     return empty_string;
   else if (s.length >= n)
     return s;
     return empty_string;
   else if (s.length >= n)
     return s;
index 086ef3ce0e80b4b95bcd84cb132c7cba701f9f7c..fdd460824e6b5c9d0435c38d9a97665c8bc7c7b7 100644 (file)
@@ -1422,8 +1422,8 @@ expr_allocate_string_buffer (struct expression *e,
 {
   union any_node *n = pool_alloc (e->expr_pool, sizeof n->string);
   n->type = OP_string;
 {
   union any_node *n = pool_alloc (e->expr_pool, sizeof n->string);
   n->type = OP_string;
-  if (length > 255)
-    length = 255;
+  if (length > MAX_STRING)
+    length = MAX_STRING;
   n->string.s = copy_string (e, string, length);
   return n;
 }
   n->string.s = copy_string (e, string, length);
   return n;
 }
index 69a83b78676fe5f8ec6d1ceb73595461012ccf61..b539432eb1d9b457773d80fca2803851cc254170 100644 (file)
@@ -128,6 +128,11 @@ parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags flags)
              ds_c_str (&tokstr));
       return 0;
     }
              ds_c_str (&tokstr));
       return 0;
     }
+  if ( w > MAX_STRING )
+    {
+      msg (SE, _("String variable width may not exceed %d"), MAX_STRING);
+      return 0;
+    }
 
   cp = cp2;
   if (f->n_args > 1 && *cp == '.')
 
   cp = cp2;
   if (f->n_args > 1 && *cp == '.')
index 36d79d3afef7a2a25bf7cf7139195ade4f7267dc..007c1362e1b54d2e2be0bac1a5fe8bb0c7480f94 100644 (file)
@@ -88,4 +88,7 @@ void lex_negative_to_dash (void);
 void lex_reset_eof (void);
 void lex_skip_comment (void);
 
 void lex_reset_eof (void);
 void lex_skip_comment (void);
 
+int parse_format_specifier (struct fmt_spec *input, enum fmt_parse_flags);
+int parse_format_specifier_name (const char **cp, enum fmt_parse_flags);
+
 #endif /* !lexer_h */
 #endif /* !lexer_h */
index c8497c34af4fbf1dd57ace97d18d1ad72e60116c..613ecbc5455c69549c2880a3944ed124bfcaf502 100644 (file)
@@ -681,6 +681,22 @@ ds_concat (struct string *st, const char *buf, size_t len)
   st->length += len;
 }
 
   st->length += len;
 }
 
+/* Returns ds_end(ST) and THEN increases the length by INCR */
+char *
+ds_append_uninit(struct string *st, size_t incr)
+{
+  char *end ;
+  assert(incr >= 0 );
+
+  ds_extend(st, ds_length(st) + incr + 1);
+
+  end = ds_end(st);
+
+  st->length += incr;
+  return end;
+}
+
 /* Formats FORMAT as a printf string and appends the result to ST. */
 void
 ds_printf (struct string *st, const char *format, ...)
 /* Formats FORMAT as a printf string and appends the result to ST. */
 void
 ds_printf (struct string *st, const char *format, ...)
index 77d918e28ce8881cf7f6fa5ca8765c4952ef566e..aa93fb2b7b751bd0600e151d51f9b2ca8bfa6ba9 100644 (file)
@@ -221,6 +221,8 @@ spprintf (char *dst, const char *format, ...)
 }
 
 
 }
 
 
+char * ds_append_uninit(struct string *st, size_t incr);
+
 
 
 #endif /* str_h */
 
 
 #endif /* str_h */
index 08da8e3ce014e0298882170e1352d2fbdc1d8ee3..97fcd16f1ee9ed360612fdc2d96e2e542236d4d7 100644 (file)
@@ -31,6 +31,7 @@ TESTS = \
        tests/command/oneway-with-splits.sh \
        tests/command/permissions.sh \
        tests/command/print.sh \
        tests/command/oneway-with-splits.sh \
        tests/command/permissions.sh \
        tests/command/print.sh \
+       tests/command/print-strings.sh \
        tests/command/rename.sh \
        tests/command/regression.sh \
        tests/command/sample.sh \
        tests/command/rename.sh \
        tests/command/regression.sh \
        tests/command/sample.sh \
@@ -52,6 +53,7 @@ TESTS = \
        tests/command/trimmed-mean.sh \
        tests/command/tabs.sh \
        tests/command/use.sh \
        tests/command/trimmed-mean.sh \
        tests/command/tabs.sh \
        tests/command/use.sh \
+       tests/command/very-long-strings.sh \
        tests/command/weight.sh \
        tests/bugs/agg_crash.sh \
        tests/bugs/agg-crash-2.sh \
        tests/command/weight.sh \
        tests/bugs/agg_crash.sh \
        tests/bugs/agg-crash-2.sh \
@@ -74,6 +76,7 @@ TESTS = \
        tests/bugs/if_crash.sh \
        tests/bugs/input-crash.sh \
        tests/bugs/lag_crash.sh \
        tests/bugs/if_crash.sh \
        tests/bugs/input-crash.sh \
        tests/bugs/lag_crash.sh \
+       tests/bugs/list-overflow.sh \
        tests/bugs/match-files-scratch.sh \
        tests/bugs/multipass.sh \
        tests/bugs/random.sh \
        tests/bugs/match-files-scratch.sh \
        tests/bugs/multipass.sh \
        tests/bugs/random.sh \
diff --git a/tests/bugs/list-overflow.sh b/tests/bugs/list-overflow.sh
new file mode 100755 (executable)
index 0000000..e89ecad
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# This program tests for a bug which caused a buffer overflow
+# when the list command attempted to write very long strings.
+
+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 test program"
+cat > $TESTFILE <<EOF 
+INPUT PROGRAM.
+STRING foo (a2000).
++ COMPUTE foo=CONCAT(RPAD('A',1999, 'x'), 'Z').
+END CASE.
+END FILE.
+END INPUT PROGRAM.
+
+EXECUTE.
+
+DISPLAY VARIABLES.
+
+LIST.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="run program"
+$SUPERVISOR $PSPP --testing-mode $TESTFILE 
+if [ $? -ne 0 ] ; then fail ; fi
+
+pass;
index dd4cfd97e408e3aa38bbc91c41709ea7189c9ba6..7b3e8e4b79cb1aedc3debaff8c69ec42240bcc07 100755 (executable)
@@ -78,7 +78,7 @@ $SUPERVISOR $PSPP -o raw-ascii $TESTFILE
 if [ $? -ne 0 ] ; then no_result ; fi
 
 
 if [ $? -ne 0 ] ; then no_result ; fi
 
 
-activity="compare results"
+activity="compare results 1"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
 1.1 DATA LIST.  Reading 1 record from INLINE.
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
 1.1 DATA LIST.  Reading 1 record from INLINE.
diff --git a/tests/command/print-strings.sh b/tests/command/print-strings.sh
new file mode 100755 (executable)
index 0000000..cc51b45
--- /dev/null
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+# This program tests that the PRINT command properly outputs string variables.
+
+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
+
+export STAT_CONFIG_PATH=$top_srcdir/config
+
+
+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 File"
+cat > $TESTFILE <<EOF
+DATA LIST FREE /s8 (a8) s10 (a10) vl255 (a255) vl258 (a258).
+BEGIN DATA.
+12345678
+AaaaaaaaaZ
+AbbbbMaryHadALittleLambbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbZ
+AccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccZ
+87654321
+AnnnnnnnnZ
+AmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmZ
+AoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooWhyIsItSoZ
+END DATA.
+
+print 
+       outfile='foobar'
+       /s10 * vl255 * vl258 *.
+
+EXECUTE.
+
+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
+
+
+diff $TEMPDIR/foobar - <<EOF
+AaaaaaaaaZ AbbbbMaryHadALittleLambbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbZ AccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccZ 
+AnnnnnnnnZ AmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmZ AoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooWhyIsItSoZ 
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass;
diff --git a/tests/command/very-long-strings.sh b/tests/command/very-long-strings.sh
new file mode 100755 (executable)
index 0000000..79267ab
--- /dev/null
@@ -0,0 +1,196 @@
+#!/bin/sh
+
+# This program tests that very long strings (up to 32767 bytes) can be
+# read and written, a la spss v13/v14
+
+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
+
+export STAT_CONFIG_PATH=$top_srcdir/config
+
+
+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
+
+# First check that we can read files created with spss versions 13/14
+
+activity="Create file 0"
+cat > $TESTFILE <<EOF
+GET FILE='$top_srcdir/tests/v13.sav'.
+DISPLAY VARIABLES.
+LIST.
+
+NEW FILE.
+
+GET FILE='$top_srcdir/tests/v14.sav'.
+DISPLAY VARIABLES.
+LIST.
+
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run program 0"
+$SUPERVISOR $PSPP --testing-mode -o raw-ascii $TESTFILE > /dev/null
+if [ $? -ne 0 ] ; then fail ; fi
+
+activity="compare variable display 0"
+diff $TEMPDIR/pspp.list - <<EOF
+1.1 DISPLAY.  
++--------+-------------------------------------------+--------+
+|Variable|Description                                |Position|
+#========#===========================================#========#
+|N       |Format: F8.2                               |       1|
++--------+-------------------------------------------+--------+
+|A255    |Format: A255                               |       2|
++--------+-------------------------------------------+--------+
+|A258    |Format: A258                               |       3|
++--------+-------------------------------------------+--------+
+|A2000   |Format: A2000                              |       4|
++--------+-------------------------------------------+--------+
+
+       N                                                                                                                                                                                                                                                            A255                                                                                                                                                                                                                                                               A258                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A2000
+-------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+    1.00 a1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA b1BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB c1CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 
+    2.00 a2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX b2YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY c2ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
+
+2.1 DISPLAY.  
++--------+-------------------------------------------+--------+
+|Variable|Description                                |Position|
+#========#===========================================#========#
+|vl255   |Format: A255                               |       1|
++--------+-------------------------------------------+--------+
+|vl256   |Format: A256                               |       2|
++--------+-------------------------------------------+--------+
+|vl1335  |Format: A1335                              |       3|
++--------+-------------------------------------------+--------+
+|vl2000  |Format: A2000                              |       4|
++--------+-------------------------------------------+--------+
+
+                                                                                                                                                                                                                                                          vl255                                                                                                                                                                                                                                                            vl256                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  vl1335                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           vl2000
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM 
+
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+# Now check that we can write files with Very Long Strings
+
+activity="Create data file"
+cat > $TEMPDIR/data <<EOF
+1xxxxxxxx2aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXbcYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYdeZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZf
+1xxxxxxxx2aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXbcYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYdeZZMaryHadAlittleLambZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZf
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+
+activity="Create file1"
+cat > $TESTFILE <<EOF
+DATA LIST FIXED FILE='$TEMPDIR/data'  /a 1-10 (a) 
+ b (a256) 
+ c (a200) 
+ d (a32767)
+ .
+
+
+SAVE OUTFILE='$TEMPDIR/foo.sav' /UNCOMPRESSED.
+
+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="Create file2"
+cat > $TESTFILE <<EOF
+
+GET FILE='$TEMPDIR/foo.sav'.
+
+DISPLAY VARIABLES.
+
+PRINT OUTFILE='$TEMPDIR/out.txt'
+       /a (a10) b (a256) c (a200) 
+       d (a32767)
+       .
+
+EXECUTE.
+
+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
+
+
+# Check that the file read back in has the same data as what we wrote.
+
+activity="compare print"
+diff $TEMPDIR/out.txt $TEMPDIR/data
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+activity="compare variable display"
+diff $TEMPDIR/pspp.list - <<EOF
+1.1 DISPLAY.  
++--------+-------------------------------------------+--------+
+|Variable|Description                                |Position|
+#========#===========================================#========#
+|a       |Format: A10                                |       1|
++--------+-------------------------------------------+--------+
+|b       |Format: A256                               |       2|
++--------+-------------------------------------------+--------+
+|c       |Format: A200                               |       3|
++--------+-------------------------------------------+--------+
+|d       |Format: A32767                             |       4|
++--------+-------------------------------------------+--------+
+
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass;
index 9bfd90ca6fabf0c60dae2314ce4bba1546a6b657..b80f508084961fb9a970110084873c00d00684e9 100755 (executable)
@@ -648,14 +648,14 @@ lpad('abc', 0) => "abc"
 lpad('abc', 2) => "abc"
 lpad('abc', 3) => "abc"
 lpad('abc', 10) => "       abc"
 lpad('abc', 2) => "abc"
 lpad('abc', 3) => "abc"
 lpad('abc', 10) => "       abc"
-lpad('abc', 256) => ""
+lpad('abc', 32768) => ""
 lpad('abc', $sysmis) => ""
 lpad('abc', -1, '*') => ""
 lpad('abc', 0, '*') => "abc"
 lpad('abc', 2, '*') => "abc"
 lpad('abc', 3, '*') => "abc"
 lpad('abc', 10, '*') => "*******abc"
 lpad('abc', $sysmis) => ""
 lpad('abc', -1, '*') => ""
 lpad('abc', 0, '*') => "abc"
 lpad('abc', 2, '*') => "abc"
 lpad('abc', 3, '*') => "abc"
 lpad('abc', 10, '*') => "*******abc"
-lpad('abc', 256, '*') => ""
+lpad('abc', 32768, '*') => ""
 lpad('abc', $sysmis, '*') => ""
 lpad('abc', $sysmis, '') => ""
 lpad('abc', $sysmis, 'xy') => ""
 lpad('abc', $sysmis, '*') => ""
 lpad('abc', $sysmis, '') => ""
 lpad('abc', $sysmis, 'xy') => ""
@@ -693,14 +693,14 @@ rpad('abc', 0) => "abc"
 rpad('abc', 2) => "abc"
 rpad('abc', 3) => "abc"
 rpad('abc', 10) => "abc       "
 rpad('abc', 2) => "abc"
 rpad('abc', 3) => "abc"
 rpad('abc', 10) => "abc       "
-rpad('abc', 256) => ""
+rpad('abc', 32768) => ""
 rpad('abc', $sysmis) => ""
 rpad('abc', -1, '*') => ""
 rpad('abc', 0, '*') => "abc"
 rpad('abc', 2, '*') => "abc"
 rpad('abc', 3, '*') => "abc"
 rpad('abc', 10, '*') => "abc*******"
 rpad('abc', $sysmis) => ""
 rpad('abc', -1, '*') => ""
 rpad('abc', 0, '*') => "abc"
 rpad('abc', 2, '*') => "abc"
 rpad('abc', 3, '*') => "abc"
 rpad('abc', 10, '*') => "abc*******"
-rpad('abc', 256, '*') => ""
+rpad('abc', 32768, '*') => ""
 rpad('abc', $sysmis, '*') => ""
 rpad('abc', $sysmis, '') => ""
 rpad('abc', $sysmis, 'xy') => ""
 rpad('abc', $sysmis, '*') => ""
 rpad('abc', $sysmis, '') => ""
 rpad('abc', $sysmis, 'xy') => ""
diff --git a/tests/v13.sav b/tests/v13.sav
new file mode 100755 (executable)
index 0000000..916cc73
Binary files /dev/null and b/tests/v13.sav differ
diff --git a/tests/v14.sav b/tests/v14.sav
new file mode 100644 (file)
index 0000000..d4aa1df
Binary files /dev/null and b/tests/v14.sav differ