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