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