Replace legacy_recode with recode_string.
[pspp-builds.git] / src / data / data-in.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2009 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 #include <limits.h>
31
32 #include "calendar.h"
33 #include "identifier.h"
34 #include "settings.h"
35 #include "value.h"
36 #include "format.h"
37
38 #include <libpspp/assertion.h>
39 #include <libpspp/legacy-encoding.h>
40 #include <libpspp/i18n.h>
41 #include <libpspp/compiler.h>
42 #include <libpspp/integer-format.h>
43 #include <libpspp/message.h>
44 #include <libpspp/misc.h>
45 #include <libpspp/str.h>
46 #include "c-ctype.h"
47 #include "c-strtod.h"
48 #include "minmax.h"
49 #include "xalloc.h"
50
51 #include "gettext.h"
52 #define _(msgid) gettext (msgid)
53 \f
54 /* Information about parsing one data field. */
55 struct data_in
56   {
57     const char *encoding;       /* Encoding of source. */
58     struct substring input;     /* Source. */
59     enum fmt_type format;       /* Input format. */
60     int implied_decimals;       /* Number of implied decimal places. */
61
62     union value *output;        /* Destination. */
63     int width;                  /* Output width. */
64
65     int first_column;           /* First column of field; 0 if inapplicable. */
66     int last_column;            /* Last column. */
67   };
68
69
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, which are encoded in the given
88    ENCODING, according to FORMAT.  Stores the parsed
89    representation in OUTPUT, which the caller must have
90    initialized with the given WIDTH (0 for a numeric field,
91    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 and LAST_COLUMN are nonzero, then they should
98    be the 1-based column number of the first and
99    one-past-the-last-character in INPUT, for use in error
100    messages.  (LAST_COLUMN cannot always be calculated from
101    FIRST_COLUMN plus the length of the input because of the
102    possibility of escaped quotes in strings, etc.) */
103 bool
104 data_in (struct substring input, const char *encoding,
105          enum fmt_type format, int implied_decimals,
106          int first_column, int last_column, union value *output, int width)
107 {
108   static data_in_parser_func *const handlers[FMT_NUMBER_OF_FORMATS] =
109     {
110 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) parse_##METHOD,
111 #include "format.def"
112     };
113
114   struct data_in i;
115   void *copy = NULL;
116   bool ok;
117
118   assert ((width != 0) == fmt_is_string (format));
119
120   if (0 == strcmp (encoding, LEGACY_NATIVE)
121       || fmt_get_category (format) & (FMT_CAT_BINARY | FMT_CAT_STRING))
122     {
123       i.input = input;
124       i.encoding = encoding;
125     }
126   else
127     {
128       char *s;
129       ss_alloc_uninit (&i.input, ss_length (input));
130
131       s = recode_string (LEGACY_NATIVE, encoding, ss_data (input), ss_length (input));
132       memcpy (ss_data (i.input), s, ss_length (input));
133       free (s);
134       i.encoding = LEGACY_NATIVE;
135       copy = ss_data (i.input);
136     }
137   i.format = format;
138   i.implied_decimals = implied_decimals;
139
140   i.output = output;
141   i.width = width;
142
143   i.first_column = first_column;
144   i.last_column = last_column;
145
146   if (!ss_is_empty (i.input))
147     {
148       ok = handlers[i.format] (&i);
149       if (!ok)
150         default_result (&i);
151     }
152   else
153     {
154       default_result (&i);
155       ok = true;
156     }
157
158   if (copy)
159     free (copy);
160
161   return ok;
162 }
163
164 \f
165 /* Format parsers. */
166
167 /* Parses F, COMMA, DOT, DOLLAR, PCT, and E input formats. */
168 static bool
169 parse_number (struct data_in *i)
170 {
171   const struct fmt_number_style *style =
172     settings_get_style (i->format);
173
174   struct string tmp;
175
176   bool explicit_decimals = false;
177   int save_errno;
178   char *tail;
179
180   if  (fmt_get_category (i->format) == FMT_CAT_CUSTOM)
181     {
182       style = settings_get_style (FMT_F);
183     }
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 c_strtod() do the conversion. */
275   save_errno = errno;
276   errno = 0;
277   i->output->f = c_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 c_strtod() do the conversion. */
465   save_errno = errno;
466   errno = 0;
467   i->output->f = c_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 (settings_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 (settings_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   enum float_format ff = settings_get_input_float_format ();
599   size_t size = float_get_size (ff);
600   if (ss_length (i->input) >= size)
601     float_convert (ff, 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   /* This is equivalent to buf_copy_rpad, except that we posibly
614      do a character set recoding in the middle. */
615   char *dst = value_str_rw (i->output, i->width);
616   size_t dst_size = i->width;
617   const char *src = ss_data (i->input);
618   size_t src_size = ss_length (i->input);
619
620   char *s = recode_string (LEGACY_NATIVE, i->encoding, src, MIN (src_size, dst_size));
621   memcpy (dst, s, dst_size);
622   free (s);
623   if (dst_size > src_size)
624     memset (&dst[src_size], ' ', dst_size - src_size);
625
626   return true;
627 }
628
629 /* Parses AHEX format. */
630 static bool
631 parse_AHEX (struct data_in *i)
632 {
633   char *s = value_str_rw (i->output, i->width);
634   size_t j;
635
636   for (j = 0; ; j++)
637     {
638       int hi = ss_get_char (&i->input);
639       int lo = ss_get_char (&i->input);
640       if (hi == EOF)
641         break;
642       else if (lo == EOF)
643         {
644           data_warning (i, _("Field must have even length."));
645           return false;
646         }
647
648       if (0 != strcmp (i->encoding, LEGACY_NATIVE))
649         {
650           hi = legacy_to_native (i->encoding, hi);
651           lo = legacy_to_native (i->encoding, lo);
652         }
653       if (!c_isxdigit (hi) || !c_isxdigit (lo))
654         {
655           data_warning (i, _("Field must contain only hex digits."));
656           return false;
657         }
658
659       if (j < i->width)
660         s[j] = hexit_value (hi) * 16 + hexit_value (lo);
661     }
662
663   memset (&s[j], ' ', i->width - j);
664
665   return true;
666 }
667 \f
668 /* Date & time format components. */
669
670 /* Sign of a time value. */
671 enum time_sign
672   {
673     SIGN_NO_TIME,       /* No time yet encountered. */
674     SIGN_POSITIVE,      /* Positive time. */
675     SIGN_NEGATIVE       /* Negative time. */
676   };
677
678 /* Parses a signed decimal integer from at most the first
679    MAX_DIGITS characters in I, storing the result into *RESULT.
680    Returns true if successful, false if no integer was
681    present. */
682 static bool
683 parse_int (struct data_in *i, long *result, size_t max_digits)
684 {
685   struct substring head = ss_head (i->input, max_digits);
686   size_t n = ss_get_long (&head, result);
687   if (n)
688     {
689       ss_advance (&i->input, n);
690       return true;
691     }
692   else
693     {
694       data_warning (i, _("Syntax error in date field."));
695       return false;
696     }
697 }
698
699 /* Parses a date integer between 1 and 31 from I, storing it into
700    *DAY.
701    Returns true if successful, false if no date was present. */
702 static bool
703 parse_day (struct data_in *i, long *day)
704 {
705   if (!parse_int (i, day, SIZE_MAX))
706     return false;
707   if (*day >= 1 && *day <= 31)
708     return true;
709
710   data_warning (i, _("Day (%ld) must be between 1 and 31."), *day);
711   return false;
712 }
713
714 /* Parses an integer from the beginning of I.
715    Adds SECONDS_PER_UNIT times the absolute value of the integer
716    to *TIME.
717    If *TIME_SIGN is SIGN_NO_TIME, allows a sign to precede the
718    time and sets *TIME_SIGN.  Otherwise, does not allow a sign.
719    Returns true if successful, false if no integer was present. */
720 static bool
721 parse_time_units (struct data_in *i, double seconds_per_unit,
722                   enum time_sign *time_sign, double *time)
723
724 {
725   long units;
726
727   if (*time_sign == SIGN_NO_TIME)
728     {
729       if (ss_match_char (&i->input, '-'))
730         *time_sign = SIGN_NEGATIVE;
731       else
732         {
733           ss_match_char (&i->input, '+');
734           *time_sign = SIGN_POSITIVE;
735         }
736     }
737   if (!parse_int (i, &units, SIZE_MAX))
738     return false;
739   if (units < 0)
740     {
741       data_warning (i, _("Syntax error in date field."));
742       return false;
743     }
744   *time += units * seconds_per_unit;
745   return true;
746 }
747
748 /* Parses a data delimiter from the beginning of I.
749    Returns true if successful, false if no delimiter was
750    present. */
751 static bool
752 parse_date_delimiter (struct data_in *i)
753 {
754   if (ss_ltrim (&i->input, ss_cstr ("-/.," CC_SPACES)))
755     return true;
756
757   data_warning (i, _("Delimiter expected between fields in date."));
758   return false;
759 }
760
761 /* Parses spaces at the beginning of I. */
762 static void
763 parse_spaces (struct data_in *i)
764 {
765   ss_ltrim (&i->input, ss_cstr (CC_SPACES));
766 }
767
768 static struct substring
769 parse_name_token (struct data_in *i)
770 {
771   struct substring token;
772   ss_get_chars (&i->input, ss_span (i->input, ss_cstr (CC_LETTERS)), &token);
773   return token;
774 }
775
776 /* Reads a name from I and sets *OUTPUT to the value associated
777    with that name.  If ALLOW_SUFFIXES is true, then names that
778    begin with one of the names are accepted; otherwise, only
779    exact matches (except for case) are allowed.
780    Returns true if successful, false otherwise. */
781 static bool
782 match_name (struct substring token, const char *const *names, long *output)
783 {
784   int i;
785
786   for (i = 1; *names != NULL; i++)
787     if (ss_equals_case (ss_cstr (*names++), token))
788       {
789         *output = i;
790         return true;
791       }
792
793   return false;
794 }
795
796 /* Parses a month name or number from the beginning of I,
797    storing the month (in range 1...12) into *MONTH.
798    Returns true if successful, false if no month was present. */
799 static bool
800 parse_month (struct data_in *i, long *month)
801 {
802   if (c_isdigit (ss_first (i->input)))
803     {
804       if (!parse_int (i, month, SIZE_MAX))
805         return false;
806       if (*month >= 1 && *month <= 12)
807         return true;
808     }
809   else
810     {
811       static const char *const english_names[] =
812         {
813           "jan", "feb", "mar", "apr", "may", "jun",
814           "jul", "aug", "sep", "oct", "nov", "dec",
815           NULL,
816         };
817
818       static const char *const roman_names[] =
819         {
820           "i", "ii", "iii", "iv", "v", "vi",
821           "vii", "viii", "ix", "x", "xi", "xii",
822           NULL,
823         };
824
825       struct substring token = parse_name_token (i);
826       if (match_name (ss_head (token, 3), english_names, month)
827           || match_name (ss_head (token, 4), roman_names, month))
828         return true;
829     }
830
831   data_warning (i, _("Unrecognized month format.  Months may be specified "
832                      "as Arabic or Roman numerals or as at least 3 letters "
833                      "of their English names."));
834   return false;
835 }
836
837 /* Parses a year of at most MAX_DIGITS from the beginning of I,
838    storing a "4-digit" year into *YEAR. */
839 static bool
840 parse_year (struct data_in *i, long *year, size_t max_digits)
841 {
842   if (!parse_int (i, year, max_digits))
843     return false;
844
845   if (*year >= 0 && *year <= 99)
846     {
847       int epoch = settings_get_epoch ();
848       int epoch_century = ROUND_DOWN (epoch, 100);
849       int epoch_offset = epoch - epoch_century;
850       if (*year >= epoch_offset)
851         *year += epoch_century;
852       else
853         *year += epoch_century + 100;
854     }
855   if (*year >= 1582 || *year <= 19999)
856     return true;
857
858   data_warning (i, _("Year (%ld) must be between 1582 and 19999."), *year);
859   return false;
860 }
861
862 /* Returns true if input in I has been exhausted,
863    false otherwise. */
864 static bool
865 parse_trailer (struct data_in *i)
866 {
867   if (ss_is_empty (i->input))
868     return true;
869
870   data_warning (i, _("Trailing garbage \"%.*s\" following date."),
871               (int) ss_length (i->input), ss_data (i->input));
872   return false;
873 }
874
875 /* Parses a 3-digit Julian day-of-year value from I into *YDAY.
876    Returns true if successful, false on failure. */
877 static bool
878 parse_yday (struct data_in *i, long *yday)
879 {
880   struct substring num_s;
881   long num;
882
883   ss_get_chars (&i->input, 3, &num_s);
884   if (ss_span (num_s, ss_cstr (CC_DIGITS)) != 3)
885     {
886       data_warning (i, _("Julian day must have exactly three digits."));
887       return false;
888     }
889   else if (!ss_get_long (&num_s, &num) || num < 1 || num > 366)
890     {
891       data_warning (i, _("Julian day (%ld) must be between 1 and 366."), num);
892       return false;
893     }
894
895   *yday = num;
896   return true;
897 }
898
899 /* Parses a quarter-of-year integer between 1 and 4 from I.
900    Stores the corresponding month into *MONTH.
901    Returns true if successful, false if no quarter was present. */
902 static bool
903 parse_quarter (struct data_in *i, long int *month)
904 {
905   long quarter;
906
907   if (!parse_int (i, &quarter, SIZE_MAX))
908     return false;
909   if (quarter >= 1 && quarter <= 4)
910     {
911       *month = (quarter - 1) * 3 + 1;
912       return true;
913     }
914
915   data_warning (i, _("Quarter (%ld) must be between 1 and 4."), quarter);
916   return false;
917 }
918
919 /* Parses a week-of-year integer between 1 and 53 from I,
920    Stores the corresponding year-of-day into *YDAY.
921    Returns true if successful, false if no week was present. */
922 static bool
923 parse_week (struct data_in *i, long int *yday)
924 {
925   long week;
926
927   if (!parse_int (i, &week, SIZE_MAX))
928     return false;
929   if (week >= 1 && week <= 53)
930     {
931       *yday = (week - 1) * 7 + 1;
932       return true;
933     }
934
935   data_warning (i, _("Week (%ld) must be between 1 and 53."), week);
936   return false;
937 }
938
939 /* Parses a time delimiter from the beginning of I.
940    Returns true if successful, false if no delimiter was
941    present. */
942 static bool
943 parse_time_delimiter (struct data_in *i)
944 {
945   if (ss_ltrim (&i->input, ss_cstr (":" CC_SPACES)) > 0)
946     return true;
947
948   data_warning (i, _("Delimiter expected between fields in time."));
949   return false;
950 }
951
952 /* Parses minutes and optional seconds from the beginning of I.
953    The time is converted into seconds, which are added to
954    *TIME.
955    Returns true if successful, false if an error was found. */
956 static bool
957 parse_minute_second (struct data_in *i, double *time)
958 {
959   long minute;
960   char buf[64];
961   char *cp;
962
963   /* Parse minutes. */
964   if (!parse_int (i, &minute, SIZE_MAX))
965     return false;
966   if (minute < 0 || minute > 59)
967     {
968       data_warning (i, _("Minute (%ld) must be between 0 and 59."), minute);
969       return false;
970     }
971   *time += 60. * minute;
972
973   /* Check for seconds. */
974   if (ss_ltrim (&i->input, ss_cstr (":" CC_SPACES)) == 0
975       || !c_isdigit (ss_first (i->input)))
976    return true;
977
978   /* Parse seconds. */
979   cp = buf;
980   while (c_isdigit (ss_first (i->input)))
981     *cp++ = ss_get_char (&i->input);
982   if (ss_match_char (&i->input, settings_get_decimal_char (FMT_F)))
983     *cp++ = '.';
984   while (c_isdigit (ss_first (i->input)))
985     *cp++ = ss_get_char (&i->input);
986   *cp = '\0';
987
988   *time += strtod (buf, NULL);
989
990   return true;
991 }
992
993 /* Parses a weekday name from the beginning of I,
994    storing a value of 1=Sunday...7=Saturday into *WEEKDAY.
995    Returns true if successful, false if an error was found. */
996 static bool
997 parse_weekday (struct data_in *i, long *weekday)
998 {
999   static const char *const weekday_names[] =
1000     {
1001       "su", "mo", "tu", "we", "th", "fr", "sa",
1002       NULL,
1003     };
1004
1005   struct substring token = parse_name_token (i);
1006   bool ok = match_name (ss_head (token, 2), weekday_names, weekday);
1007   if (!ok)
1008     data_warning (i, _("Unrecognized weekday name.  At least the first two "
1009                        "letters of an English weekday name must be "
1010                        "specified."));
1011   return ok;
1012 }
1013 \f
1014 /* Date & time formats. */
1015
1016 /* Helper function for passing to
1017    calendar_gregorian_to_offset. */
1018 static void
1019 calendar_error (void *i_, const char *format, ...)
1020 {
1021   struct data_in *i = i_;
1022   va_list args;
1023
1024   va_start (args, format);
1025   vdata_warning (i, format, args);
1026   va_end (args);
1027 }
1028
1029 /* Parses WKDAY format. */
1030 static bool
1031 parse_WKDAY (struct data_in *i)
1032 {
1033   long weekday;
1034
1035   if (trim_spaces_and_check_missing (i))
1036     return true;
1037
1038   if (!parse_weekday (i, &weekday)
1039       || !parse_trailer (i))
1040     return false;
1041
1042   i->output->f = weekday;
1043   return true;
1044 }
1045
1046 /* Parses MONTH format. */
1047 static bool
1048 parse_MONTH (struct data_in *i)
1049 {
1050   long month;
1051
1052   if (trim_spaces_and_check_missing (i))
1053     return true;
1054
1055   if (!parse_month (i, &month)
1056       || !parse_trailer (i))
1057     return false;
1058
1059   i->output->f = month;
1060   return true;
1061 }
1062
1063 /* Parses DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, KWYR,
1064    DATETIME, TIME and DTIME formats. */
1065 static bool
1066 parse_date (struct data_in *i)
1067 {
1068   long int year = INT_MIN;
1069   long int month = 1;
1070   long int day = 1;
1071   long int yday = 1;
1072   double time = 0, date = 0;
1073   enum time_sign time_sign = SIGN_NO_TIME;
1074
1075   const char *template = fmt_date_template (i->format);
1076   size_t template_width = strlen (template);
1077
1078   if (trim_spaces_and_check_missing (i))
1079     return true;
1080
1081   while (*template != '\0')
1082     {
1083       unsigned char ch = *template;
1084       int count = 1;
1085       bool ok;
1086
1087       while (template[count] == ch)
1088         count++;
1089       template += count;
1090
1091       ok = true;
1092       switch (ch)
1093         {
1094         case 'd':
1095           ok = count < 3 ? parse_day (i, &day) : parse_yday (i, &yday);
1096           break;
1097         case 'm':
1098           ok = parse_month (i, &month);
1099           break;
1100         case 'y':
1101           {
1102             size_t max_digits;
1103             if (!c_isalpha (*template))
1104               max_digits = SIZE_MAX;
1105             else
1106               {
1107                 if (ss_length (i->input) >= template_width + 2)
1108                   max_digits = 4;
1109                 else
1110                   max_digits = 2;
1111               }
1112             ok = parse_year (i, &year, max_digits);
1113           }
1114           break;
1115         case 'q':
1116           ok = parse_quarter (i, &month);
1117           break;
1118         case 'w':
1119           ok = parse_week (i, &yday);
1120           break;
1121         case 'D':
1122           ok = parse_time_units (i, 60. * 60. * 24., &time_sign, &time);
1123           break;
1124         case 'H':
1125           ok = parse_time_units (i, 60. * 60., &time_sign, &time);
1126           break;
1127         case 'M':
1128           ok = parse_minute_second (i, &time);
1129           break;
1130         case '-':
1131         case '/':
1132         case '.':
1133         case 'X':
1134           ok = parse_date_delimiter (i);
1135           break;
1136         case ':':
1137           ok = parse_time_delimiter (i);
1138         case ' ':
1139           parse_spaces (i);
1140           break;
1141         default:
1142           assert (count == 1);
1143           if (!ss_match_char (&i->input, c_toupper (ch))
1144               && !ss_match_char (&i->input, c_tolower (ch)))
1145             {
1146               data_warning (i, _("`%c' expected in date field."), ch);
1147               return false;
1148             }
1149           break;
1150         }
1151       if (!ok)
1152         return false;
1153     }
1154   if (!parse_trailer (i))
1155     return false;
1156
1157   if (year != INT_MIN)
1158     {
1159       double ofs = calendar_gregorian_to_offset (year, month, day,
1160                                                  calendar_error, i);
1161       if (ofs == SYSMIS)
1162         return false;
1163       date = (yday - 1 + ofs) * 60. * 60. * 24.;
1164     }
1165   else
1166     date = 0.;
1167   i->output->f = date + (time_sign == SIGN_NEGATIVE ? -time : time);
1168
1169   return true;
1170 }
1171 \f
1172 /* Utility functions. */
1173
1174 /* Outputs FORMAT with the given ARGS as a warning for input
1175    I. */
1176 static void
1177 vdata_warning (const struct data_in *i, const char *format, va_list args)
1178 {
1179   struct msg m;
1180   struct string text;
1181
1182   ds_init_empty (&text);
1183   ds_put_char (&text, '(');
1184   if (i->first_column != 0)
1185     {
1186       if (i->first_column == i->last_column - 1)
1187         ds_put_format (&text, _("column %d"), i->first_column);
1188       else
1189         ds_put_format (&text, _("columns %d-%d"),
1190                        i->first_column, i->last_column - 1);
1191       ds_put_cstr (&text, ", ");
1192     }
1193   ds_put_format (&text, _("%s field) "), fmt_name (i->format));
1194   ds_put_vformat (&text, format, args);
1195
1196   m.category = MSG_DATA;
1197   m.severity = MSG_WARNING;
1198   m.text = ds_cstr (&text);
1199
1200   msg_emit (&m);
1201 }
1202
1203 /* Outputs FORMAT with the given ARGS as a warning for input
1204    I. */
1205 static void
1206 data_warning (const struct data_in *i, const char *format, ...)
1207 {
1208   va_list args;
1209
1210   va_start (args, format);
1211   vdata_warning (i, format, args);
1212   va_end (args);
1213 }
1214
1215 /* Apply implied decimal places to output. */
1216 static void
1217 apply_implied_decimals (struct data_in *i)
1218 {
1219   if (i->implied_decimals > 0)
1220     i->output->f /= pow (10., i->implied_decimals);
1221 }
1222
1223 /* Sets the default result for I.
1224    For a numeric format, this is the value set on SET BLANKS
1225    (typically system-missing); for a string format, it is all
1226    spaces. */
1227 static void
1228 default_result (struct data_in *i)
1229 {
1230   if (fmt_is_string (i->format))
1231     memset (value_str_rw (i->output, i->width), ' ', i->width);
1232   else
1233     i->output->f = settings_get_blanks ();
1234 }
1235
1236 /* Trims leading and trailing spaces from I.
1237    If the result is empty, or a single period character, then
1238    sets the default result and returns true; otherwise, returns
1239    false. */
1240 static bool
1241 trim_spaces_and_check_missing (struct data_in *i)
1242 {
1243   ss_trim (&i->input, ss_cstr (" "));
1244   if (ss_is_empty (i->input) || ss_equals (i->input, ss_cstr (".")))
1245     {
1246       default_result (i);
1247       return true;
1248     }
1249   return false;
1250 }
1251
1252 /* Returns the integer value of hex digit C. */
1253 static int
1254 hexit_value (int c)
1255 {
1256   const char s[] = "0123456789abcdef";
1257   const char *cp = strchr (s, c_tolower ((unsigned char) c));
1258
1259   assert (cp != NULL);
1260   return cp - s;
1261 }