Test both compressed and uncompressed system files with very long
[pspp] / src / data / data-in.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006 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-in.h"
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <math.h>
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdbool.h>
30
31 #include "calendar.h"
32 #include "identifier.h"
33 #include "settings.h"
34 #include "value.h"
35
36 #include <libpspp/assertion.h>
37 #include <libpspp/compiler.h>
38 #include <libpspp/integer-format.h>
39 #include <libpspp/magic.h>
40 #include <libpspp/message.h>
41 #include <libpspp/misc.h>
42 #include <libpspp/str.h>
43
44 #include "c-ctype.h"
45 #include "minmax.h"
46 #include "size_max.h"
47 #include "xalloc.h"
48
49 #include "gettext.h"
50 #define _(msgid) gettext (msgid)
51 \f
52 /* Information about parsing one data field. */
53 struct data_in
54   {
55     struct substring input;     /* Source. */
56     enum fmt_type format;       /* Input format. */
57     int implied_decimals;       /* Number of implied decimal places. */
58
59     union value *output;        /* Destination. */
60     int width;                  /* Output width. */
61
62     int first_column;           /* First column of field; 0 if inapplicable. */
63     int last_column;            /* Last column. */
64   };
65
66 /* Integer format used for IB and PIB input. */
67 static enum integer_format input_integer_format = INTEGER_NATIVE;
68
69 /* Floating-point format used for RB and RBHEX input. */
70 static enum float_format input_float_format = FLOAT_NATIVE_DOUBLE;
71
72 typedef bool data_in_parser_func (struct data_in *);
73 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
74         static data_in_parser_func parse_##METHOD;
75 #include "format.def"
76
77 static void vdata_warning (const struct data_in *, const char *, va_list)
78      PRINTF_FORMAT (2, 0);
79 static void data_warning (const struct data_in *, const char *, ...)
80      PRINTF_FORMAT (2, 3);
81
82 static void apply_implied_decimals (struct data_in *);
83 static void default_result (struct data_in *);
84 static bool trim_spaces_and_check_missing (struct data_in *);
85
86 static int hexit_value (int c);
87 \f
88 /* Parses the characters in INPUT according to FORMAT.  Stores
89    the parsed representation in OUTPUT, which has the given WIDTH
90    (0 for a numeric field, otherwise the string width).
91
92    If no decimal point is included in a numeric format, then
93    IMPLIED_DECIMALS decimal places are implied.  Specify 0 if no
94    decimal places should be implied.
95
96    If FIRST_COLUMN is nonzero, then it should be the 1-based
97    column number of the first character in INPUT, used in error
98    messages. */
99 bool
100 data_in (struct substring input,
101          enum fmt_type format, int implied_decimals,
102          int first_column, union value *output, int width)
103 {
104   static data_in_parser_func *const handlers[FMT_NUMBER_OF_FORMATS] =
105     {
106 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) parse_##METHOD,
107 #include "format.def"
108     };
109
110   struct data_in i;
111   bool ok;
112
113   assert ((width != 0) == fmt_is_string (format));
114
115   i.input = input;
116   i.format = format;
117   i.implied_decimals = implied_decimals;
118
119   i.output = output;
120   i.width = width;
121
122   i.first_column = first_column;
123   i.last_column = first_column + ss_length (input) - 1;
124
125   if (!ss_is_empty (i.input))
126     {
127       ok = handlers[i.format] (&i);
128       if (!ok)
129         default_result (&i);
130     }
131   else
132     {
133       default_result (&i);
134       ok = true;
135     }
136
137   return ok;
138 }
139
140 /* Returns the integer format used for IB and PIB input. */
141 enum integer_format
142 data_in_get_integer_format (void)
143 {
144   return input_integer_format;
145 }
146
147 /* Sets the integer format used for IB and PIB input to
148    FORMAT. */
149 void
150 data_in_set_integer_format (enum integer_format format)
151 {
152   input_integer_format = format;
153 }
154
155 /* Returns the floating-point format used for RB and RBHEX
156    input. */
157 enum float_format
158 data_in_get_float_format (void)
159 {
160   return input_float_format;
161 }
162
163 /* Sets the floating-point format used for RB and RBHEX input to
164    FORMAT. */
165 void
166 data_in_set_float_format (enum float_format format)
167 {
168   input_float_format = format;
169 }
170 \f
171 /* Format parsers. */
172
173 /* Parses F, COMMA, DOT, DOLLAR, PCT, and E input formats. */
174 static bool
175 parse_number (struct data_in *i)
176 {
177   const struct fmt_number_style *style = fmt_get_style (i->format);
178
179   struct string tmp;
180
181   bool explicit_decimals = false;
182   int save_errno;
183   char *tail;
184
185   assert (fmt_get_category (i->format) != FMT_CAT_CUSTOM);
186
187   /* Trim spaces and check for missing value representation. */
188   if (trim_spaces_and_check_missing (i))
189     return true;
190
191   ds_init_empty (&tmp);
192   ds_extend (&tmp, 64);
193
194   /* Prefix character may precede sign. */
195   if (!ss_is_empty (style->prefix))
196     {
197       ss_match_char (&i->input, ss_first (style->prefix));
198       ss_ltrim (&i->input, ss_cstr (CC_SPACES));
199     }
200
201   /* Sign. */
202   if (ss_match_char (&i->input, '-'))
203     {
204       ds_put_char (&tmp, '-');
205       ss_ltrim (&i->input, ss_cstr (CC_SPACES));
206     }
207   else
208     {
209       ss_match_char (&i->input, '+');
210       ss_ltrim (&i->input, ss_cstr (CC_SPACES));
211     }
212
213   /* Prefix character may follow sign. */
214   if (!ss_is_empty (style->prefix))
215     {
216       ss_match_char (&i->input, ss_first (style->prefix));
217       ss_ltrim (&i->input, ss_cstr (CC_SPACES));
218     }
219
220   /* Digits before decimal point. */
221   while (c_isdigit (ss_first (i->input)))
222     {
223       ds_put_char (&tmp, ss_get_char (&i->input));
224       if (style->grouping != 0)
225         ss_match_char (&i->input, style->grouping);
226     }
227
228   /* Decimal point and following digits. */
229   if (ss_match_char (&i->input, style->decimal))
230     {
231       explicit_decimals = true;
232       ds_put_char (&tmp, '.');
233       while (c_isdigit (ss_first (i->input)))
234         ds_put_char (&tmp, ss_get_char (&i->input));
235     }
236
237   /* Exponent. */
238   if (!ds_is_empty (&tmp)
239       && !ss_is_empty (i->input)
240       && strchr ("eEdD-+", ss_first (i->input)))
241     {
242       explicit_decimals = true;
243       ds_put_char (&tmp, 'e');
244
245       if (strchr ("eEdD", ss_first (i->input)))
246         {
247           ss_advance (&i->input, 1);
248           ss_match_char (&i->input, ' ');
249         }
250
251       if (ss_first (i->input) == '-' || ss_first (i->input) == '+')
252         {
253           if (ss_get_char (&i->input) == '-')
254             ds_put_char (&tmp, '-');
255           ss_match_char (&i->input, ' ');
256         }
257
258       while (c_isdigit (ss_first (i->input)))
259         ds_put_char (&tmp, ss_get_char (&i->input));
260     }
261
262   /* Suffix character. */
263   if (!ss_is_empty (style->suffix))
264     ss_match_char (&i->input, ss_first (style->suffix));
265
266   if (!ss_is_empty (i->input))
267     {
268       if (ds_is_empty (&tmp))
269         data_warning (i, _("Field contents are not numeric."));
270       else
271         data_warning (i, _("Number followed by garbage."));
272       ds_destroy (&tmp);
273       return false;
274     }
275
276   /* Let strtod() do the conversion. */
277   save_errno = errno;
278   errno = 0;
279   i->output->f = strtod (ds_cstr (&tmp), &tail);
280   if (*tail != '\0')
281     {
282       data_warning (i, _("Invalid numeric syntax."));
283       errno = save_errno;
284       ds_destroy (&tmp);
285       return false;
286     }
287   else if (errno == ERANGE)
288     {
289       if (fabs (i->output->f) > 1)
290         {
291           data_warning (i, _("Too-large number set to system-missing."));
292           i->output->f = SYSMIS;
293         }
294       else
295         {
296           data_warning (i, _("Too-small number set to zero."));
297           i->output->f = 0.0;
298         }
299     }
300   else
301     {
302       errno = save_errno;
303       if (!explicit_decimals)
304         apply_implied_decimals (i);
305     }
306
307   ds_destroy (&tmp);
308   return true;
309 }
310
311 /* Parses N format. */
312 static bool
313 parse_N (struct data_in *i)
314 {
315   int c;
316
317   i->output->f = 0;
318   while ((c = ss_get_char (&i->input)) != EOF)
319     {
320       if (!c_isdigit (c))
321         {
322           data_warning (i, _("All characters in field must be digits."));
323           return false;
324         }
325       i->output->f = i->output->f * 10.0 + (c - '0');
326     }
327
328   apply_implied_decimals (i);
329   return true;
330 }
331
332 /* Parses PIBHEX format. */
333 static bool
334 parse_PIBHEX (struct data_in *i)
335 {
336   double n;
337   int c;
338
339   n = 0.0;
340
341   while ((c = ss_get_char (&i->input)) != EOF)
342     {
343       if (!c_isxdigit (c))
344         {
345           data_warning (i, _("Unrecognized character in field."));
346           return false;
347         }
348       n = n * 16.0 + hexit_value (c);
349     }
350
351   i->output->f = n;
352   return true;
353 }
354
355 /* Parses RBHEX format. */
356 static bool
357 parse_RBHEX (struct data_in *i)
358 {
359   double d;
360   size_t j;
361
362   memset (&d, 0, sizeof d);
363   for (j = 0; !ss_is_empty (i->input) && j < sizeof d; j++)
364     {
365       int hi = ss_get_char (&i->input);
366       int lo = ss_get_char (&i->input);
367       if (lo == EOF)
368         {
369           data_warning (i, _("Field must have even length."));
370           return false;
371         }
372       else if (!c_isxdigit (hi) || !c_isxdigit (lo))
373         {
374           data_warning (i, _("Field must contain only hex digits."));
375           return false;
376         }
377       ((unsigned char *) &d)[j] = 16 * hexit_value (hi) + hexit_value (lo);
378     }
379
380   i->output->f = d;
381
382   return true;
383 }
384
385 /* Digits for Z format. */
386 static const char z_digits[] = "0123456789{ABCDEFGHI}JKLMNOPQR";
387
388 /* Returns true if C is a Z format digit, false otherwise. */
389 static bool
390 is_z_digit (int c)
391 {
392   return c > 0 && strchr (z_digits, c) != NULL;
393 }
394
395 /* Returns the (absolute value of the) value of C as a Z format
396    digit. */
397 static int
398 z_digit_value (int c)
399 {
400   assert (is_z_digit (c));
401   return (strchr (z_digits, c) - z_digits) % 10;
402 }
403
404 /* Returns true if Z format digit C represents a negative value,
405    false otherwise. */
406 static bool
407 is_negative_z_digit (int c)
408 {
409   assert (is_z_digit (c));
410   return (strchr (z_digits, c) - z_digits) >= 20;
411 }
412
413 /* Parses Z format. */
414 static bool
415 parse_Z (struct data_in *i)
416 {
417   struct string tmp;
418
419   int save_errno;
420
421   bool got_dot = false;
422   bool got_final_digit = false;
423
424   /* Trim spaces and check for missing value representation. */
425   if (trim_spaces_and_check_missing (i))
426     return true;
427
428   ds_init_empty (&tmp);
429   ds_extend (&tmp, 64);
430
431   ds_put_char (&tmp, '+');
432   while (!ss_is_empty (i->input))
433     {
434       int c = ss_get_char (&i->input);
435       if (c_isdigit (c) && !got_final_digit)
436         ds_put_char (&tmp, c);
437       else if (is_z_digit (c) && !got_final_digit)
438         {
439           ds_put_char (&tmp, z_digit_value (c) + '0');
440           if (is_negative_z_digit (c))
441             ds_data (&tmp)[0] = '-';
442           got_final_digit = true;
443         }
444       else if (c == '.' && !got_dot)
445         {
446           ds_put_char (&tmp, '.');
447           got_dot = true;
448         }
449       else
450         {
451           ds_destroy (&tmp);
452           return false;
453         }
454     }
455
456   if (!ss_is_empty (i->input))
457     {
458       if (ds_length (&tmp) == 1)
459         data_warning (i, _("Field contents are not numeric."));
460       else
461         data_warning (i, _("Number followed by garbage."));
462       ds_destroy (&tmp);
463       return false;
464     }
465
466   /* Let strtod() do the conversion. */
467   save_errno = errno;
468   errno = 0;
469   i->output->f = strtod (ds_cstr (&tmp), NULL);
470   if (errno == ERANGE)
471     {
472       if (fabs (i->output->f) > 1)
473         {
474           data_warning (i, _("Too-large number set to system-missing."));
475           i->output->f = SYSMIS;
476         }
477       else
478         {
479           data_warning (i, _("Too-small number set to zero."));
480           i->output->f = 0.0;
481         }
482     }
483   else
484     {
485       errno = save_errno;
486       if (!got_dot)
487         apply_implied_decimals (i);
488     }
489
490   ds_destroy (&tmp);
491   return true;
492 }
493
494 /* Parses IB format. */
495 static bool
496 parse_IB (struct data_in *i)
497 {
498   size_t bytes;
499   uint64_t value;
500   uint64_t sign_bit;
501
502   bytes = MIN (8, ss_length (i->input));
503   value = integer_get (input_integer_format, ss_data (i->input), bytes);
504
505   sign_bit = UINT64_C(1) << (8 * bytes - 1);
506   if (!(value & sign_bit))
507     i->output->f = value;
508   else
509     {
510       /* Sign-extend to full 64 bits. */
511       value -= sign_bit << 1;
512       i->output->f = -(double) -value;
513     }
514
515   apply_implied_decimals (i);
516
517   return true;
518 }
519
520 /* Parses PIB format. */
521 static bool
522 parse_PIB (struct data_in *i)
523 {
524   i->output->f = integer_get (input_integer_format, ss_data (i->input),
525                               MIN (8, ss_length (i->input)));
526
527   apply_implied_decimals (i);
528
529   return true;
530 }
531
532 /* Consumes the first character of S.  Stores its high 4 bits in
533    HIGH_NIBBLE and its low 4 bits in LOW_NIBBLE. */
534 static void
535 get_nibbles (struct substring *s, int *high_nibble, int *low_nibble)
536 {
537   int c = ss_get_char (s);
538   assert (c != EOF);
539   *high_nibble = (c >> 4) & 15;
540   *low_nibble = c & 15;
541 }
542
543 /* Parses P format. */
544 static bool
545 parse_P (struct data_in *i)
546 {
547   int high_nibble, low_nibble;
548
549   i->output->f = 0.0;
550
551   while (ss_length (i->input) > 1)
552     {
553       get_nibbles (&i->input, &high_nibble, &low_nibble);
554       if (high_nibble > 9 || low_nibble > 9)
555         return false;
556       i->output->f = (100 * i->output->f) + (10 * high_nibble) + low_nibble;
557     }
558
559   get_nibbles (&i->input, &high_nibble, &low_nibble);
560   if (high_nibble > 9)
561     return false;
562   i->output->f = (10 * i->output->f) + high_nibble;
563   if (low_nibble < 10)
564     i->output->f = (10 * i->output->f) + low_nibble;
565   else if (low_nibble == 0xb || low_nibble == 0xd)
566     i->output->f = -i->output->f;
567
568   apply_implied_decimals (i);
569
570   return true;
571 }
572
573 /* Parses PK format. */
574 static bool
575 parse_PK (struct data_in *i)
576 {
577   i->output->f = 0.0;
578   while (!ss_is_empty (i->input))
579     {
580       int high_nibble, low_nibble;
581
582       get_nibbles (&i->input, &high_nibble, &low_nibble);
583       if (high_nibble > 9 || low_nibble > 9)
584         {
585           i->output->f = SYSMIS;
586           return true;
587         }
588       i->output->f = (100 * i->output->f) + (10 * high_nibble) + low_nibble;
589     }
590
591   apply_implied_decimals (i);
592
593   return true;
594 }
595
596 /* Parses RB format. */
597 static bool
598 parse_RB (struct data_in *i)
599 {
600   size_t size = float_get_size (input_float_format);
601   if (ss_length (i->input) >= size)
602     float_convert (input_float_format, ss_data (i->input),
603                    FLOAT_NATIVE_DOUBLE, &i->output->f);
604   else
605     i->output->f = SYSMIS;
606
607   return true;
608 }
609
610 /* Parses A format. */
611 static bool
612 parse_A (struct data_in *i)
613 {
614   buf_copy_rpad (i->output->s, i->width,
615                  ss_data (i->input), ss_length (i->input));
616   return true;
617 }
618
619 /* Parses AHEX format. */
620 static bool
621 parse_AHEX (struct data_in *i)
622 {
623   size_t j;
624
625   for (j = 0; ; j++)
626     {
627       int hi = ss_get_char (&i->input);
628       int lo = ss_get_char (&i->input);
629       if (hi == EOF)
630         break;
631       else if (lo == EOF)
632         {
633           data_warning (i, _("Field must have even length."));
634           return false;
635         }
636
637       if (!c_isxdigit (hi) || !c_isxdigit (lo))
638         {
639           data_warning (i, _("Field must contain only hex digits."));
640           return false;
641         }
642
643       if (j < i->width)
644         i->output->s[j] = hexit_value (hi) * 16 + hexit_value (lo);
645     }
646
647   memset (i->output->s + j, ' ', i->width - j);
648
649   return true;
650 }
651 \f
652 /* Date & time format components. */
653
654 /* Sign of a time value. */
655 enum time_sign
656   {
657     SIGN_NO_TIME,       /* No time yet encountered. */
658     SIGN_POSITIVE,      /* Positive time. */
659     SIGN_NEGATIVE       /* Negative time. */
660   };
661
662 /* Parses a signed decimal integer from at most the first
663    MAX_DIGITS characters in I, storing the result into *RESULT.
664    Returns true if successful, false if no integer was
665    present. */
666 static bool
667 parse_int (struct data_in *i, long *result, size_t max_digits)
668 {
669   struct substring head = ss_head (i->input, max_digits);
670   size_t n = ss_get_long (&head, result);
671   if (n)
672     {
673       ss_advance (&i->input, n);
674       return true;
675     }
676   else
677     {
678       data_warning (i, _("Syntax error in date field."));
679       return false;
680     }
681 }
682
683 /* Parses a date integer between 1 and 31 from I, storing it into
684    *DAY.
685    Returns true if successful, false if no date was present. */
686 static bool
687 parse_day (struct data_in *i, long *day)
688 {
689   if (!parse_int (i, day, SIZE_MAX))
690     return false;
691   if (*day >= 1 && *day <= 31)
692     return true;
693
694   data_warning (i, _("Day (%ld) must be between 1 and 31."), *day);
695   return false;
696 }
697
698 /* Parses an integer from the beginning of I.
699    Adds SECONDS_PER_UNIT times the absolute value of the integer
700    to *TIME.
701    If *TIME_SIGN is SIGN_NO_TIME, allows a sign to precede the
702    time and sets *TIME_SIGN.  Otherwise, does not allow a sign.
703    Returns true if successful, false if no integer was present. */
704 static bool
705 parse_time_units (struct data_in *i, double seconds_per_unit,
706                   enum time_sign *time_sign, double *time)
707
708 {
709   long units;
710
711   if (*time_sign == SIGN_NO_TIME)
712     {
713       if (ss_match_char (&i->input, '-'))
714         *time_sign = SIGN_NEGATIVE;
715       else
716         {
717           ss_match_char (&i->input, '+');
718           *time_sign = SIGN_POSITIVE;
719         }
720     }
721   if (!parse_int (i, &units, SIZE_MAX))
722     return false;
723   if (units < 0)
724     {
725       data_warning (i, _("Syntax error in date field."));
726       return false;
727     }
728   *time += units * seconds_per_unit;
729   return true;
730 }
731
732 /* Parses a data delimiter from the beginning of I.
733    Returns true if successful, false if no delimiter was
734    present. */
735 static bool
736 parse_date_delimiter (struct data_in *i)
737 {
738   if (ss_ltrim (&i->input, ss_cstr ("-/.," CC_SPACES)))
739     return true;
740
741   data_warning (i, _("Delimiter expected between fields in date."));
742   return false;
743 }
744
745 /* Parses spaces at the beginning of I. */
746 static void
747 parse_spaces (struct data_in *i)
748 {
749   ss_ltrim (&i->input, ss_cstr (CC_SPACES));
750 }
751
752 static struct substring
753 parse_name_token (struct data_in *i)
754 {
755   struct substring token;
756   ss_get_chars (&i->input, ss_span (i->input, ss_cstr (CC_LETTERS)), &token);
757   return token;
758 }
759
760 /* Reads a name from I and sets *OUTPUT to the value associated
761    with that name.  If ALLOW_SUFFIXES is true, then names that
762    begin with one of the names are accepted; otherwise, only
763    exact matches (except for case) are allowed.
764    Returns true if successful, false otherwise. */
765 static bool
766 match_name (struct substring token, const char **names, long *output)
767 {
768   int i;
769
770   for (i = 1; *names != NULL; i++)
771     if (ss_equals_case (ss_cstr (*names++), token))
772       {
773         *output = i;
774         return true;
775       }
776
777   return false;
778 }
779
780 /* Parses a month name or number from the beginning of I,
781    storing the month (in range 1...12) into *MONTH.
782    Returns true if successful, false if no month was present. */
783 static bool
784 parse_month (struct data_in *i, long *month)
785 {
786   if (c_isdigit (ss_first (i->input)))
787     {
788       if (!parse_int (i, month, SIZE_MAX))
789         return false;
790       if (*month >= 1 && *month <= 12)
791         return true;
792     }
793   else
794     {
795       static const char *english_names[] =
796         {
797           "jan", "feb", "mar", "apr", "may", "jun",
798           "jul", "aug", "sep", "oct", "nov", "dec",
799           NULL,
800         };
801
802       static const char *roman_names[] =
803         {
804           "i", "ii", "iii", "iv", "v", "vi",
805           "vii", "viii", "ix", "x", "xi", "xii",
806           NULL,
807         };
808
809       struct substring token = parse_name_token (i);
810       if (match_name (ss_head (token, 3), english_names, month)
811           || match_name (ss_head (token, 4), roman_names, month))
812         return true;
813     }
814
815   data_warning (i, _("Unrecognized month format.  Months may be specified "
816                      "as Arabic or Roman numerals or as at least 3 letters "
817                      "of their English names."));
818   return false;
819 }
820
821 /* Parses a year of at most MAX_DIGITS from the beginning of I,
822    storing a "4-digit" year into *YEAR. */
823 static bool
824 parse_year (struct data_in *i, long *year, size_t max_digits)
825 {
826   if (!parse_int (i, year, max_digits))
827     return false;
828
829   if (*year >= 0 && *year <= 99)
830     {
831       int epoch = get_epoch ();
832       int epoch_century = ROUND_DOWN (epoch, 100);
833       int epoch_offset = epoch - epoch_century;
834       if (*year >= epoch_offset)
835         *year += epoch_century;
836       else
837         *year += epoch_century + 100;
838     }
839   if (*year >= 1582 || *year <= 19999)
840     return true;
841
842   data_warning (i, _("Year (%ld) must be between 1582 and 19999."), *year);
843   return false;
844 }
845
846 /* Returns true if input in I has been exhausted,
847    false otherwise. */
848 static bool
849 parse_trailer (struct data_in *i)
850 {
851   if (ss_is_empty (i->input))
852     return true;
853
854   data_warning (i, _("Trailing garbage \"%.*s\" following date."),
855               (int) ss_length (i->input), ss_data (i->input));
856   return false;
857 }
858
859 /* Parses a 3-digit Julian day-of-year value from I into *YDAY.
860    Returns true if successful, false on failure. */
861 static bool
862 parse_yday (struct data_in *i, long *yday)
863 {
864   struct substring num_s;
865   long num;
866
867   ss_get_chars (&i->input, 3, &num_s);
868   if (ss_span (num_s, ss_cstr (CC_DIGITS)) != 3)
869     {
870       data_warning (i, _("Julian day must have exactly three digits."));
871       return false;
872     }
873   else if (!ss_get_long (&num_s, &num) || num < 1 || num > 366)
874     {
875       data_warning (i, _("Julian day (%ld) must be between 1 and 366."), num);
876       return false;
877     }
878
879   *yday = num;
880   return true;
881 }
882
883 /* Parses a quarter-of-year integer between 1 and 4 from I.
884    Stores the corresponding month into *MONTH.
885    Returns true if successful, false if no quarter was present. */
886 static bool
887 parse_quarter (struct data_in *i, long int *month)
888 {
889   long quarter;
890
891   if (!parse_int (i, &quarter, SIZE_MAX))
892     return false;
893   if (quarter >= 1 && quarter <= 4)
894     {
895       *month = (quarter - 1) * 3 + 1;
896       return true;
897     }
898
899   data_warning (i, _("Quarter (%ld) must be between 1 and 4."), quarter);
900   return false;
901 }
902
903 /* Parses a week-of-year integer between 1 and 53 from I,
904    Stores the corresponding year-of-day into *YDAY.
905    Returns true if successful, false if no week was present. */
906 static bool
907 parse_week (struct data_in *i, long int *yday)
908 {
909   long week;
910
911   if (!parse_int (i, &week, SIZE_MAX))
912     return false;
913   if (week >= 1 && week <= 53)
914     {
915       *yday = (week - 1) * 7 + 1;
916       return true;
917     }
918
919   data_warning (i, _("Week (%ld) must be between 1 and 53."), week);
920   return false;
921 }
922
923 /* Parses a time delimiter from the beginning of I.
924    Returns true if successful, false if no delimiter was
925    present. */
926 static bool
927 parse_time_delimiter (struct data_in *i)
928 {
929   if (ss_ltrim (&i->input, ss_cstr (":" CC_SPACES)) > 0)
930     return true;
931
932   data_warning (i, _("Delimiter expected between fields in time."));
933   return false;
934 }
935
936 /* Parses minutes and optional seconds from the beginning of I.
937    The time is converted into seconds, which are added to
938    *TIME.
939    Returns true if successful, false if an error was found. */
940 static bool
941 parse_minute_second (struct data_in *i, double *time)
942 {
943   long minute;
944   char buf[64];
945   char *cp;
946
947   /* Parse minutes. */
948   if (!parse_int (i, &minute, SIZE_MAX))
949     return false;
950   if (minute < 0 || minute > 59)
951     {
952       data_warning (i, _("Minute (%ld) must be between 0 and 59."), minute);
953       return false;
954     }
955   *time += 60. * minute;
956
957   /* Check for seconds. */
958   if (ss_ltrim (&i->input, ss_cstr (":" CC_SPACES)) == 0
959       || !c_isdigit (ss_first (i->input)))
960    return true;
961
962   /* Parse seconds. */
963   cp = buf;
964   while (c_isdigit (ss_first (i->input)))
965     *cp++ = ss_get_char (&i->input);
966   if (ss_match_char (&i->input, fmt_decimal_char (FMT_F)))
967     *cp++ = '.';
968   while (c_isdigit (ss_first (i->input)))
969     *cp++ = ss_get_char (&i->input);
970   *cp = '\0';
971
972   *time += strtod (buf, NULL);
973
974   return true;
975 }
976
977 /* Parses a weekday name from the beginning of I,
978    storing a value of 1=Sunday...7=Saturday into *WEEKDAY.
979    Returns true if successful, false if an error was found. */
980 static bool
981 parse_weekday (struct data_in *i, long *weekday)
982 {
983   static const char *weekday_names[] =
984     {
985       "su", "mo", "tu", "we", "th", "fr", "sa",
986       NULL,
987     };
988
989   struct substring token = parse_name_token (i);
990   bool ok = match_name (ss_head (token, 2), weekday_names, weekday);
991   if (!ok)
992     data_warning (i, _("Unrecognized weekday name.  At least the first two "
993                        "letters of an English weekday name must be "
994                        "specified."));
995   return ok;
996 }
997 \f
998 /* Date & time formats. */
999
1000 /* Helper function for passing to
1001    calendar_gregorian_to_offset. */
1002 static void
1003 calendar_error (void *i_, const char *format, ...)
1004 {
1005   struct data_in *i = i_;
1006   va_list args;
1007
1008   va_start (args, format);
1009   vdata_warning (i, format, args);
1010   va_end (args);
1011 }
1012
1013 /* Parses WKDAY format. */
1014 static bool
1015 parse_WKDAY (struct data_in *i)
1016 {
1017   long weekday;
1018
1019   if (trim_spaces_and_check_missing (i))
1020     return true;
1021
1022   if (!parse_weekday (i, &weekday)
1023       || !parse_trailer (i))
1024     return false;
1025
1026   i->output->f = weekday;
1027   return true;
1028 }
1029
1030 /* Parses MONTH format. */
1031 static bool
1032 parse_MONTH (struct data_in *i)
1033 {
1034   long month;
1035
1036   if (trim_spaces_and_check_missing (i))
1037     return true;
1038
1039   if (!parse_month (i, &month)
1040       || !parse_trailer (i))
1041     return false;
1042
1043   i->output->f = month;
1044   return true;
1045 }
1046
1047 /* Parses DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, KWYR,
1048    DATETIME, TIME and DTIME formats. */
1049 static bool
1050 parse_date (struct data_in *i)
1051 {
1052   long int year = INT_MIN;
1053   long int month = 1;
1054   long int day = 1;
1055   long int yday = 1;
1056   double time = 0, date = 0;
1057   enum time_sign time_sign = SIGN_NO_TIME;
1058
1059   const char *template = fmt_date_template (i->format);
1060   size_t template_width = strlen (template);
1061
1062   if (trim_spaces_and_check_missing (i))
1063     return true;
1064
1065   while (*template != '\0')
1066     {
1067       unsigned char ch = *template;
1068       int count = 1;
1069       bool ok;
1070
1071       while (template[count] == ch)
1072         count++;
1073       template += count;
1074
1075       ok = true;
1076       switch (ch)
1077         {
1078         case 'd':
1079           ok = count < 3 ? parse_day (i, &day) : parse_yday (i, &yday);
1080           break;
1081         case 'm':
1082           ok = parse_month (i, &month);
1083           break;
1084         case 'y':
1085           {
1086             size_t max_digits;
1087             if (!c_isalpha (*template))
1088               max_digits = SIZE_MAX;
1089             else
1090               {
1091                 if (ss_length (i->input) >= template_width + 2)
1092                   max_digits = 4;
1093                 else
1094                   max_digits = 2;
1095               }
1096             ok = parse_year (i, &year, max_digits);
1097           }
1098           break;
1099         case 'q':
1100           ok = parse_quarter (i, &month);
1101           break;
1102         case 'w':
1103           ok = parse_week (i, &yday);
1104           break;
1105         case 'D':
1106           ok = parse_time_units (i, 60. * 60. * 24., &time_sign, &time);
1107           break;
1108         case 'H':
1109           ok = parse_time_units (i, 60. * 60., &time_sign, &time);
1110           break;
1111         case 'M':
1112           ok = parse_minute_second (i, &time);
1113           break;
1114         case '-':
1115         case '/':
1116         case '.':
1117         case 'X':
1118           ok = parse_date_delimiter (i);
1119           break;
1120         case ':':
1121           ok = parse_time_delimiter (i);
1122         case ' ':
1123           parse_spaces (i);
1124           break;
1125         default:
1126           assert (count == 1);
1127           if (!ss_match_char (&i->input, c_toupper (ch))
1128               && !ss_match_char (&i->input, c_tolower (ch)))
1129             {
1130               data_warning (i, _("`%c' expected in date field."), ch);
1131               return false;
1132             }
1133           break;
1134         }
1135       if (!ok)
1136         return false;
1137     }
1138   if (!parse_trailer (i))
1139     return false;
1140
1141   if (year != INT_MIN)
1142     {
1143       double ofs = calendar_gregorian_to_offset (year, month, day,
1144                                                  calendar_error, i);
1145       if (ofs == SYSMIS)
1146         return false;
1147       date = (yday - 1 + ofs) * 60. * 60. * 24.;
1148     }
1149   else
1150     date = 0.;
1151   i->output->f = date + (time_sign == SIGN_NEGATIVE ? -time : time);
1152
1153   return true;
1154 }
1155 \f
1156 /* Utility functions. */
1157
1158 /* Outputs FORMAT with the given ARGS as a warning for input
1159    I. */
1160 static void
1161 vdata_warning (const struct data_in *i, const char *format, va_list args)
1162 {
1163   struct msg m;
1164   struct string text;
1165
1166   ds_init_empty (&text);
1167   ds_put_char (&text, '(');
1168   if (i->first_column != 0)
1169     {
1170       if (i->first_column == i->last_column)
1171         ds_put_format (&text, _("column %d"), i->first_column);
1172       else
1173         ds_put_format (&text, _("columns %d-%d"),
1174                        i->first_column, i->last_column);
1175       ds_put_cstr (&text, ", ");
1176     }
1177   ds_put_format (&text, _("%s field) "), fmt_name (i->format));
1178   ds_put_vformat (&text, format, args);
1179
1180   m.category = MSG_DATA;
1181   m.severity = MSG_WARNING;
1182   m.text = ds_cstr (&text);
1183
1184   msg_emit (&m);
1185 }
1186
1187 /* Outputs FORMAT with the given ARGS as a warning for input
1188    I. */
1189 static void
1190 data_warning (const struct data_in *i, const char *format, ...)
1191 {
1192   va_list args;
1193
1194   va_start (args, format);
1195   vdata_warning (i, format, args);
1196   va_end (args);
1197 }
1198
1199 /* Apply implied decimal places to output. */
1200 static void
1201 apply_implied_decimals (struct data_in *i)
1202 {
1203   if (i->implied_decimals > 0)
1204     i->output->f /= pow (10., i->implied_decimals);
1205 }
1206
1207 /* Sets the default result for I.
1208    For a numeric format, this is the value set on SET BLANKS
1209    (typically system-missing); for a string format, it is all
1210    spaces. */
1211 static void
1212 default_result (struct data_in *i)
1213 {
1214   if (fmt_is_string (i->format))
1215     memset (i->output->s, ' ', i->width);
1216   else
1217     i->output->f = get_blanks ();
1218 }
1219
1220 /* Trims leading and trailing spaces from I.
1221    If the result is empty, or a single period character, then
1222    sets the default result and returns true; otherwise, returns
1223    false. */
1224 static bool
1225 trim_spaces_and_check_missing (struct data_in *i)
1226 {
1227   ss_trim (&i->input, ss_cstr (" "));
1228   if (ss_is_empty (i->input) || ss_equals (i->input, ss_cstr (".")))
1229     {
1230       default_result (i);
1231       return true;
1232     }
1233   return false;
1234 }
1235
1236 /* Returns the integer value of hex digit C. */
1237 static int
1238 hexit_value (int c)
1239 {
1240   const char s[] = "0123456789abcdef";
1241   const char *cp = strchr (s, c_tolower ((unsigned char) c));
1242
1243   assert (cp != NULL);
1244   return cp - s;
1245 }