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