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