Merge commit 'origin/stable'
[pspp-builds.git] / src / data / sys-file-reader.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2007, 2009 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <data/sys-file-reader.h>
20 #include <data/sys-file-private.h>
21
22 #include <errno.h>
23 #include <float.h>
24 #include <inttypes.h>
25 #include <setjmp.h>
26 #include <stdlib.h>
27
28 #include <libpspp/i18n.h>
29 #include <libpspp/assertion.h>
30 #include <libpspp/message.h>
31 #include <libpspp/compiler.h>
32 #include <libpspp/misc.h>
33 #include <libpspp/pool.h>
34 #include <libpspp/str.h>
35 #include <libpspp/hash.h>
36 #include <libpspp/array.h>
37
38 #include <data/attributes.h>
39 #include <data/case.h>
40 #include <data/casereader-provider.h>
41 #include <data/casereader.h>
42 #include <data/dictionary.h>
43 #include <data/file-handle-def.h>
44 #include <data/file-name.h>
45 #include <data/format.h>
46 #include <data/missing-values.h>
47 #include <data/short-names.h>
48 #include <data/value-labels.h>
49 #include <data/variable.h>
50 #include <data/value.h>
51
52 #include "c-ctype.h"
53 #include "inttostr.h"
54 #include "minmax.h"
55 #include "unlocked-io.h"
56 #include "xalloc.h"
57 #include "xsize.h"
58
59 #include "gettext.h"
60 #define _(msgid) gettext (msgid)
61 #define N_(msgid) (msgid)
62
63 /* System file reader. */
64 struct sfm_reader
65   {
66     /* Resource tracking. */
67     struct pool *pool;          /* All system file state. */
68     jmp_buf bail_out;           /* longjmp() target for error handling. */
69
70     /* File state. */
71     struct file_handle *fh;     /* File handle. */
72     struct fh_lock *lock;       /* Mutual exclusion for file handle. */
73     FILE *file;                 /* File stream. */
74     bool error;                 /* I/O or corruption error? */
75     struct caseproto *proto;    /* Format of output cases. */
76
77     /* File format. */
78     enum integer_format integer_format; /* On-disk integer format. */
79     enum float_format float_format; /* On-disk floating point format. */
80     int oct_cnt;                /* Number of 8-byte units per case. */
81     struct sfm_var *sfm_vars;   /* Variables. */
82     size_t sfm_var_cnt;         /* Number of variables. */
83     casenumber case_cnt;        /* Number of cases */
84     bool has_long_var_names;    /* File has a long variable name map */
85
86     /* Decompression. */
87     bool compressed;            /* File is compressed? */
88     double bias;                /* Compression bias, usually 100.0. */
89     uint8_t opcodes[8];         /* Current block of opcodes. */
90     size_t opcode_idx;          /* Next opcode to interpret, 8 if none left. */
91     bool corruption_warning;    /* Warned about possible corruption? */
92   };
93
94 static const struct casereader_class sys_file_casereader_class;
95
96 static bool close_reader (struct sfm_reader *);
97
98 static struct variable **make_var_by_value_idx (struct sfm_reader *,
99                                                 struct dictionary *);
100 static struct variable *lookup_var_by_value_idx (struct sfm_reader *,
101                                                  struct variable **,
102                                                  int value_idx);
103
104 static void sys_msg (struct sfm_reader *r, int class,
105                      const char *format, va_list args)
106      PRINTF_FORMAT (3, 0);
107 static void sys_warn (struct sfm_reader *, const char *, ...)
108      PRINTF_FORMAT (2, 3);
109 static void sys_error (struct sfm_reader *, const char *, ...)
110      PRINTF_FORMAT (2, 3)
111      NO_RETURN;
112
113 static void read_bytes (struct sfm_reader *, void *, size_t);
114 static bool try_read_bytes (struct sfm_reader *, void *, size_t);
115 static int read_int (struct sfm_reader *);
116 static double read_float (struct sfm_reader *);
117 static void read_string (struct sfm_reader *, char *, size_t);
118 static void skip_bytes (struct sfm_reader *, size_t);
119
120 static struct text_record *open_text_record (struct sfm_reader *, size_t size);
121 static void close_text_record (struct sfm_reader *r,
122                                struct text_record *);
123 static bool read_variable_to_value_pair (struct sfm_reader *,
124                                          struct dictionary *,
125                                          struct text_record *,
126                                          struct variable **var, char **value);
127 static void text_warn (struct sfm_reader *r, struct text_record *text,
128                        const char *format, ...)
129   PRINTF_FORMAT (3, 4);
130 static char *text_get_token (struct text_record *,
131                              struct substring delimiters);
132 static bool text_match (struct text_record *, char c);
133 static bool text_read_short_name (struct sfm_reader *, struct dictionary *,
134                                   struct text_record *,
135                                   struct substring delimiters,
136                                   struct variable **);
137
138 static bool close_reader (struct sfm_reader *r);
139 \f
140 /* Dictionary reader. */
141
142 enum which_format
143   {
144     PRINT_FORMAT,
145     WRITE_FORMAT
146   };
147
148 static void read_header (struct sfm_reader *, struct dictionary *,
149                          int *weight_idx, int *claimed_oct_cnt,
150                          struct sfm_read_info *);
151 static void read_variable_record (struct sfm_reader *, struct dictionary *,
152                                   int *format_warning_cnt);
153 static void parse_format_spec (struct sfm_reader *, unsigned int,
154                                enum which_format, struct variable *,
155                                int *format_warning_cnt);
156 static void setup_weight (struct sfm_reader *, int weight_idx,
157                           struct variable **var_by_value_idx,
158                           struct dictionary *);
159 static void read_documents (struct sfm_reader *, struct dictionary *);
160 static void read_value_labels (struct sfm_reader *, struct dictionary *,
161                                struct variable **var_by_value_idx);
162
163 static void read_extension_record (struct sfm_reader *, struct dictionary *,
164                                    struct sfm_read_info *);
165 static void read_machine_integer_info (struct sfm_reader *,
166                                        size_t size, size_t count,
167                                        struct sfm_read_info *,
168                                        struct dictionary *
169                                        );
170 static void read_machine_float_info (struct sfm_reader *,
171                                      size_t size, size_t count);
172 static void read_display_parameters (struct sfm_reader *,
173                                      size_t size, size_t count,
174                                      struct dictionary *);
175 static void read_long_var_name_map (struct sfm_reader *,
176                                     size_t size, size_t count,
177                                     struct dictionary *);
178 static void read_long_string_map (struct sfm_reader *,
179                                   size_t size, size_t count,
180                                   struct dictionary *);
181 static void read_data_file_attributes (struct sfm_reader *,
182                                        size_t size, size_t count,
183                                        struct dictionary *);
184 static void read_variable_attributes (struct sfm_reader *,
185                                       size_t size, size_t count,
186                                       struct dictionary *);
187 static void read_long_string_value_labels (struct sfm_reader *,
188                                            size_t size, size_t count,
189                                            struct dictionary *);
190
191 /* Convert all the strings in DICT from the dict encoding to UTF8 */
192 static void
193 recode_strings (struct dictionary *dict)
194 {
195   int i;
196
197   const char *enc = dict_get_encoding (dict);
198
199   if ( NULL == enc)
200     enc = get_default_encoding ();
201
202   for (i = 0 ; i < dict_get_var_cnt (dict); ++i)
203     {
204       /* Convert the long variable name */
205       struct variable *var = dict_get_var (dict, i);
206       const char *native_name = var_get_name (var);
207       char *utf8_name = recode_string (UTF8, enc, native_name, -1);
208       if ( 0 != strcmp (utf8_name, native_name))
209         {
210           if ( NULL == dict_lookup_var (dict, utf8_name))
211             dict_rename_var (dict, var, utf8_name);
212           else
213             msg (MW,
214              _("Recoded variable name duplicates an existing `%s' within system file."), utf8_name);
215     }
216
217       free (utf8_name);
218
219       /* Convert the variable label */
220       if (var_has_label (var))
221         {
222           char *utf8_label = recode_string (UTF8, enc, var_get_label (var), -1);
223           var_set_label (var, utf8_label);
224           free (utf8_label);
225         }
226
227       if (var_has_value_labels (var))
228         {
229           const struct val_lab *vl = NULL;
230           const struct val_labs *vlabs = var_get_value_labels (var);
231
232           for (vl = val_labs_first (vlabs); vl != NULL; vl = val_labs_next (vlabs, vl))
233             {
234               const union value *val = val_lab_get_value (vl);
235               const char *label = val_lab_get_label (vl);
236               char *new_label = NULL;
237
238               new_label = recode_string (UTF8, enc, label, -1);
239
240               var_replace_value_label (var, val, new_label);
241               free (new_label);
242             }
243         }
244     }
245 }
246
247 /* Opens the system file designated by file handle FH for
248    reading.  Reads the system file's dictionary into *DICT.
249    If INFO is non-null, then it receives additional info about the
250    system file. */
251 struct casereader *
252 sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
253                  struct sfm_read_info *volatile info)
254 {
255   struct sfm_reader *volatile r = NULL;
256   struct variable **var_by_value_idx;
257   struct sfm_read_info local_info;
258   int format_warning_cnt = 0;
259   int weight_idx;
260   int claimed_oct_cnt;
261   int rec_type;
262
263   *dict = dict_create ();
264
265   /* Create and initialize reader. */
266   r = pool_create_container (struct sfm_reader, pool);
267   r->fh = fh_ref (fh);
268   r->lock = NULL;
269   r->file = NULL;
270   r->error = false;
271   r->oct_cnt = 0;
272   r->has_long_var_names = false;
273   r->opcode_idx = sizeof r->opcodes;
274   r->corruption_warning = false;
275
276   /* TRANSLATORS: this fragment will be interpolated into
277      messages in fh_lock() that identify types of files. */
278   r->lock = fh_lock (fh, FH_REF_FILE, N_("system file"), FH_ACC_READ, false);
279   if (r->lock == NULL)
280     goto error;
281
282   r->file = fn_open (fh_get_file_name (fh), "rb");
283   if (r->file == NULL)
284     {
285       msg (ME, _("Error opening \"%s\" for reading as a system file: %s."),
286            fh_get_file_name (r->fh), strerror (errno));
287       goto error;
288     }
289
290   /* Initialize info. */
291   if (info == NULL)
292     info = &local_info;
293   memset (info, 0, sizeof *info);
294
295   if (setjmp (r->bail_out))
296     goto error;
297
298
299   /* Read header. */
300   read_header (r, *dict, &weight_idx, &claimed_oct_cnt, info);
301
302   /* Read all the variable definition records. */
303   rec_type = read_int (r);
304   while (rec_type == 2)
305     {
306       read_variable_record (r, *dict, &format_warning_cnt);
307       rec_type = read_int (r);
308     }
309
310   /* Figure out the case format. */
311   var_by_value_idx = make_var_by_value_idx (r, *dict);
312   setup_weight (r, weight_idx, var_by_value_idx, *dict);
313
314   /* Read all the rest of the dictionary records. */
315   while (rec_type != 999)
316     {
317       switch (rec_type)
318         {
319         case 3:
320           read_value_labels (r, *dict, var_by_value_idx);
321           break;
322
323         case 4:
324           sys_error (r, _("Misplaced type 4 record."));
325
326         case 6:
327           read_documents (r, *dict);
328           break;
329
330         case 7:
331           read_extension_record (r, *dict, info);
332           break;
333
334         default:
335           sys_error (r, _("Unrecognized record type %d."), rec_type);
336         }
337       rec_type = read_int (r);
338     }
339
340
341   if ( ! r->has_long_var_names )
342     {
343       int i;
344       for (i = 0; i < dict_get_var_cnt (*dict); i++)
345         {
346           struct variable *var = dict_get_var (*dict, i);
347           char short_name[SHORT_NAME_LEN + 1];
348           char long_name[SHORT_NAME_LEN + 1];
349
350           strcpy (short_name, var_get_name (var));
351
352           strcpy (long_name, short_name);
353           str_lowercase (long_name);
354
355           /* Set long name.  Renaming a variable may clear the short
356              name, but we want to retain it, so re-set it
357              explicitly. */
358           dict_rename_var (*dict, var, long_name);
359           var_set_short_name (var, 0, short_name);
360         }
361
362       r->has_long_var_names = true;
363     }
364
365   recode_strings (*dict);
366
367   /* Read record 999 data, which is just filler. */
368   read_int (r);
369
370   /* Warn if the actual amount of data per case differs from the
371      amount that the header claims.  SPSS version 13 gets this
372      wrong when very long strings are involved, so don't warn in
373      that case. */
374   if (claimed_oct_cnt != -1 && claimed_oct_cnt != r->oct_cnt
375       && info->version_major != 13)
376     sys_warn (r, _("File header claims %d variable positions but "
377                    "%d were read from file."),
378               claimed_oct_cnt, r->oct_cnt);
379
380   /* Create an index of dictionary variable widths for
381      sfm_read_case to use.  We cannot use the `struct variable's
382      from the dictionary we created, because the caller owns the
383      dictionary and may destroy or modify its variables. */
384   sfm_dictionary_to_sfm_vars (*dict, &r->sfm_vars, &r->sfm_var_cnt);
385   pool_register (r->pool, free, r->sfm_vars);
386   r->proto = caseproto_ref_pool (dict_get_proto (*dict), r->pool);
387
388   pool_free (r->pool, var_by_value_idx);
389   return casereader_create_sequential
390     (NULL, r->proto,
391      r->case_cnt == -1 ? CASENUMBER_MAX: r->case_cnt,
392                                        &sys_file_casereader_class, r);
393
394 error:
395   close_reader (r);
396   dict_destroy (*dict);
397   *dict = NULL;
398   return NULL;
399 }
400
401 /* Closes a system file after we're done with it.
402    Returns true if an I/O error has occurred on READER, false
403    otherwise. */
404 static bool
405 close_reader (struct sfm_reader *r)
406 {
407   bool error;
408
409   if (r == NULL)
410     return true;
411
412   if (r->file)
413     {
414       if (fn_close (fh_get_file_name (r->fh), r->file) == EOF)
415         {
416           msg (ME, _("Error closing system file \"%s\": %s."),
417                fh_get_file_name (r->fh), strerror (errno));
418           r->error = true;
419         }
420       r->file = NULL;
421     }
422
423   fh_unlock (r->lock);
424   fh_unref (r->fh);
425
426   error = r->error;
427   pool_destroy (r->pool);
428
429   return !error;
430 }
431
432 /* Destroys READER. */
433 static void
434 sys_file_casereader_destroy (struct casereader *reader UNUSED, void *r_)
435 {
436   struct sfm_reader *r = r_;
437   close_reader (r);
438 }
439
440 /* Returns true if FILE is an SPSS system file,
441    false otherwise. */
442 bool
443 sfm_detect (FILE *file)
444 {
445   char rec_type[5];
446
447   if (fread (rec_type, 4, 1, file) != 1)
448     return false;
449   rec_type[4] = '\0';
450
451   return !strcmp ("$FL2", rec_type);
452 }
453 \f
454 /* Reads the global header of the system file.
455    Sets DICT's file label to the system file's label.
456    Sets *WEIGHT_IDX to 0 if the system file is unweighted,
457    or to the value index of the weight variable otherwise.
458    Sets *CLAIMED_OCT_CNT to the number of "octs" (8-byte units)
459    per case that the file claims to have (although it is not
460    always correct).
461    Initializes INFO with header information. */
462 static void
463 read_header (struct sfm_reader *r, struct dictionary *dict,
464              int *weight_idx, int *claimed_oct_cnt,
465              struct sfm_read_info *info)
466 {
467   char rec_type[5];
468   char eye_catcher[61];
469   uint8_t raw_layout_code[4];
470   uint8_t raw_bias[8];
471   char creation_date[10];
472   char creation_time[9];
473   char file_label[65];
474   struct substring file_label_ss;
475   struct substring product;
476
477   read_string (r, rec_type, sizeof rec_type);
478   read_string (r, eye_catcher, sizeof eye_catcher);
479
480   if (strcmp ("$FL2", rec_type) != 0)
481     sys_error (r, _("This is not an SPSS system file."));
482
483   /* Identify integer format. */
484   read_bytes (r, raw_layout_code, sizeof raw_layout_code);
485   if ((!integer_identify (2, raw_layout_code, sizeof raw_layout_code,
486                           &r->integer_format)
487        && !integer_identify (3, raw_layout_code, sizeof raw_layout_code,
488                              &r->integer_format))
489       || (r->integer_format != INTEGER_MSB_FIRST
490           && r->integer_format != INTEGER_LSB_FIRST))
491     sys_error (r, _("This is not an SPSS system file."));
492
493   *claimed_oct_cnt = read_int (r);
494   if (*claimed_oct_cnt < 0 || *claimed_oct_cnt > INT_MAX / 16)
495     *claimed_oct_cnt = -1;
496
497   r->compressed = read_int (r) != 0;
498
499   *weight_idx = read_int (r);
500
501   r->case_cnt = read_int (r);
502   if ( r->case_cnt > INT_MAX / 2)
503     r->case_cnt = -1;
504
505
506   /* Identify floating-point format and obtain compression bias. */
507   read_bytes (r, raw_bias, sizeof raw_bias);
508   if (float_identify (100.0, raw_bias, sizeof raw_bias, &r->float_format) == 0)
509     {
510       uint8_t zero_bias[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
511
512       if (memcmp (raw_bias, zero_bias, 8))
513         sys_warn (r, _("Compression bias is not the usual "
514                        "value of 100, or system file uses unrecognized "
515                        "floating-point format."));
516       else
517         {
518           /* Some software is known to write all-zeros to this
519              field.  Such software also writes floating-point
520              numbers in the format that we expect by default
521              (it seems that all software most likely does, in
522              reality), so don't warn in this case. */
523         }
524
525       if (r->integer_format == INTEGER_MSB_FIRST)
526         r->float_format = FLOAT_IEEE_DOUBLE_BE;
527       else
528         r->float_format = FLOAT_IEEE_DOUBLE_LE;
529     }
530   float_convert (r->float_format, raw_bias, FLOAT_NATIVE_DOUBLE, &r->bias);
531
532   read_string (r, creation_date, sizeof creation_date);
533   read_string (r, creation_time, sizeof creation_time);
534   read_string (r, file_label, sizeof file_label);
535   skip_bytes (r, 3);
536
537   file_label_ss = ss_cstr (file_label);
538   ss_trim (&file_label_ss, ss_cstr (" "));
539   if (!ss_is_empty (file_label_ss))
540     {
541       ss_data (file_label_ss)[ss_length (file_label_ss)] = '\0';
542       dict_set_label (dict, ss_data (file_label_ss));
543     }
544
545   strcpy (info->creation_date, creation_date);
546   strcpy (info->creation_time, creation_time);
547   info->integer_format = r->integer_format;
548   info->float_format = r->float_format;
549   info->compressed = r->compressed;
550   info->case_cnt = r->case_cnt;
551
552   product = ss_cstr (eye_catcher);
553   ss_match_string (&product, ss_cstr ("@(#) SPSS DATA FILE"));
554   ss_trim (&product, ss_cstr (" "));
555   str_copy_buf_trunc (info->product, sizeof info->product,
556                       ss_data (product), ss_length (product));
557 }
558
559 /* Reads a variable (type 2) record from R and adds the
560    corresponding variable to DICT.
561    Also skips past additional variable records for long string
562    variables. */
563 static void
564 read_variable_record (struct sfm_reader *r, struct dictionary *dict,
565                       int *format_warning_cnt)
566 {
567   int width;
568   int has_variable_label;
569   int missing_value_code;
570   int print_format;
571   int write_format;
572   char name[9];
573
574   struct variable *var;
575   int nv;
576
577   width = read_int (r);
578   has_variable_label = read_int (r);
579   missing_value_code = read_int (r);
580   print_format = read_int (r);
581   write_format = read_int (r);
582   read_string (r, name, sizeof name);
583   name[strcspn (name, " ")] = '\0';
584
585   /* Check variable name. */
586   if (name[0] == '$' || name[0] == '#')
587     sys_error (r, "Variable name begins with invalid character `%c'.",
588                name[0]);
589   if (!var_is_plausible_name (name, false))
590     sys_error (r, _("Invalid variable name `%s'."), name);
591
592   /* Create variable. */
593   if (width < 0 || width > 255)
594     sys_error (r, _("Bad width %d for variable %s."), width, name);
595   var = dict_create_var (dict, name, width);
596   if (var == NULL)
597     sys_error (r,
598                _("Duplicate variable name `%s' within system file."),
599                name);
600
601   /* Set the short name the same as the long name. */
602   var_set_short_name (var, 0, var_get_name (var));
603
604   /* Get variable label, if any. */
605   if (has_variable_label != 0 && has_variable_label != 1)
606     sys_error (r, _("Variable label indicator field is not 0 or 1."));
607   if (has_variable_label == 1)
608     {
609       size_t len;
610       char label[255 + 1];
611
612       len = read_int (r);
613       if (len >= sizeof label)
614         sys_error (r, _("Variable %s has label of invalid length %zu."),
615                    name, len);
616       read_string (r, label, len + 1);
617       var_set_label (var, label);
618
619       skip_bytes (r, ROUND_UP (len, 4) - len);
620     }
621
622   /* Set missing values. */
623   if (missing_value_code != 0)
624     {
625       struct missing_values mv;
626       int i;
627
628       mv_init_pool (r->pool, &mv, var_get_width (var));
629       if (var_is_numeric (var))
630         {
631           if (missing_value_code < -3 || missing_value_code > 3
632               || missing_value_code == -1)
633             sys_error (r, _("Numeric missing value indicator field is not "
634                             "-3, -2, 0, 1, 2, or 3."));
635           if (missing_value_code < 0)
636             {
637               double low = read_float (r);
638               double high = read_float (r);
639               mv_add_range (&mv, low, high);
640               missing_value_code = -missing_value_code - 2;
641             }
642           for (i = 0; i < missing_value_code; i++)
643             mv_add_num (&mv, read_float (r));
644         }
645       else
646         {
647           int mv_width = MAX (width, 8);
648           union value value;
649
650           if (missing_value_code < 1 || missing_value_code > 3)
651             sys_error (r, _("String missing value indicator field is not "
652                             "0, 1, 2, or 3."));
653
654           value_init (&value, mv_width);
655           value_set_missing (&value, mv_width);
656           for (i = 0; i < missing_value_code; i++)
657             {
658               uint8_t *s = value_str_rw (&value, mv_width);
659               read_bytes (r, s, 8);
660               mv_add_str (&mv, s);
661             }
662           value_destroy (&value, mv_width);
663         }
664       var_set_missing_values (var, &mv);
665     }
666
667   /* Set formats. */
668   parse_format_spec (r, print_format, PRINT_FORMAT, var, format_warning_cnt);
669   parse_format_spec (r, write_format, WRITE_FORMAT, var, format_warning_cnt);
670
671   /* Account for values.
672      Skip long string continuation records, if any. */
673   nv = width == 0 ? 1 : DIV_RND_UP (width, 8);
674   r->oct_cnt += nv;
675   if (width > 8)
676     {
677       int i;
678
679       for (i = 1; i < nv; i++)
680         {
681           /* Check for record type 2 and width -1. */
682           if (read_int (r) != 2 || read_int (r) != -1)
683             sys_error (r, _("Missing string continuation record."));
684
685           /* Skip and ignore remaining continuation data. */
686           has_variable_label = read_int (r);
687           missing_value_code = read_int (r);
688           print_format = read_int (r);
689           write_format = read_int (r);
690           read_string (r, name, sizeof name);
691
692           /* Variable label fields on continuation records have
693              been spotted in system files created by "SPSS Power
694              Macintosh Release 6.1". */
695           if (has_variable_label)
696             skip_bytes (r, ROUND_UP (read_int (r), 4));
697         }
698     }
699 }
700
701 /* Translates the format spec from sysfile format to internal
702    format. */
703 static void
704 parse_format_spec (struct sfm_reader *r, unsigned int s,
705                    enum which_format which, struct variable *v,
706                    int *format_warning_cnt)
707 {
708   const int max_format_warnings = 8;
709   struct fmt_spec f;
710   uint8_t raw_type = s >> 16;
711   uint8_t w = s >> 8;
712   uint8_t d = s;
713
714   bool ok;
715
716   if (!fmt_from_io (raw_type, &f.type))
717     sys_error (r, _("Unknown variable format %"PRIu8"."), raw_type);
718   f.w = w;
719   f.d = d;
720
721   msg_disable ();
722   ok = fmt_check_output (&f) && fmt_check_width_compat (&f, var_get_width (v));
723   msg_enable ();
724
725   if (ok)
726     {
727       if (which == PRINT_FORMAT)
728         var_set_print_format (v, &f);
729       else
730         var_set_write_format (v, &f);
731     }
732   else if (*++format_warning_cnt <= max_format_warnings)
733     {
734       char fmt_string[FMT_STRING_LEN_MAX + 1];
735       sys_warn (r, _("%s variable %s has invalid %s format %s."),
736                 var_is_numeric (v) ? _("Numeric") : _("String"),
737                 var_get_name (v),
738                 which == PRINT_FORMAT ? _("print") : _("write"),
739                 fmt_to_string (&f, fmt_string));
740
741       if (*format_warning_cnt == max_format_warnings)
742         sys_warn (r, _("Suppressing further invalid format warnings."));
743     }
744 }
745
746 /* Sets the weighting variable in DICT to the variable
747    corresponding to the given 1-based VALUE_IDX, if VALUE_IDX is
748    nonzero. */
749 static void
750 setup_weight (struct sfm_reader *r, int weight_idx,
751               struct variable **var_by_value_idx, struct dictionary *dict)
752 {
753   if (weight_idx != 0)
754     {
755       struct variable *weight_var
756         = lookup_var_by_value_idx (r, var_by_value_idx, weight_idx);
757       if (var_is_numeric (weight_var))
758         dict_set_weight (dict, weight_var);
759       else
760         sys_error (r, _("Weighting variable must be numeric."));
761     }
762 }
763
764 /* Reads a document record, type 6, from system file R, and sets up
765    the documents and n_documents fields in the associated
766    dictionary. */
767 static void
768 read_documents (struct sfm_reader *r, struct dictionary *dict)
769 {
770   int line_cnt;
771   char *documents;
772
773   if (dict_get_documents (dict) != NULL)
774     sys_error (r, _("Multiple type 6 (document) records."));
775
776   line_cnt = read_int (r);
777   if (line_cnt <= 0)
778     sys_error (r, _("Number of document lines (%d) "
779                     "must be greater than 0."), line_cnt);
780
781   documents = pool_nmalloc (r->pool, line_cnt + 1, DOC_LINE_LENGTH);
782   read_string (r, documents, DOC_LINE_LENGTH * line_cnt + 1);
783   if (strlen (documents) == DOC_LINE_LENGTH * line_cnt)
784     dict_set_documents (dict, documents);
785   else
786     sys_error (r, _("Document line contains null byte."));
787   pool_free (r->pool, documents);
788 }
789
790 /* Read a type 7 extension record. */
791 static void
792 read_extension_record (struct sfm_reader *r, struct dictionary *dict,
793                        struct sfm_read_info *info)
794 {
795   int subtype = read_int (r);
796   size_t size = read_int (r);
797   size_t count = read_int (r);
798   size_t bytes = size * count;
799
800   /* Check that SIZE * COUNT + 1 doesn't overflow.  Adding 1
801      allows an extra byte for a null terminator, used by some
802      extension processing routines. */
803   if (size != 0 && size_overflow_p (xsum (1, xtimes (count, size))))
804     sys_error (r, "Record type 7 subtype %d too large.", subtype);
805
806   switch (subtype)
807     {
808     case 3:
809       read_machine_integer_info (r, size, count, info, dict);
810       return;
811
812     case 4:
813       read_machine_float_info (r, size, count);
814       return;
815
816     case 5:
817       /* Variable sets information.  We don't use these yet.
818          They only apply to GUIs; see VARSETS on the APPLY
819          DICTIONARY command in SPSS documentation. */
820       break;
821
822     case 6:
823       /* DATE variable information.  We don't use it yet, but we
824          should. */
825       break;
826
827     case 7:
828       /* Used by the MRSETS command. */
829       break;
830
831     case 8:
832       /* Used by the SPSS Data Entry software. */
833       break;
834
835     case 11:
836       read_display_parameters (r, size, count, dict);
837       return;
838
839     case 13:
840       read_long_var_name_map (r, size, count, dict);
841       return;
842
843     case 14:
844       read_long_string_map (r, size, count, dict);
845       return;
846
847     case 16:
848       /* New in SPSS v14?  Unknown purpose.  */
849       break;
850
851     case 17:
852       read_data_file_attributes (r, size, count, dict);
853       return;
854
855     case 18:
856       read_variable_attributes (r, size, count, dict);
857       return;
858
859     case 20:
860       /* New in SPSS 16.  Contains a single string that describes
861          the character encoding, e.g. "windows-1252". */
862       {
863         char *encoding = pool_calloc (r->pool, size, count + 1);
864         read_string (r, encoding, count + 1);
865         dict_set_encoding (dict, encoding);
866         return;
867       }
868
869     case 21:
870       /* New in SPSS 16.  Encodes value labels for long string
871          variables. */
872       read_long_string_value_labels (r, size, count, dict);
873       return;
874
875     default:
876       sys_warn (r, _("Unrecognized record type 7, subtype %d.  Please send a copy of this file, and the syntax which created it to %s"),
877                 subtype, PACKAGE_BUGREPORT);
878       break;
879     }
880
881   skip_bytes (r, bytes);
882 }
883
884 /* Read record type 7, subtype 3. */
885 static void
886 read_machine_integer_info (struct sfm_reader *r, size_t size, size_t count,
887                            struct sfm_read_info *info,
888                            struct dictionary *dict)
889 {
890   int version_major = read_int (r);
891   int version_minor = read_int (r);
892   int version_revision = read_int (r);
893   int machine_code UNUSED = read_int (r);
894   int float_representation = read_int (r);
895   int compression_code UNUSED = read_int (r);
896   int integer_representation = read_int (r);
897   int character_code = read_int (r);
898
899   int expected_float_format;
900   int expected_integer_format;
901
902   if (size != 4 || count != 8)
903     sys_error (r, _("Bad size (%zu) or count (%zu) field on record type 7, "
904                     "subtype 3."),
905                 size, count);
906
907   /* Save version info. */
908   info->version_major = version_major;
909   info->version_minor = version_minor;
910   info->version_revision = version_revision;
911
912   /* Check floating point format. */
913   if (r->float_format == FLOAT_IEEE_DOUBLE_BE
914       || r->float_format == FLOAT_IEEE_DOUBLE_LE)
915     expected_float_format = 1;
916   else if (r->float_format == FLOAT_Z_LONG)
917     expected_float_format = 2;
918   else if (r->float_format == FLOAT_VAX_G || r->float_format == FLOAT_VAX_D)
919     expected_float_format = 3;
920   else
921     NOT_REACHED ();
922   if (float_representation != expected_float_format)
923     sys_error (r, _("Floating-point representation indicated by "
924                     "system file (%d) differs from expected (%d)."),
925                r->float_format, expected_float_format);
926
927   /* Check integer format. */
928   if (r->integer_format == INTEGER_MSB_FIRST)
929     expected_integer_format = 1;
930   else if (r->integer_format == INTEGER_LSB_FIRST)
931     expected_integer_format = 2;
932   else
933     NOT_REACHED ();
934   if (integer_representation != expected_integer_format)
935     {
936       static const char *const endian[] = {N_("Little Endian"), N_("Big Endian")};
937       sys_warn (r, _("Integer format indicated by system file (%s) "
938                      "differs from expected (%s)."),
939                 gettext (endian[integer_representation == 1]),
940                 gettext (endian[expected_integer_format == 1]));
941     }
942
943
944   /*
945     Record 7 (20) provides a much more reliable way of
946     setting the encoding.
947     The character_code is used as a fallback only.
948   */
949   if ( NULL == dict_get_encoding (dict))
950     {
951       switch (character_code)
952         {
953         case 1:
954           dict_set_encoding (dict, "EBCDIC-US");
955           break;
956         case 2:
957         case 3:
958           /* These ostensibly mean "7-bit ASCII" and "8-bit ASCII"[sic]
959              respectively.   However, there are known to be many files
960              in the wild with character code 2, yet have data which are
961              clearly not ascii.
962              Therefore we ignore these values.
963           */
964           return;
965         case 4:
966           dict_set_encoding (dict, "MS_KANJI");
967           break;
968         case 65000:
969           dict_set_encoding (dict, "UTF-7");
970           break;
971         case 65001:
972           dict_set_encoding (dict, "UTF-8");
973           break;
974         default:
975           {
976             char enc[100];
977             snprintf (enc, 100, "CP%d", character_code);
978             dict_set_encoding (dict, enc);
979           }
980           break;
981         };
982     }
983 }
984
985 /* Read record type 7, subtype 4. */
986 static void
987 read_machine_float_info (struct sfm_reader *r, size_t size, size_t count)
988 {
989   double sysmis = read_float (r);
990   double highest = read_float (r);
991   double lowest = read_float (r);
992
993   if (size != 8 || count != 3)
994     sys_error (r, _("Bad size (%zu) or count (%zu) on extension 4."),
995                size, count);
996
997   if (sysmis != SYSMIS)
998     sys_warn (r, _("File specifies unexpected value %g as %s."),
999               sysmis, "SYSMIS");
1000
1001   if (highest != HIGHEST)
1002     sys_warn (r, _("File specifies unexpected value %g as %s."),
1003               highest, "HIGHEST");
1004
1005   if (lowest != LOWEST)
1006     sys_warn (r, _("File specifies unexpected value %g as %s."),
1007               lowest, "LOWEST");
1008 }
1009
1010 /* Read record type 7, subtype 11, which specifies how variables
1011    should be displayed in GUI environments. */
1012 static void
1013 read_display_parameters (struct sfm_reader *r, size_t size, size_t count,
1014                          struct dictionary *dict)
1015 {
1016   size_t n_vars;
1017   bool includes_width;
1018   bool warned = false;
1019   size_t i;
1020
1021   if (size != 4)
1022     {
1023       sys_warn (r, _("Bad size %zu on extension 11."), size);
1024       skip_bytes (r, size * count);
1025       return;
1026     }
1027
1028   n_vars = dict_get_var_cnt (dict);
1029   if (count == 3 * n_vars)
1030     includes_width = true;
1031   else if (count == 2 * n_vars)
1032     includes_width = false;
1033   else
1034     {
1035       sys_warn (r, _("Extension 11 has bad count %zu (for %zu variables)."),
1036                 count, n_vars);
1037       skip_bytes (r, size * count);
1038       return;
1039     }
1040
1041   for (i = 0; i < n_vars; ++i)
1042     {
1043       struct variable *v = dict_get_var (dict, i);
1044       int measure = read_int (r);
1045       int width = includes_width ? read_int (r) : 0;
1046       int align = read_int (r);
1047
1048       /* SPSS 14 sometimes seems to set string variables' measure
1049          to zero. */
1050       if (0 == measure && var_is_alpha (v))
1051         measure = 1;
1052
1053       if (measure < 1 || measure > 3 || align < 0 || align > 2)
1054         {
1055           if (!warned)
1056             sys_warn (r, _("Invalid variable display parameters "
1057                            "for variable %zu (%s).  "
1058                            "Default parameters substituted."),
1059                       i, var_get_name (v));
1060           warned = true;
1061           continue;
1062         }
1063
1064       var_set_measure (v, (measure == 1 ? MEASURE_NOMINAL
1065                            : measure == 2 ? MEASURE_ORDINAL
1066                            : MEASURE_SCALE));
1067       var_set_alignment (v, (align == 0 ? ALIGN_LEFT
1068                              : align == 1 ? ALIGN_RIGHT
1069                              : ALIGN_CENTRE));
1070
1071       /* Older versions (SPSS 9.0) sometimes set the display
1072          width to zero.  This causes confusion in the GUI, so
1073          only set the width if it is nonzero. */
1074       if (width > 0)
1075         var_set_display_width (v, width);
1076     }
1077 }
1078
1079 /* Reads record type 7, subtype 13, which gives the long name
1080    that corresponds to each short name.  Modifies variable names
1081    in DICT accordingly.  */
1082 static void
1083 read_long_var_name_map (struct sfm_reader *r, size_t size, size_t count,
1084                         struct dictionary *dict)
1085 {
1086   struct text_record *text;
1087   struct variable *var;
1088   char *long_name;
1089
1090   text = open_text_record (r, size * count);
1091   while (read_variable_to_value_pair (r, dict, text, &var, &long_name))
1092     {
1093       char **short_names;
1094       size_t short_name_cnt;
1095       size_t i;
1096
1097       /* Validate long name. */
1098       if (!var_is_valid_name (long_name, false))
1099         {
1100           sys_warn (r, _("Long variable mapping from %s to invalid "
1101                          "variable name `%s'."),
1102                     var_get_name (var), long_name);
1103           continue;
1104         }
1105
1106       /* Identify any duplicates. */
1107       if (strcasecmp (var_get_short_name (var, 0), long_name)
1108           && dict_lookup_var (dict, long_name) != NULL)
1109         {
1110           sys_warn (r, _("Duplicate long variable name `%s' "
1111                          "within system file."), long_name);
1112           continue;
1113         }
1114
1115       /* Renaming a variable may clear its short names, but we
1116          want to retain them, so we save them and re-set them
1117          afterward. */
1118       short_name_cnt = var_get_short_name_cnt (var);
1119       short_names = xnmalloc (short_name_cnt, sizeof *short_names);
1120       for (i = 0; i < short_name_cnt; i++)
1121         {
1122           const char *s = var_get_short_name (var, i);
1123           short_names[i] = s != NULL ? xstrdup (s) : NULL;
1124         }
1125
1126       /* Set long name. */
1127       dict_rename_var (dict, var, long_name);
1128
1129       /* Restore short names. */
1130       for (i = 0; i < short_name_cnt; i++)
1131         {
1132           var_set_short_name (var, i, short_names[i]);
1133           free (short_names[i]);
1134         }
1135       free (short_names);
1136     }
1137   close_text_record (r, text);
1138   r->has_long_var_names = true;
1139 }
1140
1141 /* Reads record type 7, subtype 14, which gives the real length
1142    of each very long string.  Rearranges DICT accordingly. */
1143 static void
1144 read_long_string_map (struct sfm_reader *r, size_t size, size_t count,
1145                       struct dictionary *dict)
1146 {
1147   struct text_record *text;
1148   struct variable *var;
1149   char *length_s;
1150
1151   text = open_text_record (r, size * count);
1152   while (read_variable_to_value_pair (r, dict, text, &var, &length_s))
1153     {
1154       size_t idx = var_get_dict_index (var);
1155       long int length;
1156       int segment_cnt;
1157       int i;
1158
1159       /* Get length. */
1160       length = strtol (length_s, NULL, 10);
1161       if (length < 1 || length > MAX_STRING)
1162         {
1163           sys_warn (r, _("%s listed as string of invalid length %s "
1164                          "in very length string record."),
1165                     var_get_name (var), length_s);
1166           continue;
1167         }
1168
1169       /* Check segments. */
1170       segment_cnt = sfm_width_to_segments (length);
1171       if (segment_cnt == 1)
1172         {
1173           sys_warn (r, _("%s listed in very long string record with width %s, "
1174                          "which requires only one segment."),
1175                     var_get_name (var), length_s);
1176           continue;
1177         }
1178       if (idx + segment_cnt > dict_get_var_cnt (dict))
1179         sys_error (r, _("Very long string %s overflows dictionary."),
1180                    var_get_name (var));
1181
1182       /* Get the short names from the segments and check their
1183          lengths. */
1184       for (i = 0; i < segment_cnt; i++)
1185         {
1186           struct variable *seg = dict_get_var (dict, idx + i);
1187           int alloc_width = sfm_segment_alloc_width (length, i);
1188           int width = var_get_width (seg);
1189
1190           if (i > 0)
1191             var_set_short_name (var, i, var_get_short_name (seg, 0));
1192           if (ROUND_UP (width, 8) != ROUND_UP (alloc_width, 8))
1193             sys_error (r, _("Very long string with width %ld has segment %d "
1194                             "of width %d (expected %d)"),
1195                        length, i, width, alloc_width);
1196         }
1197       dict_delete_consecutive_vars (dict, idx + 1, segment_cnt - 1);
1198       var_set_width (var, length);
1199     }
1200   close_text_record (r, text);
1201   dict_compact_values (dict);
1202 }
1203
1204 /* Reads value labels from sysfile H and inserts them into the
1205    associated dictionary. */
1206 static void
1207 read_value_labels (struct sfm_reader *r,
1208                    struct dictionary *dict, struct variable **var_by_value_idx)
1209 {
1210   struct pool *subpool;
1211
1212   struct label
1213     {
1214       uint8_t raw_value[8];        /* Value as uninterpreted bytes. */
1215       union value value;        /* Value. */
1216       char *label;              /* Null-terminated label string. */
1217     };
1218
1219   struct label *labels = NULL;
1220   int label_cnt;                /* Number of labels. */
1221
1222   struct variable **var = NULL; /* Associated variables. */
1223   int var_cnt;                  /* Number of associated variables. */
1224   int max_width;                /* Maximum width of string variables. */
1225
1226   int i;
1227
1228   subpool = pool_create_subpool (r->pool);
1229
1230   /* Read the type 3 record and record its contents.  We can't do
1231      much with the data yet because we don't know whether it is
1232      of numeric or string type. */
1233
1234   /* Read number of labels. */
1235   label_cnt = read_int (r);
1236
1237   if (size_overflow_p (xtimes (label_cnt, sizeof *labels)))
1238     {
1239       sys_warn (r, _("Invalid number of labels: %d.  Ignoring labels."),
1240                 label_cnt);
1241       label_cnt = 0;
1242     }
1243
1244   /* Read each value/label tuple into labels[]. */
1245   labels = pool_nalloc (subpool, label_cnt, sizeof *labels);
1246   for (i = 0; i < label_cnt; i++)
1247     {
1248       struct label *label = labels + i;
1249       unsigned char label_len;
1250       size_t padded_len;
1251
1252       /* Read value. */
1253       read_bytes (r, label->raw_value, sizeof label->raw_value);
1254
1255       /* Read label length. */
1256       read_bytes (r, &label_len, sizeof label_len);
1257       padded_len = ROUND_UP (label_len + 1, 8);
1258
1259       /* Read label, padding. */
1260       label->label = pool_alloc (subpool, padded_len + 1);
1261       read_bytes (r, label->label, padded_len - 1);
1262       label->label[label_len] = 0;
1263     }
1264
1265   /* Now, read the type 4 record that has the list of variables
1266      to which the value labels are to be applied. */
1267
1268   /* Read record type of type 4 record. */
1269   if (read_int (r) != 4)
1270     sys_error (r, _("Variable index record (type 4) does not immediately "
1271                     "follow value label record (type 3) as it should."));
1272
1273   /* Read number of variables associated with value label from type 4
1274      record. */
1275   var_cnt = read_int (r);
1276   if (var_cnt < 1 || var_cnt > dict_get_var_cnt (dict))
1277     sys_error (r, _("Number of variables associated with a value label (%d) "
1278                     "is not between 1 and the number of variables (%zu)."),
1279                var_cnt, dict_get_var_cnt (dict));
1280
1281   /* Read the list of variables. */
1282   var = pool_nalloc (subpool, var_cnt, sizeof *var);
1283   max_width = 0;
1284   for (i = 0; i < var_cnt; i++)
1285     {
1286       var[i] = lookup_var_by_value_idx (r, var_by_value_idx, read_int (r));
1287       if (var_get_width (var[i]) > 8)
1288         sys_error (r, _("Value labels may not be added to long string "
1289                         "variables (e.g. %s) using records types 3 and 4."),
1290                    var_get_name (var[i]));
1291       max_width = MAX (max_width, var_get_width (var[i]));
1292     }
1293
1294   /* Type check the variables. */
1295   for (i = 1; i < var_cnt; i++)
1296     if (var_get_type (var[i]) != var_get_type (var[0]))
1297       sys_error (r, _("Variables associated with value label are not all of "
1298                       "identical type.  Variable %s is %s, but variable "
1299                       "%s is %s."),
1300                  var_get_name (var[0]),
1301                  var_is_numeric (var[0]) ? _("numeric") : _("string"),
1302                  var_get_name (var[i]),
1303                  var_is_numeric (var[i]) ? _("numeric") : _("string"));
1304
1305   /* Fill in labels[].value, now that we know the desired type. */
1306   for (i = 0; i < label_cnt; i++)
1307     {
1308       struct label *label = labels + i;
1309
1310       value_init_pool (subpool, &label->value, max_width);
1311       if (var_is_alpha (var[0]))
1312         u8_buf_copy_rpad (value_str_rw (&label->value, max_width), max_width,
1313                        label->raw_value, sizeof label->raw_value, ' ');
1314       else
1315         label->value.f = float_get_double (r->float_format, label->raw_value);
1316     }
1317
1318   /* Assign the `value_label's to each variable. */
1319   for (i = 0; i < var_cnt; i++)
1320     {
1321       struct variable *v = var[i];
1322       int j;
1323
1324       /* Add each label to the variable. */
1325       for (j = 0; j < label_cnt; j++)
1326         {
1327           struct label *label = &labels[j];
1328           if (!var_add_value_label (v, &label->value, label->label))
1329             {
1330               if (var_is_numeric (var[0]))
1331                 sys_warn (r, _("Duplicate value label for %g on %s."),
1332                           label->value.f, var_get_name (v));
1333               else
1334                 sys_warn (r, _("Duplicate value label for \"%.*s\" on %s."),
1335                           max_width, value_str (&label->value, max_width),
1336                           var_get_name (v));
1337             }
1338         }
1339     }
1340
1341   pool_destroy (subpool);
1342 }
1343
1344 /* Reads a set of custom attributes from TEXT into ATTRS.
1345    ATTRS may be a null pointer, in which case the attributes are
1346    read but discarded. */
1347 static void
1348 read_attributes (struct sfm_reader *r, struct text_record *text,
1349                  struct attrset *attrs)
1350 {
1351   do
1352     {
1353       struct attribute *attr;
1354       char *key;
1355       int index;
1356
1357       /* Parse the key. */
1358       key = text_get_token (text, ss_cstr ("("));
1359       if (key == NULL)
1360         return;
1361
1362       attr = attribute_create (key);
1363       for (index = 1; ; index++)
1364         {
1365           /* Parse the value. */
1366           char *value;
1367           size_t length;
1368
1369           value = text_get_token (text, ss_cstr ("\n"));
1370           if (value == NULL)
1371             {
1372               text_warn (r, text, _("Error parsing attribute value %s[%d]"),
1373                          key, index);
1374               break;
1375             }              
1376
1377           length = strlen (value);
1378           if (length >= 2 && value[0] == '\'' && value[length - 1] == '\'') 
1379             {
1380               value[length - 1] = '\0';
1381               attribute_add_value (attr, value + 1); 
1382             }
1383           else 
1384             {
1385               text_warn (r, text,
1386                          _("Attribute value %s[%d] is not quoted: %s"),
1387                          key, index, value);
1388               attribute_add_value (attr, value); 
1389             }
1390
1391           /* Was this the last value for this attribute? */
1392           if (text_match (text, ')'))
1393             break;
1394         }
1395       if (attrs != NULL)
1396         attrset_add (attrs, attr);
1397       else
1398         attribute_destroy (attr);
1399     }
1400   while (!text_match (text, '/'));
1401 }
1402
1403 /* Reads record type 7, subtype 17, which lists custom
1404    attributes on the data file.  */
1405 static void
1406 read_data_file_attributes (struct sfm_reader *r,
1407                            size_t size, size_t count,
1408                            struct dictionary *dict)
1409 {
1410   struct text_record *text = open_text_record (r, size * count);
1411   read_attributes (r, text, dict_get_attributes (dict));
1412   close_text_record (r, text);
1413 }
1414
1415 static void
1416 skip_long_string_value_labels (struct sfm_reader *r, size_t n_labels)
1417 {
1418   size_t i;
1419
1420   for (i = 0; i < n_labels; i++)
1421     {
1422       size_t value_length, label_length;
1423
1424       value_length = read_int (r);
1425       skip_bytes (r, value_length);
1426       label_length = read_int (r);
1427       skip_bytes (r, label_length);
1428     }
1429 }
1430
1431 static void
1432 read_long_string_value_labels (struct sfm_reader *r,
1433                                size_t size, size_t count,
1434                                struct dictionary *d)
1435 {
1436   const off_t start = ftello (r->file);
1437   while (ftello (r->file) - start < size * count)
1438     {
1439       char var_name[VAR_NAME_LEN + 1];
1440       size_t n_labels, i;
1441       struct variable *v;
1442       union value value;
1443       int var_name_len;
1444       int width;
1445
1446       /* Read header. */
1447       var_name_len = read_int (r);
1448       if (var_name_len > VAR_NAME_LEN)
1449         sys_error (r, _("Variable name length in long string value label "
1450                         "record (%d) exceeds %d-byte limit."),
1451                    var_name_len, VAR_NAME_LEN);
1452       read_string (r, var_name, var_name_len + 1);
1453       width = read_int (r);
1454       n_labels = read_int (r);
1455
1456       v = dict_lookup_var (d, var_name);
1457       if (v == NULL)
1458         {
1459           sys_warn (r, _("Ignoring long string value record for "
1460                          "unknown variable %s."), var_name);
1461           skip_long_string_value_labels (r, n_labels);
1462           continue;
1463         }
1464       if (var_is_numeric (v))
1465         {
1466           sys_warn (r, _("Ignoring long string value record for "
1467                          "numeric variable %s."), var_name);
1468           skip_long_string_value_labels (r, n_labels);
1469           continue;
1470         }
1471       if (width != var_get_width (v))
1472         {
1473           sys_warn (r, _("Ignoring long string value record for variable %s "
1474                          "because the record's width (%d) does not match the "
1475                          "variable's width (%d)"),
1476                     var_name, width, var_get_width (v));
1477           skip_long_string_value_labels (r, n_labels);
1478           continue;
1479         }
1480
1481       /* Read values. */
1482       value_init_pool (r->pool, &value, width);
1483       for (i = 0; i < n_labels; i++)
1484         {
1485           size_t value_length, label_length;
1486           char label[256];
1487           bool skip = false;
1488
1489           /* Read value. */
1490           value_length = read_int (r);
1491           if (value_length == width)
1492             read_bytes (r, value_str_rw (&value, width), width);
1493           else
1494             {
1495               sys_warn (r, _("Ignoring long string value %zu for variable %s, "
1496                              "with width %d, that has bad value width %zu."),
1497                         i, var_get_name (v), width, value_length);
1498               skip_bytes (r, value_length);
1499               skip = true;
1500             }
1501
1502           /* Read label. */
1503           label_length = read_int (r);
1504           read_string (r, label, MIN (sizeof label, label_length + 1));
1505           if (label_length >= sizeof label)
1506             {
1507               /* Skip and silently ignore label text after the
1508                  first 255 bytes.  The maximum documented length
1509                  of a label is 120 bytes so this is more than
1510                  generous. */
1511               skip_bytes (r, sizeof label - (label_length + 1));
1512             }
1513
1514           if (!skip && !var_add_value_label (v, &value, label))
1515             sys_warn (r, _("Duplicate value label for \"%.*s\" on %s."),
1516                       width, value_str (&value, width), var_get_name (v));
1517         }
1518     }
1519 }
1520
1521
1522 /* Reads record type 7, subtype 18, which lists custom
1523    attributes on individual variables.  */
1524 static void
1525 read_variable_attributes (struct sfm_reader *r,
1526                           size_t size, size_t count,
1527                           struct dictionary *dict)
1528 {
1529   struct text_record *text = open_text_record (r, size * count);
1530   for (;;) 
1531     {
1532       struct variable *var;
1533       if (!text_read_short_name (r, dict, text, ss_cstr (":"), &var))
1534         break;
1535       read_attributes (r, text, var != NULL ? var_get_attributes (var) : NULL);
1536     }
1537   close_text_record (r, text);
1538 }
1539
1540 \f
1541 /* Case reader. */
1542
1543 static void partial_record (struct sfm_reader *r)
1544      NO_RETURN;
1545
1546 static void read_error (struct casereader *, const struct sfm_reader *);
1547
1548 static bool read_case_number (struct sfm_reader *, double *);
1549 static bool read_case_string (struct sfm_reader *, uint8_t *, size_t);
1550 static int read_opcode (struct sfm_reader *);
1551 static bool read_compressed_number (struct sfm_reader *, double *);
1552 static bool read_compressed_string (struct sfm_reader *, uint8_t *);
1553 static bool read_whole_strings (struct sfm_reader *, uint8_t *, size_t);
1554 static bool skip_whole_strings (struct sfm_reader *, size_t);
1555
1556 /* Reads and returns one case from READER's file.  Returns a null
1557    pointer if not successful. */
1558 static struct ccase *
1559 sys_file_casereader_read (struct casereader *reader, void *r_)
1560 {
1561   struct sfm_reader *r = r_;
1562   struct ccase *volatile c;
1563   int i;
1564
1565   if (r->error)
1566     return NULL;
1567
1568   c = case_create (r->proto);
1569   if (setjmp (r->bail_out))
1570     {
1571       casereader_force_error (reader);
1572       case_unref (c);
1573       return NULL;
1574     }
1575
1576   for (i = 0; i < r->sfm_var_cnt; i++)
1577     {
1578       struct sfm_var *sv = &r->sfm_vars[i];
1579       union value *v = case_data_rw_idx (c, sv->case_index);
1580
1581       if (sv->var_width == 0)
1582         {
1583           if (!read_case_number (r, &v->f))
1584             goto eof;
1585         }
1586       else
1587         {
1588           uint8_t *s = value_str_rw (v, sv->var_width);
1589           if (!read_case_string (r, s + sv->offset, sv->segment_width))
1590             goto eof;
1591           if (!skip_whole_strings (r, ROUND_DOWN (sv->padding, 8)))
1592             partial_record (r);
1593         }
1594     }
1595   return c;
1596
1597 eof:
1598   case_unref (c);
1599   if (i != 0)
1600     partial_record (r);
1601   if (r->case_cnt != -1)
1602     read_error (reader, r);
1603   return NULL;
1604 }
1605
1606 /* Issues an error that R ends in a partial record. */
1607 static void
1608 partial_record (struct sfm_reader *r)
1609 {
1610   sys_error (r, _("File ends in partial case."));
1611 }
1612
1613 /* Issues an error that an unspecified error occurred SFM, and
1614    marks R tainted. */
1615 static void
1616 read_error (struct casereader *r, const struct sfm_reader *sfm)
1617 {
1618   msg (ME, _("Error reading case from file %s."), fh_get_name (sfm->fh));
1619   casereader_force_error (r);
1620 }
1621
1622 /* Reads a number from R and stores its value in *D.
1623    If R is compressed, reads a compressed number;
1624    otherwise, reads a number in the regular way.
1625    Returns true if successful, false if end of file is
1626    reached immediately. */
1627 static bool
1628 read_case_number (struct sfm_reader *r, double *d)
1629 {
1630   if (!r->compressed)
1631     {
1632       uint8_t number[8];
1633       if (!try_read_bytes (r, number, sizeof number))
1634         return false;
1635       float_convert (r->float_format, number, FLOAT_NATIVE_DOUBLE, d);
1636       return true;
1637     }
1638   else
1639     return read_compressed_number (r, d);
1640 }
1641
1642 /* Reads LENGTH string bytes from R into S.
1643    Always reads a multiple of 8 bytes; if LENGTH is not a
1644    multiple of 8, then extra bytes are read and discarded without
1645    being written to S.
1646    Reads compressed strings if S is compressed.
1647    Returns true if successful, false if end of file is
1648    reached immediately. */
1649 static bool
1650 read_case_string (struct sfm_reader *r, uint8_t *s, size_t length)
1651 {
1652   size_t whole = ROUND_DOWN (length, 8);
1653   size_t partial = length % 8;
1654
1655   if (whole)
1656     {
1657       if (!read_whole_strings (r, s, whole))
1658         return false;
1659     }
1660
1661   if (partial)
1662     {
1663       uint8_t bounce[8];
1664       if (!read_whole_strings (r, bounce, sizeof bounce))
1665         {
1666           if (whole)
1667             partial_record (r);
1668           return false;
1669         }
1670       memcpy (s + whole, bounce, partial);
1671     }
1672
1673   return true;
1674 }
1675
1676 /* Reads and returns the next compression opcode from R. */
1677 static int
1678 read_opcode (struct sfm_reader *r)
1679 {
1680   assert (r->compressed);
1681   for (;;)
1682     {
1683       int opcode;
1684       if (r->opcode_idx >= sizeof r->opcodes)
1685         {
1686           if (!try_read_bytes (r, r->opcodes, sizeof r->opcodes))
1687             return -1;
1688           r->opcode_idx = 0;
1689         }
1690       opcode = r->opcodes[r->opcode_idx++];
1691
1692       if (opcode != 0)
1693         return opcode;
1694     }
1695 }
1696
1697 /* Reads a compressed number from R and stores its value in D.
1698    Returns true if successful, false if end of file is
1699    reached immediately. */
1700 static bool
1701 read_compressed_number (struct sfm_reader *r, double *d)
1702 {
1703   int opcode = read_opcode (r);
1704   switch (opcode)
1705     {
1706     case -1:
1707     case 252:
1708       return false;
1709
1710     case 253:
1711       *d = read_float (r);
1712       break;
1713
1714     case 254:
1715       float_convert (r->float_format, "        ", FLOAT_NATIVE_DOUBLE, d);
1716       if (!r->corruption_warning)
1717         {
1718           r->corruption_warning = true;
1719           sys_warn (r, _("Possible compressed data corruption: "
1720                          "compressed spaces appear in numeric field."));
1721         }
1722       break;
1723
1724     case 255:
1725       *d = SYSMIS;
1726       break;
1727
1728     default:
1729       *d = opcode - r->bias;
1730       break;
1731     }
1732
1733   return true;
1734 }
1735
1736 /* Reads a compressed 8-byte string segment from R and stores it
1737    in DST.
1738    Returns true if successful, false if end of file is
1739    reached immediately. */
1740 static bool
1741 read_compressed_string (struct sfm_reader *r, uint8_t *dst)
1742 {
1743   int opcode = read_opcode (r);
1744   switch (opcode)
1745     {
1746     case -1:
1747     case 252:
1748       return false;
1749
1750     case 253:
1751       read_bytes (r, dst, 8);
1752       break;
1753
1754     case 254:
1755       memset (dst, ' ', 8);
1756       break;
1757
1758     default:
1759       {
1760         double value = opcode - r->bias;
1761         float_convert (FLOAT_NATIVE_DOUBLE, &value, r->float_format, dst);
1762         if (value == 0.0)
1763           {
1764             /* This has actually been seen "in the wild".  The submitter of the
1765                file that showed that the contents decoded as spaces, but they
1766                were at the end of the field so it's possible that the null
1767                bytes just acted as null terminators. */
1768           }
1769         else if (!r->corruption_warning)
1770           {
1771             r->corruption_warning = true;
1772             sys_warn (r, _("Possible compressed data corruption: "
1773                            "string contains compressed integer (opcode %d)"),
1774                       opcode);
1775           }
1776       }
1777       break;
1778     }
1779
1780   return true;
1781 }
1782
1783 /* Reads LENGTH string bytes from R into S.
1784    LENGTH must be a multiple of 8.
1785    Reads compressed strings if S is compressed.
1786    Returns true if successful, false if end of file is
1787    reached immediately. */
1788 static bool
1789 read_whole_strings (struct sfm_reader *r, uint8_t *s, size_t length)
1790 {
1791   assert (length % 8 == 0);
1792   if (!r->compressed)
1793     return try_read_bytes (r, s, length);
1794   else
1795     {
1796       size_t ofs;
1797       for (ofs = 0; ofs < length; ofs += 8)
1798         if (!read_compressed_string (r, s + ofs))
1799           {
1800             if (ofs != 0)
1801               partial_record (r);
1802             return false;
1803           }
1804       return true;
1805     }
1806 }
1807
1808 /* Skips LENGTH string bytes from R.
1809    LENGTH must be a multiple of 8.
1810    (LENGTH is also limited to 1024, but that's only because the
1811    current caller never needs more than that many bytes.)
1812    Returns true if successful, false if end of file is
1813    reached immediately. */
1814 static bool
1815 skip_whole_strings (struct sfm_reader *r, size_t length)
1816 {
1817   uint8_t buffer[1024];
1818   assert (length < sizeof buffer);
1819   return read_whole_strings (r, buffer, length);
1820 }
1821 \f
1822 /* Creates and returns a table that can be used for translating a value
1823    index into a case to a "struct variable *" for DICT.  Multiple
1824    system file fields reference variables this way.
1825
1826    This table must be created before processing the very long
1827    string extension record, because that record causes some
1828    values to be deleted from the case and the dictionary to be
1829    compacted. */
1830 static struct variable **
1831 make_var_by_value_idx (struct sfm_reader *r, struct dictionary *dict)
1832 {
1833   struct variable **var_by_value_idx;
1834   int value_idx = 0;
1835   int i;
1836
1837   var_by_value_idx = pool_nmalloc (r->pool,
1838                                    r->oct_cnt, sizeof *var_by_value_idx);
1839   for (i = 0; i < dict_get_var_cnt (dict); i++)
1840     {
1841       struct variable *v = dict_get_var (dict, i);
1842       int nv = var_is_numeric (v) ? 1 : DIV_RND_UP (var_get_width (v), 8);
1843       int j;
1844
1845       var_by_value_idx[value_idx++] = v;
1846       for (j = 1; j < nv; j++)
1847         var_by_value_idx[value_idx++] = NULL;
1848     }
1849   assert (value_idx == r->oct_cnt);
1850
1851   return var_by_value_idx;
1852 }
1853
1854 /* Returns the "struct variable" corresponding to the given
1855    1-basd VALUE_IDX in VAR_BY_VALUE_IDX.  Verifies that the index
1856    is valid. */
1857 static struct variable *
1858 lookup_var_by_value_idx (struct sfm_reader *r,
1859                          struct variable **var_by_value_idx, int value_idx)
1860 {
1861   struct variable *var;
1862
1863   if (value_idx < 1 || value_idx > r->oct_cnt)
1864     sys_error (r, _("Variable index %d not in valid range 1...%d."),
1865                value_idx, r->oct_cnt);
1866
1867   var = var_by_value_idx[value_idx - 1];
1868   if (var == NULL)
1869     sys_error (r, _("Variable index %d refers to long string "
1870                     "continuation."),
1871                value_idx);
1872
1873   return var;
1874 }
1875
1876 /* Returns the variable in D with the given SHORT_NAME,
1877    or a null pointer if there is none. */
1878 static struct variable *
1879 lookup_var_by_short_name (struct dictionary *d, const char *short_name)
1880 {
1881   struct variable *var;
1882   size_t var_cnt;
1883   size_t i;
1884
1885   /* First try looking up by full name.  This often succeeds. */
1886   var = dict_lookup_var (d, short_name);
1887   if (var != NULL && !strcasecmp (var_get_short_name (var, 0), short_name))
1888     return var;
1889
1890   /* Iterate through the whole dictionary as a fallback. */
1891   var_cnt = dict_get_var_cnt (d);
1892   for (i = 0; i < var_cnt; i++)
1893     {
1894       var = dict_get_var (d, i);
1895       if (!strcasecmp (var_get_short_name (var, 0), short_name))
1896         return var;
1897     }
1898
1899   return NULL;
1900 }
1901 \f
1902 /* Helpers for reading records that contain structured text
1903    strings. */
1904
1905 /* Maximum number of warnings to issue for a single text
1906    record. */
1907 #define MAX_TEXT_WARNINGS 5
1908
1909 /* State. */
1910 struct text_record
1911   {
1912     struct substring buffer;    /* Record contents. */
1913     size_t pos;                 /* Current position in buffer. */
1914     int n_warnings;             /* Number of warnings issued or suppressed. */
1915   };
1916
1917 /* Reads SIZE bytes into a text record for R,
1918    and returns the new text record. */
1919 static struct text_record *
1920 open_text_record (struct sfm_reader *r, size_t size)
1921 {
1922   struct text_record *text = pool_alloc (r->pool, sizeof *text);
1923   char *buffer = pool_malloc (r->pool, size + 1);
1924   read_bytes (r, buffer, size);
1925   text->buffer = ss_buffer (buffer, size);
1926   text->pos = 0;
1927   text->n_warnings = 0;
1928   return text;
1929 }
1930
1931 /* Closes TEXT, frees its storage, and issues a final warning
1932    about suppressed warnings if necesary. */
1933 static void
1934 close_text_record (struct sfm_reader *r, struct text_record *text)
1935 {
1936   if (text->n_warnings > MAX_TEXT_WARNINGS)
1937     sys_warn (r, _("Suppressed %d additional related warnings."),
1938               text->n_warnings - MAX_TEXT_WARNINGS);
1939   pool_free (r->pool, ss_data (text->buffer));
1940 }
1941
1942 /* Reads a variable=value pair from TEXT.
1943    Looks up the variable in DICT and stores it into *VAR.
1944    Stores a null-terminated value into *VALUE. */
1945 static bool
1946 read_variable_to_value_pair (struct sfm_reader *r, struct dictionary *dict,
1947                              struct text_record *text,
1948                              struct variable **var, char **value)
1949 {
1950   for (;;)
1951     {
1952       if (!text_read_short_name (r, dict, text, ss_cstr ("="), var))
1953         return false;
1954       
1955       *value = text_get_token (text, ss_buffer ("\t\0", 2));
1956       if (*value == NULL)
1957         return false;
1958
1959       text->pos += ss_span (ss_substr (text->buffer, text->pos, SIZE_MAX),
1960                             ss_buffer ("\t\0", 2));
1961
1962       if (*var != NULL)
1963         return true;
1964     }
1965 }
1966
1967 static bool
1968 text_read_short_name (struct sfm_reader *r, struct dictionary *dict,
1969                       struct text_record *text, struct substring delimiters,
1970                       struct variable **var)
1971 {
1972   char *short_name = text_get_token (text, delimiters);
1973   if (short_name == NULL)
1974     return false;
1975
1976   *var = lookup_var_by_short_name (dict, short_name);
1977   if (*var == NULL)
1978     text_warn (r, text, _("Variable map refers to unknown variable %s."),
1979                short_name);
1980   return true;
1981 }
1982
1983 /* Displays a warning for the current file position, limiting the
1984    number to MAX_TEXT_WARNINGS for TEXT. */
1985 static void
1986 text_warn (struct sfm_reader *r, struct text_record *text,
1987            const char *format, ...)
1988 {
1989   if (text->n_warnings++ < MAX_TEXT_WARNINGS) 
1990     {
1991       va_list args;
1992
1993       va_start (args, format);
1994       sys_msg (r, MW, format, args);
1995       va_end (args);
1996     }
1997 }
1998
1999 static char *
2000 text_get_token (struct text_record *text, struct substring delimiters)
2001 {
2002   struct substring token;
2003
2004   if (!ss_tokenize (text->buffer, delimiters, &text->pos, &token))
2005     return NULL;
2006   ss_data (token)[ss_length (token)] = '\0';
2007   return ss_data (token);
2008 }
2009
2010 static bool
2011 text_match (struct text_record *text, char c)
2012 {
2013   if (text->buffer.string[text->pos] == c) 
2014     {
2015       text->pos++;
2016       return true;
2017     }
2018   else
2019     return false;
2020 }
2021 \f
2022 /* Messages. */
2023
2024 /* Displays a corruption message. */
2025 static void
2026 sys_msg (struct sfm_reader *r, int class, const char *format, va_list args)
2027 {
2028   struct msg m;
2029   struct string text;
2030
2031   ds_init_empty (&text);
2032   ds_put_format (&text, "\"%s\" near offset 0x%lx: ",
2033                  fh_get_file_name (r->fh), (unsigned long) ftell (r->file));
2034   ds_put_vformat (&text, format, args);
2035
2036   m.category = msg_class_to_category (class);
2037   m.severity = msg_class_to_severity (class);
2038   m.where.file_name = NULL;
2039   m.where.line_number = 0;
2040   m.text = ds_cstr (&text);
2041
2042   msg_emit (&m);
2043 }
2044
2045 /* Displays a warning for the current file position. */
2046 static void
2047 sys_warn (struct sfm_reader *r, const char *format, ...)
2048 {
2049   va_list args;
2050
2051   va_start (args, format);
2052   sys_msg (r, MW, format, args);
2053   va_end (args);
2054 }
2055
2056 /* Displays an error for the current file position,
2057    marks it as in an error state,
2058    and aborts reading it using longjmp. */
2059 static void
2060 sys_error (struct sfm_reader *r, const char *format, ...)
2061 {
2062   va_list args;
2063
2064   va_start (args, format);
2065   sys_msg (r, ME, format, args);
2066   va_end (args);
2067
2068   r->error = true;
2069   longjmp (r->bail_out, 1);
2070 }
2071 \f
2072 /* Reads BYTE_CNT bytes into BUF.
2073    Returns true if exactly BYTE_CNT bytes are successfully read.
2074    Aborts if an I/O error or a partial read occurs.
2075    If EOF_IS_OK, then an immediate end-of-file causes false to be
2076    returned; otherwise, immediate end-of-file causes an abort
2077    too. */
2078 static inline bool
2079 read_bytes_internal (struct sfm_reader *r, bool eof_is_ok,
2080                    void *buf, size_t byte_cnt)
2081 {
2082   size_t bytes_read = fread (buf, 1, byte_cnt, r->file);
2083   if (bytes_read == byte_cnt)
2084     return true;
2085   else if (ferror (r->file))
2086     sys_error (r, _("System error: %s."), strerror (errno));
2087   else if (!eof_is_ok || bytes_read != 0)
2088     sys_error (r, _("Unexpected end of file."));
2089   else
2090     return false;
2091 }
2092
2093 /* Reads BYTE_CNT into BUF.
2094    Aborts upon I/O error or if end-of-file is encountered. */
2095 static void
2096 read_bytes (struct sfm_reader *r, void *buf, size_t byte_cnt)
2097 {
2098   read_bytes_internal (r, false, buf, byte_cnt);
2099 }
2100
2101 /* Reads BYTE_CNT bytes into BUF.
2102    Returns true if exactly BYTE_CNT bytes are successfully read.
2103    Returns false if an immediate end-of-file is encountered.
2104    Aborts if an I/O error or a partial read occurs. */
2105 static bool
2106 try_read_bytes (struct sfm_reader *r, void *buf, size_t byte_cnt)
2107 {
2108   return read_bytes_internal (r, true, buf, byte_cnt);
2109 }
2110
2111 /* Reads a 32-bit signed integer from R and returns its value in
2112    host format. */
2113 static int
2114 read_int (struct sfm_reader *r)
2115 {
2116   uint8_t integer[4];
2117   read_bytes (r, integer, sizeof integer);
2118   return integer_get (r->integer_format, integer, sizeof integer);
2119 }
2120
2121 /* Reads a 64-bit floating-point number from R and returns its
2122    value in host format. */
2123 static double
2124 read_float (struct sfm_reader *r)
2125 {
2126   uint8_t number[8];
2127   read_bytes (r, number, sizeof number);
2128   return float_get_double (r->float_format, number);
2129 }
2130
2131 /* Reads exactly SIZE - 1 bytes into BUFFER
2132    and stores a null byte into BUFFER[SIZE - 1]. */
2133 static void
2134 read_string (struct sfm_reader *r, char *buffer, size_t size)
2135 {
2136   assert (size > 0);
2137   read_bytes (r, buffer, size - 1);
2138   buffer[size - 1] = '\0';
2139 }
2140
2141 /* Skips BYTES bytes forward in R. */
2142 static void
2143 skip_bytes (struct sfm_reader *r, size_t bytes)
2144 {
2145   while (bytes > 0)
2146     {
2147       char buffer[1024];
2148       size_t chunk = MIN (sizeof buffer, bytes);
2149       read_bytes (r, buffer, chunk);
2150       bytes -= chunk;
2151     }
2152 }
2153 \f
2154 static const struct casereader_class sys_file_casereader_class =
2155   {
2156     sys_file_casereader_read,
2157     sys_file_casereader_destroy,
2158     NULL,
2159     NULL,
2160   };