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