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