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