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