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