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