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