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