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