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