Yuri Chornoivan contributed some typo fixes
[pspp] / src / data / pc+-file-reader.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-2000, 2006-2007, 2009-2016 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 <errno.h>
20 #include <float.h>
21 #include <inttypes.h>
22 #include <stdlib.h>
23 #include <sys/stat.h>
24
25 #include "data/any-reader.h"
26 #include "data/case.h"
27 #include "data/casereader-provider.h"
28 #include "data/casereader.h"
29 #include "data/dictionary.h"
30 #include "data/file-handle-def.h"
31 #include "data/file-name.h"
32 #include "data/format.h"
33 #include "data/identifier.h"
34 #include "data/missing-values.h"
35 #include "data/value-labels.h"
36 #include "data/value.h"
37 #include "data/variable.h"
38 #include "libpspp/float-format.h"
39 #include "libpspp/i18n.h"
40 #include "libpspp/integer-format.h"
41 #include "libpspp/message.h"
42 #include "libpspp/misc.h"
43 #include "libpspp/pool.h"
44 #include "libpspp/str.h"
45
46 #include "gl/localcharset.h"
47 #include "gl/minmax.h"
48 #include "gl/xalloc.h"
49 #include "gl/xsize.h"
50
51 #include "gettext.h"
52 #define _(msgid) gettext (msgid)
53 #define N_(msgid) (msgid)
54
55 struct pcp_dir_entry
56   {
57     unsigned int ofs;
58     unsigned int len;
59   };
60
61 struct pcp_directory
62   {
63     struct pcp_dir_entry main;
64     struct pcp_dir_entry variables;
65     struct pcp_dir_entry labels;
66     struct pcp_dir_entry data;
67   };
68
69 struct pcp_main_header
70   {
71     char product[63];           /* "PCSPSS SYSTEM FILE..." */
72     unsigned int nominal_case_size; /* Number of var positions. */
73     char creation_date[9];      /* "[m]m/dd/yy". */
74     char creation_time[9];      /* "[H]H:MM:SS". */
75     char file_label[65];        /* File label. */
76     unsigned int weight_index;  /* Index of weighting variable, 0 if none. */
77   };
78
79 struct pcp_var_record
80   {
81     unsigned int pos;
82
83     char name[9];
84     int width;
85     struct fmt_spec format;
86     uint8_t missing[8];
87     char *label;
88
89     bool weight;
90
91     struct pcp_value_label *val_labs;
92     size_t n_val_labs;
93
94     struct variable *var;
95   };
96
97 struct pcp_value_label
98   {
99     uint8_t value[8];
100     char *label;
101   };
102
103 /* System file reader. */
104 struct pcp_reader
105   {
106     struct any_reader any_reader;
107
108     /* Resource tracking. */
109     struct pool *pool;          /* All system file state. */
110
111     /* File data. */
112     unsigned int file_size;
113     struct any_read_info info;
114     struct pcp_directory directory;
115     struct pcp_main_header header;
116     struct pcp_var_record *vars;
117     size_t n_vars;
118
119     /* File state. */
120     struct file_handle *fh;     /* File handle. */
121     struct fh_lock *lock;       /* Mutual exclusion for file handle. */
122     FILE *file;                 /* File stream. */
123     unsigned int pos;           /* Position in file. */
124     bool error;                 /* I/O or corruption error? */
125     struct caseproto *proto;    /* Format of output cases. */
126
127     /* File format. */
128     unsigned int n_cases;       /* Number of cases */
129     const char *encoding;       /* String encoding. */
130
131     /* Decompression. */
132     bool compressed;
133     uint8_t opcodes[8];         /* Current block of opcodes. */
134     size_t opcode_idx;          /* Next opcode to interpret, 8 if none left. */
135     bool corruption_warning;    /* Warned about possible corruption? */
136   };
137
138 static struct pcp_reader *
139 pcp_reader_cast (const struct any_reader *r_)
140 {
141   assert (r_->klass == &pcp_file_reader_class);
142   return UP_CAST (r_, struct pcp_reader, any_reader);
143 }
144
145 static const struct casereader_class pcp_file_casereader_class;
146
147 static bool pcp_close (struct any_reader *);
148
149 static bool read_variables_record (struct pcp_reader *);
150
151 static void pcp_msg (struct pcp_reader *r, off_t, int class,
152                      const char *format, va_list args)
153      PRINTF_FORMAT (4, 0);
154 static void pcp_warn (struct pcp_reader *, off_t, const char *, ...)
155      PRINTF_FORMAT (3, 4);
156 static void pcp_error (struct pcp_reader *, off_t, const char *, ...)
157      PRINTF_FORMAT (3, 4);
158
159 static bool read_bytes (struct pcp_reader *, void *, size_t)
160   WARN_UNUSED_RESULT;
161 static int try_read_bytes (struct pcp_reader *, void *, size_t)
162   WARN_UNUSED_RESULT;
163 static bool read_uint16 (struct pcp_reader *, unsigned int *)
164   WARN_UNUSED_RESULT;
165 static bool read_uint32 (struct pcp_reader *, unsigned int *)
166   WARN_UNUSED_RESULT;
167 static bool read_float (struct pcp_reader *, double *)
168   WARN_UNUSED_RESULT;
169 static double parse_float (const uint8_t number[8]);
170 static bool read_string (struct pcp_reader *, char *, size_t)
171   WARN_UNUSED_RESULT;
172 static bool skip_bytes (struct pcp_reader *, size_t) WARN_UNUSED_RESULT;
173
174 static bool pcp_seek (struct pcp_reader *, off_t);
175
176 static bool pcp_is_sysmis(const uint8_t *);
177 \f
178 /* Dictionary reader. */
179
180 static bool read_dictionary (struct pcp_reader *);
181 static bool read_main_header (struct pcp_reader *, struct pcp_main_header *);
182 static void parse_header (struct pcp_reader *,
183                           const struct pcp_main_header *,
184                           struct any_read_info *, struct dictionary *);
185 static bool parse_variable_records (struct pcp_reader *, struct dictionary *,
186                                     struct pcp_var_record *, size_t n);
187
188 /* Tries to open FH for reading as an SPSS/PC+ system file.  Returns a
189    pcp_reader if successful, otherwise NULL. */
190 static struct any_reader *
191 pcp_open (struct file_handle *fh)
192 {
193   struct stat s;
194
195   /* Create and initialize reader. */
196   struct pcp_reader *r = XZALLOC (struct pcp_reader);
197   r->any_reader.klass = &pcp_file_reader_class;
198   r->pool = pool_create ();
199   pool_register (r->pool, free, r);
200   r->fh = fh_ref (fh);
201   r->opcode_idx = sizeof r->opcodes;
202
203   /* TRANSLATORS: this fragment will be interpolated into
204      messages in fh_lock() that identify types of files. */
205   r->lock = fh_lock (fh, FH_REF_FILE, N_("SPSS/PC+ system file"),
206                      FH_ACC_READ, false);
207   if (r->lock == NULL)
208     goto error;
209
210   /* Open file. */
211   r->file = fn_open (fh, "rb");
212   if (r->file == NULL)
213     {
214       msg (ME, _("Error opening `%s' for reading as an SPSS/PC+ "
215                  "system file: %s."),
216            fh_get_file_name (r->fh), strerror (errno));
217       goto error;
218     }
219
220   /* Fetch file size. */
221   if (fstat (fileno (r->file), &s))
222     {
223       pcp_error (r, 0, _("%s: stat failed (%s)."),
224                  fh_get_file_name (r->fh), strerror (errno));
225       goto error;
226     }
227   if (s.st_size > UINT_MAX)
228     {
229       pcp_error (r, 0, _("%s: file too large."), fh_get_file_name (r->fh));
230       goto error;
231     }
232   r->file_size = s.st_size;
233
234   /* Read dictionary. */
235   if (!read_dictionary (r))
236     goto error;
237
238   if (!pcp_seek (r, r->directory.data.ofs))
239     goto error;
240
241   return &r->any_reader;
242
243 error:
244   pcp_close (&r->any_reader);
245   return NULL;
246 }
247
248 static bool
249 pcp_read_dir_entry (struct pcp_reader *r, struct pcp_dir_entry *de)
250 {
251   if (!read_uint32 (r, &de->ofs) || !read_uint32 (r, &de->len))
252     return false;
253
254   if (de->len > r->file_size || de->ofs > r->file_size - de->len)
255     {
256       pcp_error (r, r->pos - 8, _("Directory entry is for a %u-byte record "
257                                   "starting at offset %u but file is only "
258                                   "%u bytes long."),
259                  de->ofs, de->len, r->file_size);
260       return false;
261     }
262
263   return true;
264 }
265
266 static bool
267 read_dictionary (struct pcp_reader *r)
268 {
269   unsigned int two, zero;
270
271   if (!read_uint32 (r, &two) || !read_uint32 (r, &zero))
272     return false;
273   if (two != 2 || zero != 0)
274     pcp_warn (r, 0, _("Directory fields have unexpected values "
275                       "(%u,%u)."), two, zero);
276
277   if (!pcp_read_dir_entry (r, &r->directory.main)
278       || !pcp_read_dir_entry (r, &r->directory.variables)
279       || !pcp_read_dir_entry (r, &r->directory.labels)
280       || !pcp_read_dir_entry (r, &r->directory.data))
281     return false;
282
283   if (!read_main_header (r, &r->header))
284     return false;
285
286   read_variables_record (r);
287
288   return true;
289 }
290
291 struct get_strings_aux
292   {
293     struct pool *pool;
294     char **titles;
295     char **strings;
296     bool *ids;
297     size_t allocated;
298     size_t n;
299   };
300
301 static void
302 add_string__ (struct get_strings_aux *aux,
303               const char *string, bool id, char *title)
304 {
305   if (aux->n >= aux->allocated)
306     {
307       aux->allocated = 2 * (aux->allocated + 1);
308       aux->titles = pool_realloc (aux->pool, aux->titles,
309                                   aux->allocated * sizeof *aux->titles);
310       aux->strings = pool_realloc (aux->pool, aux->strings,
311                                    aux->allocated * sizeof *aux->strings);
312       aux->ids = pool_realloc (aux->pool, aux->ids,
313                                aux->allocated * sizeof *aux->ids);
314     }
315
316   aux->titles[aux->n] = title;
317   aux->strings[aux->n] = pool_strdup (aux->pool, string);
318   aux->ids[aux->n] = id;
319   aux->n++;
320 }
321
322 static void PRINTF_FORMAT (3, 4)
323 add_string (struct get_strings_aux *aux,
324             const char *string, const char *title, ...)
325 {
326   va_list args;
327
328   va_start (args, title);
329   add_string__ (aux, string, false, pool_vasprintf (aux->pool, title, args));
330   va_end (args);
331 }
332
333 static void PRINTF_FORMAT (3, 4)
334 add_id (struct get_strings_aux *aux, const char *id, const char *title, ...)
335 {
336   va_list args;
337
338   va_start (args, title);
339   add_string__ (aux, id, true, pool_vasprintf (aux->pool, title, args));
340   va_end (args);
341 }
342
343 /* Retrieves significant string data from R in its raw format, to allow the
344    caller to try to detect the encoding in use.
345
346    Returns the number of strings retrieved N.  Sets each of *TITLESP, *IDSP,
347    and *STRINGSP to an array of N elements allocated from POOL.  For each I in
348    0...N-1, UTF-8 string *TITLESP[I] describes *STRINGSP[I], which is in
349    whatever encoding system file R uses.  *IDS[I] is true if *STRINGSP[I] must
350    be a valid PSPP language identifier, false if *STRINGSP[I] is free-form
351    text. */
352 static size_t
353 pcp_get_strings (const struct any_reader *r_, struct pool *pool,
354                  char ***titlesp, bool **idsp, char ***stringsp)
355 {
356   struct pcp_reader *r = pcp_reader_cast (r_);
357   struct get_strings_aux aux;
358   size_t var_idx;
359   size_t i, j;
360
361   aux.pool = pool;
362   aux.titles = NULL;
363   aux.strings = NULL;
364   aux.ids = NULL;
365   aux.allocated = 0;
366   aux.n = 0;
367
368   var_idx = 0;
369   for (i = 0; i < r->n_vars; i++)
370     if (r->vars[i].width != -1)
371       add_id (&aux, r->vars[i].name, _("Variable %zu"), ++var_idx);
372
373   var_idx = 0;
374   for (i = 0; i < r->n_vars; i++)
375     if (r->vars[i].width != -1)
376       {
377         var_idx++;
378         if (r->vars[i].label)
379           add_string (&aux, r->vars[i].label, _("Variable %zu Label"),
380                       var_idx);
381
382         for (j = 0; j < r->vars[i].n_val_labs; j++)
383           add_string (&aux, r->vars[i].label,
384                       _("Variable %zu Value Label %zu"), var_idx, j);
385       }
386
387   add_string (&aux, r->header.creation_date, _("Creation Date"));
388   add_string (&aux, r->header.creation_time, _("Creation Time"));
389   add_string (&aux, r->header.product, _("Product"));
390   add_string (&aux, r->header.file_label, _("File Label"));
391
392   *titlesp = aux.titles;
393   *idsp = aux.ids;
394   *stringsp = aux.strings;
395   return aux.n;
396 }
397
398 static void
399 find_and_delete_var (struct dictionary *dict, const char *name)
400 {
401   struct variable *var = dict_lookup_var (dict, name);
402   if (var)
403     dict_delete_var (dict, var);
404 }
405
406 /* Decodes the dictionary read from R, saving it into *DICT.  Character
407    strings in R are decoded using ENCODING, or an encoding obtained from R if
408    ENCODING is null, or the locale encoding if R specifies no encoding.
409
410    If INFOP is non-null, then it receives additional info about the system
411    file, which the caller must eventually free with any_read_info_destroy()
412    when it is no longer needed.
413
414    This function consumes R.  The caller must use it again later, even to
415    destroy it with pcp_close(). */
416 static struct casereader *
417 pcp_decode (struct any_reader *r_, const char *encoding,
418             struct dictionary **dictp, struct any_read_info *infop)
419 {
420   struct pcp_reader *r = pcp_reader_cast (r_);
421   struct dictionary *dict;
422
423   if (encoding == NULL)
424     {
425       encoding = locale_charset ();
426       pcp_warn (r, -1, _("Using default encoding %s to read this SPSS/PC+ "
427                          "system file.  For best results, specify an "
428                          "encoding explicitly.  Use SYSFILE INFO with "
429                          "ENCODING=\"DETECT\" to analyze the possible "
430                          "encodings."),
431                 encoding);
432     }
433
434   dict = dict_create (encoding);
435   r->encoding = dict_get_encoding (dict);
436
437   parse_header (r, &r->header, &r->info, dict);
438   if (!parse_variable_records (r, dict, r->vars, r->n_vars))
439     goto error;
440
441   /* Create an index of dictionary variable widths for
442      pcp_read_case to use.  We cannot use the `struct variable's
443      from the dictionary we created, because the caller owns the
444      dictionary and may destroy or modify its variables. */
445   r->proto = caseproto_ref_pool (dict_get_proto (dict), r->pool);
446
447   find_and_delete_var (dict, "CASENUM_");
448   find_and_delete_var (dict, "DATE_");
449   find_and_delete_var (dict, "WEIGHT_");
450
451   *dictp = dict;
452   if (infop)
453     {
454       *infop = r->info;
455       memset (&r->info, 0, sizeof r->info);
456     }
457
458   return casereader_create_sequential
459     (NULL, r->proto, r->n_cases, &pcp_file_casereader_class, r);
460
461 error:
462   pcp_close (&r->any_reader);
463   dict_unref (dict);
464   *dictp = NULL;
465   return NULL;
466 }
467
468 /* Closes R, which should have been returned by pcp_open() but not already
469    closed with pcp_decode() or this function.
470    Returns true if an I/O error has occurred on READER, false
471    otherwise. */
472 static bool
473 pcp_close (struct any_reader *r_)
474 {
475   struct pcp_reader *r = pcp_reader_cast (r_);
476   bool error;
477
478   if (r->file)
479     {
480       if (fn_close (r->fh, r->file) == EOF)
481         {
482           msg (ME, _("Error closing system file `%s': %s."),
483                fh_get_file_name (r->fh), strerror (errno));
484           r->error = true;
485         }
486       r->file = NULL;
487     }
488
489   any_read_info_destroy (&r->info);
490   fh_unlock (r->lock);
491   fh_unref (r->fh);
492
493   error = r->error;
494   pool_destroy (r->pool);
495
496   return !error;
497 }
498
499 /* Destroys READER. */
500 static void
501 pcp_file_casereader_destroy (struct casereader *reader UNUSED, void *r_)
502 {
503   struct pcp_reader *r = r_;
504   pcp_close (&r->any_reader);
505 }
506
507 /* Detects whether FILE is an SPSS/PC+ system file.  Returns 1 if so, 0 if
508    not, and a negative errno value if there is an error reading FILE. */
509 static int
510 pcp_detect (FILE *file)
511 {
512   static const char signature[4] = "SPSS";
513   char buf[sizeof signature];
514
515   if (fseek (file, 0x104, SEEK_SET))
516     return -errno;
517
518   if (fread (buf, sizeof buf, 1, file) != 1)
519     return ferror (file) ? -errno : 0;
520
521   return !memcmp (buf, signature, sizeof buf);
522 }
523 \f
524 /* Reads the main header of the SPSS/PC+ system file.  Initializes *HEADER and
525    *INFO, except for the string fields in *INFO, which parse_header() will
526    initialize later once the file's encoding is known. */
527 static bool
528 read_main_header (struct pcp_reader *r, struct pcp_main_header *header)
529 {
530   unsigned int base_ofs = r->directory.main.ofs;
531   unsigned int zero0, zero1, zero2, zero3;
532   size_t min_values, min_data_size;
533   unsigned int one0, one1;
534   unsigned int compressed;
535   unsigned int n_cases1;
536   uint8_t sysmis[8];
537
538   if (!pcp_seek (r, base_ofs))
539     return false;
540
541   if (r->directory.main.len < 0xb0)
542     {
543       pcp_error (r, r->pos, _("This is not an SPSS/PC+ system file."));
544       return false;
545     }
546   else if (r->directory.main.len > 0xb0)
547     pcp_warn (r, r->pos, _("Record 0 has unexpected length %u."),
548               r->directory.main.len);
549
550   if (!read_uint16 (r, &one0)
551       || !read_string (r, header->product, sizeof header->product)
552       || !read_bytes (r, sysmis, sizeof sysmis)
553       || !read_uint32 (r, &zero0)
554       || !read_uint32 (r, &zero1)
555       || !read_uint16 (r, &one1)
556       || !read_uint16 (r, &compressed)
557       || !read_uint16 (r, &header->nominal_case_size)
558       || !read_uint16 (r, &r->n_cases)
559       || !read_uint16 (r, &header->weight_index)
560       || !read_uint16 (r, &zero2)
561       || !read_uint16 (r, &n_cases1)
562       || !read_uint16 (r, &zero3)
563       || !read_string (r, header->creation_date, sizeof header->creation_date)
564       || !read_string (r, header->creation_time, sizeof header->creation_time)
565       || !read_string (r, header->file_label, sizeof header->file_label))
566     return false;
567
568   if (!pcp_is_sysmis (sysmis))
569     {
570       double d = parse_float (sysmis);
571       pcp_warn (r, base_ofs, _("Record 0 specifies unexpected system missing "
572                                "value %g (%a)."), d, d);
573     }
574   if (one0 != 1 || one1 != 1
575       || zero0 != 0 || zero1 != 0 || zero2 != 0 || zero3 != 0)
576     pcp_warn (r, base_ofs, _("Record 0 reserved fields have unexpected values "
577                              "(%u,%u,%u,%u,%u,%u)."),
578               one0, one1, zero0, zero1, zero2, zero3);
579   if (n_cases1 != r->n_cases)
580     pcp_warn (r, base_ofs, _("Record 0 case counts differ (%u versus %u)."),
581               r->n_cases, n_cases1);
582   if (compressed != 0 && compressed != 1)
583     {
584       pcp_error (r, base_ofs, _("Invalid compression type %u."), compressed);
585       return false;
586     }
587
588   r->compressed = compressed != 0;
589
590   min_values = xtimes (header->nominal_case_size, r->n_cases);
591   min_data_size = xtimes (compressed ? 1 : 8, min_values);
592   if (r->directory.data.len < min_data_size
593       || size_overflow_p (min_data_size))
594     {
595       pcp_warn (r, base_ofs, _("Record 0 claims %u cases with %u values per "
596                                "case (requiring at least %zu bytes) but data "
597                                "record is only %u bytes long."),
598                 r->n_cases, header->nominal_case_size, min_data_size,
599                 r->directory.data.len);
600       return true;
601     }
602
603   return true;
604 }
605
606 static bool
607 read_value_labels (struct pcp_reader *r, struct pcp_var_record *var,
608                    unsigned int start, unsigned int end)
609 {
610   size_t allocated_val_labs = 0;
611
612   start += 7;
613   end += 7;
614   if (end > r->directory.labels.len)
615     {
616       pcp_warn (r, r->pos - 32,
617                 _("Value labels claimed to end at offset %u in labels record "
618                   "but labels record is only %u bytes."),
619                 end, r->directory.labels.len);
620       return true;
621     }
622
623   start += r->directory.labels.ofs;
624   end += r->directory.labels.ofs;
625   if (start > end || end > r->file_size)
626     {
627       pcp_warn (r, r->pos - 32,
628                 _("Value labels claimed to be at offset %u with length %u "
629                   "but file size is only %u bytes."),
630                 start, end - start, r->file_size);
631       return true;
632     }
633
634   if (!pcp_seek (r, start))
635     return false;
636
637   while (r->pos < end && end - r->pos > 8)
638     {
639       struct pcp_value_label *vl;
640       uint8_t len;
641
642       if (var->n_val_labs >= allocated_val_labs)
643         var->val_labs = pool_2nrealloc (r->pool, var->val_labs,
644                                         &allocated_val_labs,
645                                         sizeof *var->val_labs);
646       vl = &var->val_labs[var->n_val_labs];
647
648       if (!read_bytes (r, vl->value, sizeof vl->value)
649           || !read_bytes (r, &len, 1))
650         return false;
651
652       if (end - r->pos < len)
653         {
654           pcp_warn (r, r->pos,
655                     _("Value labels end with partial label (%u bytes left in "
656                       "record, label length %"PRIu8")."),
657                     end - r->pos, len);
658           return true;
659         }
660       vl->label = pool_malloc (r->pool, len + 1);
661       if (!read_bytes (r, vl->label, len))
662         return false;
663
664       vl->label[len] = '\0';
665       var->n_val_labs++;
666     }
667   if (r->pos < end)
668     pcp_warn (r, r->pos, _("%u leftover bytes following value labels."),
669               end - r->pos);
670
671   return true;
672 }
673
674 static bool
675 read_var_label (struct pcp_reader *r, struct pcp_var_record *var,
676                 unsigned int ofs)
677 {
678   uint8_t len;
679
680   ofs += 7;
681   if (ofs >= r->directory.labels.len)
682     {
683       pcp_warn (r, r->pos - 32,
684                 _("Variable label claimed to start at offset %u in labels "
685                   "record but labels record is only %u bytes."),
686                 ofs, r->directory.labels.len);
687       return true;
688     }
689
690   if (!pcp_seek (r, ofs + r->directory.labels.ofs) || !read_bytes (r, &len, 1))
691     return false;
692
693   if (len >= r->directory.labels.len - ofs)
694     {
695       pcp_warn (r, r->pos - 1,
696                 _("Variable label with length %u starting at offset %u in "
697                   "labels record overruns end of %u-byte labels record."),
698                 len, ofs + 1, r->directory.labels.len);
699       return false;
700     }
701
702   var->label = pool_malloc (r->pool, len + 1);
703   var->label[len] = '\0';
704   return read_bytes (r, var->label, len);
705 }
706
707 /* Reads the variables record (record 1) into R. */
708 static bool
709 read_variables_record (struct pcp_reader *r)
710 {
711   unsigned int i;
712   bool weighted;
713
714   if (!pcp_seek (r, r->directory.variables.ofs))
715     return false;
716   if (r->directory.variables.len != r->header.nominal_case_size * 32)
717     {
718       pcp_error (r, r->pos, _("Record 1 has length %u (expected %u)."),
719                  r->directory.variables.len, r->header.nominal_case_size * 32);
720       return false;
721     }
722
723   r->vars = pool_calloc (r->pool,
724                          r->header.nominal_case_size, sizeof *r->vars);
725   weighted = false;
726   for (i = 0; i < r->header.nominal_case_size; i++)
727     {
728       struct pcp_var_record *var = &r->vars[r->n_vars++];
729       unsigned int value_label_start, value_label_end;
730       unsigned int var_label_ofs;
731       unsigned int format;
732       uint8_t raw_type;
733
734       var->pos = r->pos;
735       if (!read_uint32 (r, &value_label_start)
736           || !read_uint32 (r, &value_label_end)
737           || !read_uint32 (r, &var_label_ofs)
738           || !read_uint32 (r, &format)
739           || !read_string (r, var->name, sizeof var->name)
740           || !read_bytes (r, var->missing, sizeof var->missing))
741         return false;
742
743       var->weight = r->header.weight_index && i == r->header.weight_index - 1;
744       if (var->weight)
745         weighted = true;
746
747       raw_type = format >> 16;
748       if (!fmt_from_io (raw_type, &var->format.type))
749         {
750           pcp_error (r, var->pos, _("Variable %u has invalid type %"PRIu8"."),
751                      i, raw_type);
752           return false;
753         }
754
755       var->format.w = (format >> 8) & 0xff;
756       var->format.d = format & 0xff;
757       fmt_fix_output (&var->format);
758       var->width = fmt_var_width (&var->format);
759
760       if (var_label_ofs)
761         {
762           unsigned int save_pos = r->pos;
763           if (!read_var_label (r, var, var_label_ofs)
764               || !pcp_seek (r, save_pos))
765             return false;
766         }
767
768       if (value_label_end > value_label_start && var->width <= 8)
769         {
770           unsigned int save_pos = r->pos;
771           if (!read_value_labels (r, var, value_label_start, value_label_end)
772               || !pcp_seek (r, save_pos))
773             return false;
774         }
775
776       if (var->width > 8)
777         {
778           int extra = DIV_RND_UP (var->width - 8, 8);
779           i += extra;
780           if (!skip_bytes (r, 32 * extra))
781             return false;
782         }
783     }
784
785   if (r->header.weight_index && !weighted)
786     pcp_warn (r, -1, _("Invalid weight index %u."), r->header.weight_index);
787
788   return true;
789 }
790
791 static char *
792 recode_and_trim_string (struct pool *pool, const char *from, const char *in)
793 {
794   struct substring out;
795
796   out = recode_substring_pool ("UTF-8", from, ss_cstr (in), pool);
797   ss_trim (&out, ss_cstr (" "));
798   return ss_xstrdup (out);
799 }
800
801 static void
802 parse_header (struct pcp_reader *r, const struct pcp_main_header *header,
803               struct any_read_info *info, struct dictionary *dict)
804 {
805   const char *dict_encoding = dict_get_encoding (dict);
806   char *label;
807
808   memset (info, 0, sizeof *info);
809
810   info->integer_format = INTEGER_LSB_FIRST;
811   info->float_format = FLOAT_IEEE_DOUBLE_LE;
812   info->compression = r->compressed ? ANY_COMP_SIMPLE : ANY_COMP_NONE;
813   info->n_cases = r->n_cases;
814
815   /* Convert file label to UTF-8 and put it into DICT. */
816   label = recode_and_trim_string (r->pool, dict_encoding, header->file_label);
817   dict_set_label (dict, label);
818   free (label);
819
820   /* Put creation date, time, and product in UTF-8 into INFO. */
821   info->creation_date = recode_and_trim_string (r->pool, dict_encoding,
822                                                 header->creation_date);
823   info->creation_time = recode_and_trim_string (r->pool, dict_encoding,
824                                                 header->creation_time);
825   info->product = recode_and_trim_string (r->pool, dict_encoding,
826                                           header->product);
827 }
828
829 /* Reads a variable (type 2) record from R and adds the
830    corresponding variable to DICT.
831    Also skips past additional variable records for long string
832    variables. */
833 static bool
834 parse_variable_records (struct pcp_reader *r, struct dictionary *dict,
835                         struct pcp_var_record *var_recs, size_t n_var_recs)
836 {
837   const char *dict_encoding = dict_get_encoding (dict);
838   struct pcp_var_record *rec;
839
840   for (rec = var_recs; rec < &var_recs[n_var_recs]; rec++)
841     {
842       struct variable *var;
843       char *name;
844       size_t i;
845
846       name = recode_string_pool ("UTF-8", dict_encoding,
847                                  rec->name, -1, r->pool);
848       name[strcspn (name, " ")] = '\0';
849
850       /* Transform $DATE => DATE_, $WEIGHT => WEIGHT_, $CASENUM => CASENUM_. */
851       if (name[0] == '$')
852         name = pool_asprintf (r->pool, "%s_", name + 1);
853
854       if (!dict_id_is_valid (dict, name, false) || name[0] == '#')
855         {
856           pcp_error (r, rec->pos, _("Invalid variable name `%s'."), name);
857           return false;
858         }
859
860       var = rec->var = dict_create_var (dict, name, rec->width);
861       if (var == NULL)
862         {
863           char *new_name = dict_make_unique_var_name (dict, NULL, NULL);
864           pcp_warn (r, rec->pos, _("Renaming variable with duplicate name "
865                                    "`%s' to `%s'."),
866                     name, new_name);
867           var = rec->var = dict_create_var_assert (dict, new_name, rec->width);
868           free (new_name);
869         }
870       if (rec->weight)
871         {
872           if (!rec->width)
873             dict_set_weight (dict, var);
874           else
875             pcp_warn (r, rec->pos,
876                       _("Cannot weight by string variable `%s'."), name);
877         }
878
879       /* Set the short name the same as the long name. */
880       var_set_short_name (var, 0, name);
881
882       /* Get variable label, if any. */
883       if (rec->label)
884         {
885           char *utf8_label;
886
887           utf8_label = recode_string ("UTF-8", dict_encoding, rec->label, -1);
888           var_set_label (var, utf8_label);
889           free (utf8_label);
890         }
891
892       /* Add value labels. */
893       for (i = 0; i < rec->n_val_labs; i++)
894         {
895           union value value;
896           char *utf8_label;
897
898           value_init (&value, rec->width);
899           if (var_is_numeric (var))
900             value.f = parse_float (rec->val_labs[i].value);
901           else
902             memcpy (value.s, rec->val_labs[i].value, rec->width);
903
904           utf8_label = recode_string ("UTF-8", dict_encoding,
905                                       rec->val_labs[i].label, -1);
906           var_add_value_label (var, &value, utf8_label);
907           free (utf8_label);
908
909           value_destroy (&value, rec->width);
910         }
911
912       /* Set missing values. */
913       if (rec->width <= 8 && !pcp_is_sysmis (rec->missing))
914         {
915           int width = var_get_width (var);
916           struct missing_values mv;
917
918           mv_init_pool (r->pool, &mv, width);
919           if (var_is_numeric (var))
920             mv_add_num (&mv, parse_float (rec->missing));
921           else
922             mv_add_str (&mv, rec->missing, MIN (width, 8));
923           var_set_missing_values (var, &mv);
924         }
925
926       /* Set formats. */
927       var_set_both_formats (var, &rec->format);
928     }
929
930   return true;
931 }
932 \f
933 /* Case reader. */
934
935 static void read_error (struct casereader *, const struct pcp_reader *);
936
937 static bool read_case_number (struct pcp_reader *, double *);
938 static int read_case_string (struct pcp_reader *, uint8_t *, size_t);
939 static int read_opcode (struct pcp_reader *);
940 static bool read_compressed_number (struct pcp_reader *, double *);
941 static int read_compressed_string (struct pcp_reader *, uint8_t *);
942 static int read_whole_strings (struct pcp_reader *, uint8_t *, size_t);
943
944 /* Reads and returns one case from READER's file.  Returns a null
945    pointer if not successful. */
946 static struct ccase *
947 pcp_file_casereader_read (struct casereader *reader, void *r_)
948 {
949   struct pcp_reader *r = r_;
950   unsigned int start_pos = r->pos;
951   struct ccase *c;
952   int retval;
953   int i;
954
955   if (r->error || !r->n_cases)
956     return NULL;
957   r->n_cases--;
958
959   c = case_create (r->proto);
960   for (i = 0; i < r->n_vars; i++)
961     {
962       struct pcp_var_record *var = &r->vars[i];
963       union value *v = case_data_rw_idx (c, i);
964
965       if (var->width == 0)
966         retval = read_case_number (r, &v->f);
967       else
968         retval = read_case_string (r, v->s, var->width);
969
970       if (retval != 1)
971         {
972           pcp_error (r, r->pos, _("File ends in partial case."));
973           goto error;
974         }
975     }
976   if (r->pos > r->directory.data.ofs + r->directory.data.len)
977     {
978       pcp_error (r, r->pos, _("Case beginning at offset 0x%08x extends past "
979                               "end of data record at offset 0x%08x."),
980                  start_pos, r->directory.data.ofs + r->directory.data.len);
981       goto error;
982     }
983
984   return c;
985
986 error:
987   read_error (reader, r);
988   case_unref (c);
989   return NULL;
990 }
991
992 /* Issues an error that an unspecified error occurred PCP, and
993    marks R tainted. */
994 static void
995 read_error (struct casereader *r, const struct pcp_reader *pcp)
996 {
997   msg (ME, _("Error reading case from file %s."), fh_get_name (pcp->fh));
998   casereader_force_error (r);
999 }
1000
1001 /* Reads a number from R and stores its value in *D.
1002    If R is compressed, reads a compressed number;
1003    otherwise, reads a number in the regular way.
1004    Returns true if successful, false if end of file is
1005    reached immediately. */
1006 static bool
1007 read_case_number (struct pcp_reader *r, double *d)
1008 {
1009   if (!r->compressed)
1010     {
1011       uint8_t number[8];
1012       if (!try_read_bytes (r, number, sizeof number))
1013         return false;
1014       *d = parse_float (number);
1015       return true;
1016     }
1017   else
1018     return read_compressed_number (r, d);
1019 }
1020
1021 /* Reads LENGTH string bytes from R into S.  Always reads a multiple of 8
1022    bytes; if LENGTH is not a multiple of 8, then extra bytes are read and
1023    discarded without being written to S.  Reads compressed strings if S is
1024    compressed.  Returns 1 if successful, 0 if end of file is reached
1025    immediately, or -1 for some kind of error. */
1026 static int
1027 read_case_string (struct pcp_reader *r, uint8_t *s, size_t length)
1028 {
1029   size_t whole = ROUND_DOWN (length, 8);
1030   size_t partial = length % 8;
1031
1032   if (whole)
1033     {
1034       int retval = read_whole_strings (r, s, whole);
1035       if (retval != 1)
1036         return retval;
1037     }
1038
1039   if (partial)
1040     {
1041       uint8_t bounce[8];
1042       int retval = read_whole_strings (r, bounce, sizeof bounce);
1043       if (retval <= 0)
1044         return -1;
1045       memcpy (s + whole, bounce, partial);
1046     }
1047
1048   return 1;
1049 }
1050
1051 /* Reads and returns the next compression opcode from R. */
1052 static int
1053 read_opcode (struct pcp_reader *r)
1054 {
1055   assert (r->compressed);
1056   if (r->opcode_idx >= sizeof r->opcodes)
1057     {
1058       int retval = try_read_bytes (r, r->opcodes, sizeof r->opcodes);
1059       if (retval != 1)
1060         return -1;
1061       r->opcode_idx = 0;
1062     }
1063   return r->opcodes[r->opcode_idx++];
1064 }
1065
1066 /* Reads a compressed number from R and stores its value in D.
1067    Returns true if successful, false if end of file is
1068    reached immediately. */
1069 static bool
1070 read_compressed_number (struct pcp_reader *r, double *d)
1071 {
1072   int opcode = read_opcode (r);
1073   switch (opcode)
1074     {
1075     case -1:
1076       return false;
1077
1078     case 0:
1079       *d = SYSMIS;
1080       return true;
1081
1082     case 1:
1083       return read_float (r, d);
1084
1085     default:
1086       *d = opcode - 105.0;
1087       return true;
1088     }
1089 }
1090
1091 /* Reads a compressed 8-byte string segment from R and stores it in DST. */
1092 static int
1093 read_compressed_string (struct pcp_reader *r, uint8_t *dst)
1094 {
1095   int opcode;
1096   int retval;
1097
1098   opcode = read_opcode (r);
1099   switch (opcode)
1100     {
1101     case -1:
1102       return 0;
1103
1104     case 1:
1105       retval = read_bytes (r, dst, 8);
1106       return retval == 1 ? 1 : -1;
1107
1108     default:
1109       if (!r->corruption_warning)
1110         {
1111           r->corruption_warning = true;
1112           pcp_warn (r, r->pos,
1113                     _("Possible compressed data corruption: "
1114                       "string contains compressed integer (opcode %d)."),
1115                     opcode);
1116       }
1117       memset (dst, ' ', 8);
1118       return 1;
1119     }
1120 }
1121
1122 /* Reads LENGTH string bytes from R into S.  LENGTH must be a multiple of 8.
1123    Reads compressed strings if S is compressed.  Returns 1 if successful, 0 if
1124    end of file is reached immediately, or -1 for some kind of error. */
1125 static int
1126 read_whole_strings (struct pcp_reader *r, uint8_t *s, size_t length)
1127 {
1128   assert (length % 8 == 0);
1129   if (!r->compressed)
1130     return try_read_bytes (r, s, length);
1131   else
1132     {
1133       size_t ofs;
1134
1135       for (ofs = 0; ofs < length; ofs += 8)
1136         {
1137           int retval = read_compressed_string (r, s + ofs);
1138           if (retval != 1)
1139             return -1;
1140           }
1141       return 1;
1142     }
1143 }
1144 \f
1145 /* Messages. */
1146
1147 /* Displays a corruption message. */
1148 static void
1149 pcp_msg (struct pcp_reader *r, off_t offset,
1150          int class, const char *format, va_list args)
1151 {
1152   struct string text;
1153   ds_init_empty (&text);
1154   if (offset >= 0)
1155     ds_put_format (&text, _("`%s' near offset 0x%llx: "),
1156                    fh_get_file_name (r->fh), (long long int) offset);
1157   else
1158     ds_put_format (&text, _("`%s': "), fh_get_file_name (r->fh));
1159   ds_put_vformat (&text, format, args);
1160
1161   struct msg *m = xmalloc (sizeof *m);
1162   *m = (struct msg) {
1163     .category = msg_class_to_category (class),
1164     .severity = msg_class_to_severity (class),
1165     .text = ds_steal_cstr (&text),
1166   };
1167   msg_emit (m);
1168 }
1169
1170 /* Displays a warning for offset OFFSET in the file. */
1171 static void
1172 pcp_warn (struct pcp_reader *r, off_t offset, const char *format, ...)
1173 {
1174   va_list args;
1175
1176   va_start (args, format);
1177   pcp_msg (r, offset, MW, format, args);
1178   va_end (args);
1179 }
1180
1181 /* Displays an error for the current file position,
1182    marks it as in an error state,
1183    and aborts reading it using longjmp. */
1184 static void
1185 pcp_error (struct pcp_reader *r, off_t offset, const char *format, ...)
1186 {
1187   va_list args;
1188
1189   va_start (args, format);
1190   pcp_msg (r, offset, ME, format, args);
1191   va_end (args);
1192
1193   r->error = true;
1194 }
1195 \f
1196 /* Reads BYTE_CNT bytes into BUF.
1197    Returns 1 if exactly BYTE_CNT bytes are successfully read.
1198    Returns -1 if an I/O error or a partial read occurs.
1199    Returns 0 for an immediate end-of-file and, if EOF_IS_OK is false, reports
1200    an error. */
1201 static inline int
1202 read_bytes_internal (struct pcp_reader *r, bool eof_is_ok,
1203                      void *buf, size_t n_bytes)
1204 {
1205   size_t bytes_read = fread (buf, 1, n_bytes, r->file);
1206   r->pos += bytes_read;
1207   if (bytes_read == n_bytes)
1208     return 1;
1209   else if (ferror (r->file))
1210     {
1211       pcp_error (r, r->pos, _("System error: %s."), strerror (errno));
1212       return -1;
1213     }
1214   else if (!eof_is_ok || bytes_read != 0)
1215     {
1216       pcp_error (r, r->pos, _("Unexpected end of file."));
1217       return -1;
1218     }
1219   else
1220     return 0;
1221 }
1222
1223 /* Reads BYTE_CNT into BUF.
1224    Returns true if successful.
1225    Returns false upon I/O error or if end-of-file is encountered. */
1226 static bool
1227 read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes)
1228 {
1229   return read_bytes_internal (r, false, buf, n_bytes) == 1;
1230 }
1231
1232 /* Reads BYTE_CNT bytes into BUF.
1233    Returns 1 if exactly BYTE_CNT bytes are successfully read.
1234    Returns 0 if an immediate end-of-file is encountered.
1235    Returns -1 if an I/O error or a partial read occurs. */
1236 static int
1237 try_read_bytes (struct pcp_reader *r, void *buf, size_t n_bytes)
1238 {
1239   return read_bytes_internal (r, true, buf, n_bytes);
1240 }
1241
1242 /* Reads a 16-bit signed integer from R and stores its value in host format in
1243    *X.  Returns true if successful, otherwise false. */
1244 static bool
1245 read_uint16 (struct pcp_reader *r, unsigned int *x)
1246 {
1247   uint8_t integer[2];
1248   if (read_bytes (r, integer, sizeof integer) != 1)
1249     return false;
1250   *x = integer_get (INTEGER_LSB_FIRST, integer, sizeof integer);
1251   return true;
1252 }
1253
1254 /* Reads a 32-bit signed integer from R and stores its value in host format in
1255    *X.  Returns true if successful, otherwise false. */
1256 static bool
1257 read_uint32 (struct pcp_reader *r, unsigned int *x)
1258 {
1259   uint8_t integer[4];
1260   if (read_bytes (r, integer, sizeof integer) != 1)
1261     return false;
1262   *x = integer_get (INTEGER_LSB_FIRST, integer, sizeof integer);
1263   return true;
1264 }
1265
1266 /* Reads exactly SIZE - 1 bytes into BUFFER
1267    and stores a null byte into BUFFER[SIZE - 1]. */
1268 static bool
1269 read_string (struct pcp_reader *r, char *buffer, size_t size)
1270 {
1271   bool ok;
1272
1273   assert (size > 0);
1274   ok = read_bytes (r, buffer, size - 1);
1275   if (ok)
1276     buffer[size - 1] = '\0';
1277   return ok;
1278 }
1279
1280 /* Skips BYTES bytes forward in R. */
1281 static bool
1282 skip_bytes (struct pcp_reader *r, size_t bytes)
1283 {
1284   while (bytes > 0)
1285     {
1286       char buffer[1024];
1287       size_t chunk = MIN (sizeof buffer, bytes);
1288       if (!read_bytes (r, buffer, chunk))
1289         return false;
1290       bytes -= chunk;
1291     }
1292
1293   return true;
1294 }
1295 \f
1296 static bool
1297 pcp_seek (struct pcp_reader *r, off_t offset)
1298 {
1299   if (fseeko (r->file, offset, SEEK_SET))
1300     {
1301       pcp_error (r, 0, _("%s: seek failed (%s)."),
1302                  fh_get_file_name (r->fh), strerror (errno));
1303       return false;
1304     }
1305   r->pos = offset;
1306   return true;
1307 }
1308
1309 /* Reads a 64-bit floating-point number from R and returns its
1310    value in host format. */
1311 static bool
1312 read_float (struct pcp_reader *r, double *d)
1313 {
1314   uint8_t number[8];
1315
1316   if (!read_bytes (r, number, sizeof number))
1317     return false;
1318   else
1319     {
1320       *d = parse_float (number);
1321       return true;
1322     }
1323 }
1324
1325 static double
1326 parse_float (const uint8_t number[8])
1327 {
1328   return (pcp_is_sysmis (number)
1329           ? SYSMIS
1330           : float_get_double (FLOAT_IEEE_DOUBLE_LE, number));
1331 }
1332
1333 static bool
1334 pcp_is_sysmis(const uint8_t *p)
1335 {
1336   static const uint8_t sysmis[8]
1337     = { 0xf5, 0x1e, 0x26, 0x02, 0x8a, 0x8c, 0xed, 0xff };
1338   return !memcmp (p, sysmis, 8);
1339 }
1340 \f
1341 static const struct casereader_class pcp_file_casereader_class =
1342   {
1343     pcp_file_casereader_read,
1344     pcp_file_casereader_destroy,
1345     NULL,
1346     NULL,
1347   };
1348
1349 const struct any_reader_class pcp_file_reader_class =
1350   {
1351     N_("SPSS/PC+ System File"),
1352     pcp_detect,
1353     pcp_open,
1354     pcp_close,
1355     pcp_decode,
1356     pcp_get_strings,
1357   };