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