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