Completely rewrite src/data/format.[ch], to achieve better
[pspp-builds.git] / src / data / data-in.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include "data-in.h"
22 #include <libpspp/assertion.h>
23 #include <math.h>
24 #include <ctype.h>
25 #include <stdarg.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdbool.h>
30 #include <libpspp/message.h>
31 #include "calendar.h"
32 #include <libpspp/compiler.h>
33 #include "identifier.h"
34 #include <libpspp/magic.h>
35 #include <libpspp/misc.h>
36 #include "settings.h"
37 #include <libpspp/str.h>
38 #include "variable.h"
39
40 #include "gettext.h"
41 #define _(msgid) gettext (msgid)
42 \f
43 /* Specialized error routine. */
44
45 static void dls_error (const struct data_in *, const char *format, ...)
46      PRINTF_FORMAT (2, 3);
47
48 static void
49 vdls_error (const struct data_in *i, const char *format, va_list args)
50 {
51   struct msg m;
52   struct string text;
53   char format_string[FMT_STRING_LEN_MAX + 1];
54
55   if (i->flags & DI_IGNORE_ERROR)
56     return;
57
58   ds_init_empty (&text);
59   if (i->f1 == i->f2)
60     ds_put_format (&text, _("(column %d"), i->f1);
61   else
62     ds_put_format (&text, _("(columns %d-%d"), i->f1, i->f2);
63   ds_put_format (&text, _(", field type %s) "),
64                  fmt_to_string (&i->format, format_string));
65   ds_put_vformat (&text, format, args);
66
67   m.category = MSG_DATA;
68   m.severity = MSG_ERROR;
69   m.text = ds_cstr (&text);
70
71   msg_emit (&m);
72 }
73
74 static void
75 dls_error (const struct data_in *i, const char *format, ...) 
76 {
77   va_list args;
78
79   va_start (args, format);
80   vdls_error (i, format, args);
81   va_end (args);
82 }
83 \f
84 /* Parsing utility functions. */
85
86 /* Excludes leading and trailing whitespace from I by adjusting
87    pointers. */
88 static void
89 trim_whitespace (struct data_in *i)
90 {
91   while (i->s < i->e && isspace ((unsigned char) i->s[0])) 
92     i->s++;
93
94   while (i->s < i->e && isspace ((unsigned char) i->e[-1]))
95     i->e--;
96 }
97
98 /* Returns true if we're not at the end of the string being
99    parsed. */
100 static inline bool
101 have_char (struct data_in *i)
102 {
103   return i->s < i->e;
104 }
105
106 /* If implied decimal places are enabled, apply them to
107    I->v->f. */
108 static void
109 apply_implied_decimals (struct data_in *i) 
110 {
111   if ((i->flags & DI_IMPLIED_DECIMALS) && i->format.d > 0)
112     i->v->f /= pow (10., i->format.d);
113 }
114 \f
115 /* Format parsers. */ 
116
117 static bool parse_int (struct data_in *i, long *result);
118
119 /* This function is based on strtod() from the GNU C library. */
120 static bool
121 parse_numeric (struct data_in *i)
122 {
123   int sign;                     /* +1 or -1. */
124   double num;                   /* The number so far.  */
125
126   bool got_dot;                 /* Found a decimal point.  */
127   size_t digit_cnt;             /* Count of digits.  */
128
129   int decimal;                  /* Decimal point character. */
130   int grouping;                 /* Grouping character. */
131
132   long int exponent;            /* Number's exponent. */
133   int type;                     /* Usually same as i->format.type. */
134
135   trim_whitespace (i);
136
137   type = i->format.type;
138   if (type == FMT_DOLLAR && have_char (i) && *i->s == '$')
139     {
140       i->s++;
141       type = FMT_COMMA;
142     }
143
144   /* Get the sign.  */
145   if (have_char (i))
146     {
147       sign = *i->s == '-' ? -1 : 1;
148       if (*i->s == '-' || *i->s == '+')
149         i->s++;
150     }
151   else
152     sign = 1;
153
154   decimal = fmt_decimal_char (type);
155   grouping = fmt_grouping_char (type);
156
157   i->v->f = SYSMIS;
158   num = 0.0;
159   got_dot = false;
160   digit_cnt = 0;
161   exponent = 0;
162   for (; have_char (i); i->s++)
163     {
164       if (isdigit ((unsigned char) *i->s))
165         {
166           digit_cnt++;
167
168           /* Make sure that multiplication by 10 will not overflow.  */
169           if (num > DBL_MAX * 0.1)
170             /* The value of the digit doesn't matter, since we have already
171                gotten as many digits as can be represented in a `double'.
172                This doesn't necessarily mean the result will overflow.
173                The exponent may reduce it to within range.
174
175                We just need to record that there was another
176                digit so that we can multiply by 10 later.  */
177             ++exponent;
178           else
179             num = (num * 10.0) + (*i->s - '0');
180
181           /* Keep track of the number of digits after the decimal point.
182              If we just divided by 10 here, we would lose precision.  */
183           if (got_dot)
184             --exponent;
185         }
186       else if (!got_dot && *i->s == decimal)
187         /* Record that we have found the decimal point.  */
188         got_dot = true;
189       else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
190         /* Any other character terminates the number.  */
191         break;
192     }
193
194   if (!digit_cnt)
195     {
196       if (got_dot)
197         {
198           i->v->f = SYSMIS;
199           return true;
200         }
201       dls_error (i, _("Field does not form a valid floating-point constant."));
202       i->v->f = SYSMIS;
203       return false;
204     }
205   
206   if (have_char (i) && strchr ("eEdD-+", *i->s))
207     {
208       /* Get the exponent specified after the `e' or `E'.  */
209       long exp;
210
211       if (isalpha ((unsigned char) *i->s))
212         i->s++;
213       if (!parse_int (i, &exp))
214         {
215           i->v->f = SYSMIS;
216           return false;
217         }
218
219       exponent += exp;
220     }
221   else if (!got_dot && (i->flags & DI_IMPLIED_DECIMALS))
222     exponent -= i->format.d;
223
224   if (type == FMT_PCT && have_char (i) && *i->s == '%')
225     i->s++;
226   if (i->s < i->e)
227     {
228       dls_error (i, _("Field contents followed by garbage."));
229       i->v->f = SYSMIS;
230       return false;
231     }
232
233   if (num == 0.0)
234     {
235       i->v->f = 0.0;
236       return true;
237     }
238
239   /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
240      and underflow.  */
241   if (exponent < 0)
242     {
243       if (-exponent + digit_cnt > -(DBL_MIN_10_EXP) + 5
244           || num < DBL_MIN * pow (10.0, (double) -exponent)) 
245         {
246           dls_error (i, _("Underflow in floating-point constant."));
247           i->v->f = 0.0;
248           return false;
249         }
250
251       num *= pow (10.0, (double) exponent);
252     }
253   else if (exponent > 0)
254     {
255       if (num > DBL_MAX * pow (10.0, (double) -exponent))
256         {
257           dls_error (i, _("Overflow in floating-point constant."));
258           i->v->f = SYSMIS;
259           return false;
260         }
261       
262       num *= pow (10.0, (double) exponent);
263     }
264
265   i->v->f = sign > 0 ? num : -num;
266   return true;
267 }
268
269 /* Returns the integer value of hex digit C. */
270 static inline int
271 hexit_value (int c)
272 {
273   const char s[] = "0123456789abcdef";
274   const char *cp = strchr (s, tolower ((unsigned char) c));
275
276   assert (cp != NULL);
277   return cp - s;
278 }
279
280 static inline bool
281 parse_N (struct data_in *i)
282 {
283   const char *cp;
284
285   i->v->f = 0;
286   for (cp = i->s; cp < i->e; cp++)
287     {
288       if (!isdigit ((unsigned char) *cp))
289         {
290           dls_error (i, _("All characters in field must be digits."));
291           return false;
292         }
293
294       i->v->f = i->v->f * 10.0 + (*cp - '0');
295     }
296
297   apply_implied_decimals (i);
298   return true;
299 }
300
301 static inline bool
302 parse_PIBHEX (struct data_in *i)
303 {
304   double n;
305   const char *cp;
306
307   trim_whitespace (i);
308
309   n = 0.0;
310   for (cp = i->s; cp < i->e; cp++)
311     {
312       if (!isxdigit ((unsigned char) *cp))
313         {
314           dls_error (i, _("Unrecognized character in field."));
315           return false;
316         }
317
318       n = n * 16.0 + hexit_value (*cp);
319     }
320   
321   i->v->f = n;
322   return true;
323 }
324
325 static inline bool
326 parse_RBHEX (struct data_in *i)
327 {
328   /* Validate input. */
329   trim_whitespace (i);
330   if ((i->e - i->s) % 2)
331     {
332       dls_error (i, _("Field must have even length."));
333       return false;
334     }
335   
336   {
337     const char *cp;
338     
339     for (cp = i->s; cp < i->e; cp++)
340       if (!isxdigit ((unsigned char) *cp))
341         {
342           dls_error (i, _("Field must contain only hex digits."));
343           return false;
344         }
345   }
346   
347   /* Parse input. */
348   {
349     union
350       {
351         double d;
352         unsigned char c[sizeof (double)];
353       }
354     u;
355
356     int j;
357
358     memset (u.c, 0, sizeof u.c);
359     for (j = 0; j < min ((i->e - i->s) / 2, sizeof u.d); j++)
360       u.c[j] = 16 * hexit_value (i->s[j * 2]) + hexit_value (i->s[j * 2 + 1]);
361
362     i->v->f = u.d;
363   }
364   
365   return true;
366 }
367
368 static inline bool
369 parse_Z (struct data_in *i)
370 {
371   char buf[64];
372   bool got_dot = false;
373
374   /* Warn user that we suck. */
375   {
376     static bool warned;
377
378     if (!warned)
379       {
380         msg (MW, 
381              _("Quality of zoned decimal (Z) input format code is "
382                "suspect.  Check your results three times. Report bugs "
383                 "to %s."),PACKAGE_BUGREPORT);
384         warned = true;
385       }
386   }
387
388   /* Validate input. */
389   trim_whitespace (i);
390
391   if (i->e - i->s < 2)
392     {
393       dls_error (i, _("Zoned decimal field contains fewer than 2 "
394                       "characters."));
395       return false;
396     }
397
398   /* Copy sign into buf[0]. */
399   if ((i->e[-1] & 0xc0) != 0xc0)
400     {
401       dls_error (i, _("Bad sign byte in zoned decimal number."));
402       return false;
403     }
404   buf[0] = (i->e[-1] ^ (i->e[-1] >> 1)) & 0x10 ? '-' : '+';
405
406   /* Copy digits into buf[1 ... len - 1] and terminate string. */
407   {
408     const char *sp;
409     char *dp;
410
411     for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
412       if (*sp == '.') 
413         {
414           *dp = '.';
415           got_dot = true;
416         }
417       else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
418         *dp = (*sp & 0xf) + '0';
419       else
420         {
421           dls_error (i, _("Format error in zoned decimal number."));
422           return false;
423         }
424
425     *dp = '\0';
426   }
427
428   /* Parse as number. */
429   {
430     char *tail;
431     
432     i->v->f = strtod (buf, &tail);
433     if (tail != i->e)
434       {
435         dls_error (i, _("Error in syntax of zoned decimal number."));
436         return false;
437       }
438   }
439
440   if (!got_dot)
441     apply_implied_decimals (i);
442
443   return true;
444 }
445
446 static inline bool
447 parse_IB (struct data_in *i)
448 {
449 #ifndef WORDS_BIGENDIAN
450   char buf[64];
451 #endif
452   const unsigned char *p;
453
454   unsigned char xor;
455
456   /* We want the data to be in big-endian format.  If this is a
457      little-endian machine, reverse the byte order. */
458 #ifdef WORDS_BIGENDIAN
459   p = (const unsigned char *) i->s;
460 #else
461   memcpy (buf, i->s, i->e - i->s);
462   buf_reverse (buf, i->e - i->s);
463   p = (const unsigned char *) buf;
464 #endif
465
466   /* If the value is negative, we need to logical-NOT each value
467      before adding it. */
468   if (p[0] & 0x80)
469     xor = 0xff;
470   else
471     xor = 0x00;
472   
473   {
474     int j;
475
476     i->v->f = 0.0;
477     for (j = 0; j < i->e - i->s; j++)
478       i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
479   }
480
481   /* If the value is negative, add 1 and set the sign, to complete a
482      two's-complement negation. */
483   if (p[0] & 0x80)
484     i->v->f = -(i->v->f + 1.0);
485
486   apply_implied_decimals (i);
487
488   return true;
489 }
490
491 static inline bool
492 parse_PIB (struct data_in *i)
493 {
494   int j;
495
496   i->v->f = 0.0;
497 #if WORDS_BIGENDIAN
498   for (j = 0; j < i->e - i->s; j++)
499     i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
500 #else
501   for (j = i->e - i->s - 1; j >= 0; j--)
502     i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
503 #endif
504
505   apply_implied_decimals (i);
506
507   return true;
508 }
509
510 static inline bool
511 parse_P (struct data_in *i)
512 {
513   const char *cp;
514
515   i->v->f = 0.0;
516   for (cp = i->s; cp < i->e - 1; cp++)
517     {
518       i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
519       i->v->f = i->v->f * 10 + (*cp & 15);
520     }
521   i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
522   if ((*cp ^ (*cp >> 1)) & 0x10)
523       i->v->f = -i->v->f;
524
525   apply_implied_decimals (i);
526
527   return true;
528 }
529
530 static inline bool
531 parse_PK (struct data_in *i)
532 {
533   const char *cp;
534
535   i->v->f = 0.0;
536   for (cp = i->s; cp < i->e; cp++)
537     {
538       i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
539       i->v->f = i->v->f * 10 + (*cp & 15);
540     }
541
542   apply_implied_decimals (i);
543
544   return true;
545 }
546
547 static inline bool
548 parse_RB (struct data_in *i)
549 {
550   union
551     {
552       double d;
553       unsigned char c[sizeof (double)];
554     }
555   u;
556
557   memset (u.c, 0, sizeof u.c);
558   memcpy (u.c, i->s, min (sizeof u.c, (size_t) (i->e - i->s)));
559   i->v->f = u.d;
560
561   return true;
562 }
563
564
565 static inline bool
566 parse_A (struct data_in *i)
567 {
568   buf_copy_rpad (i->v->s, i->format.w, i->s, i->e - i->s);
569   
570   return true;
571 }
572
573 static inline bool
574 parse_AHEX (struct data_in *i)
575 {
576   /* Validate input. */
577   trim_whitespace (i);
578   if ((i->e - i->s) % 2)
579     {
580       dls_error (i, _("Field must have even length."));
581       return false;
582     }
583
584   {
585     const char *cp;
586     
587     for (cp = i->s; cp < i->e; cp++)
588       if (!isxdigit ((unsigned char) *cp))
589         {
590           dls_error (i, _("Field must contain only hex digits."));
591           return false;
592         }
593   }
594   
595   {
596     int j;
597     
598     /* Parse input. */
599     for (j = 0; j < min (i->e - i->s, i->format.w); j += 2)
600       i->v->s[j / 2] = hexit_value (i->s[j]) * 16 + hexit_value (i->s[j + 1]);
601     memset (i->v->s + (i->e - i->s) / 2, ' ', (i->format.w - (i->e - i->s)) / 2);
602   }
603   
604   return true;
605 }
606 \f
607 /* Date & time format components. */
608
609 /* Advances *CP past any whitespace characters. */
610 static inline void
611 skip_whitespace (struct data_in *i)
612 {
613   while (isspace ((unsigned char) *i->s))
614     i->s++;
615 }
616
617 static inline bool
618 parse_leader (struct data_in *i)
619 {
620   skip_whitespace (i);
621   return true;
622 }
623
624 static inline bool
625 force_have_char (struct data_in *i)
626 {
627   if (have_char (i))
628     return true;
629
630   dls_error (i, _("Unexpected end of field."));
631   return false;
632 }
633
634 static bool
635 parse_int (struct data_in *i, long *result)
636 {
637   bool negative = false;
638   
639   if (!force_have_char (i))
640     return false;
641
642   if (*i->s == '+')
643     {
644       i->s++;
645       force_have_char (i);
646     }
647   else if (*i->s == '-')
648     {
649       negative = true;
650       i->s++;
651       force_have_char (i);
652     }
653   
654   if (!isdigit ((unsigned char) *i->s))
655     {
656       dls_error (i, _("Digit expected in field."));
657       return false;
658     }
659
660   *result = 0;
661   for (;;)
662     {
663       *result = *result * 10 + (*i->s++ - '0');
664       if (!have_char (i) || !isdigit ((unsigned char) *i->s))
665         break;
666     }
667
668   if (negative)
669     *result = -*result;
670   return true;
671 }
672
673 static bool
674 parse_day (struct data_in *i, long *day)
675 {
676   if (!parse_int (i, day))
677     return false;
678   if (*day >= 1 && *day <= 31)
679     return true;
680
681   dls_error (i, _("Day (%ld) must be between 1 and 31."), *day);
682   return false;
683 }
684
685 static bool
686 parse_day_count (struct data_in *i, long *day_count)
687 {
688   return parse_int (i, day_count);
689 }
690
691 static bool
692 parse_date_delimiter (struct data_in *i)
693 {
694   bool delim = false;
695
696   while (have_char (i)
697          && (*i->s == '-' || *i->s == '/' || isspace ((unsigned char) *i->s)
698              || *i->s == '.' || *i->s == ','))
699     {
700       delim = true;
701       i->s++;
702     }
703   if (delim)
704     return true;
705
706   dls_error (i, _("Delimiter expected between fields in date."));
707   return false;
708 }
709
710 /* Association between a name and a value. */
711 struct enum_name
712   {
713     const char *name;           /* Name. */
714     bool can_abbreviate;        /* True if name may be abbreviated. */
715     int value;                  /* Value associated with name. */
716   };
717
718 /* Reads a name from I and sets *OUTPUT to the value associated
719    with that name.  Returns true if successful, false otherwise. */
720 static bool
721 parse_enum (struct data_in *i, const char *what,
722             const struct enum_name *enum_names,
723             long *output) 
724 {
725   const char *name;
726   size_t length;
727   const struct enum_name *ep;
728
729   /* Consume alphabetic characters. */
730   name = i->s;
731   length = 0;
732   while (have_char (i) && isalpha ((unsigned char) *i->s)) 
733     {
734       length++;
735       i->s++; 
736     }
737   if (length == 0) 
738     {
739       dls_error (i, _("Parse error at `%c' expecting %s."), *i->s, what);
740       return false;
741     }
742
743   for (ep = enum_names; ep->name != NULL; ep++)
744     if ((ep->can_abbreviate
745          && lex_id_match_len (ep->name, strlen (ep->name), name, length))
746         || (!ep->can_abbreviate && length == strlen (ep->name)
747             && !buf_compare_case (name, ep->name, length)))
748       {
749         *output = ep->value;
750         return true;
751       }
752
753   dls_error (i, _("Unknown %s `%.*s'."), what, (int) length, name);
754   return false;
755 }
756
757 static bool
758 parse_month (struct data_in *i, long *month)
759 {
760   static const struct enum_name month_names[] = 
761     {
762       {"january", true, 1},
763       {"february", true, 2},
764       {"march", true, 3},
765       {"april", true, 4},
766       {"may", true, 5},
767       {"june", true, 6},
768       {"july", true, 7},
769       {"august", true, 8},
770       {"september", true, 9},
771       {"october", true, 10},
772       {"november", true, 11},
773       {"december", true, 12},
774
775       {"i", false, 1},
776       {"ii", false, 2},
777       {"iii", false, 3},
778       {"iv", false, 4},
779       {"iiii", false, 4},
780       {"v", false, 5},
781       {"vi", false, 6},
782       {"vii", false, 7},
783       {"viii", false, 8},
784       {"ix", false, 9},
785       {"viiii", false, 9},
786       {"x", false, 10},
787       {"xi", false, 11},
788       {"xii", false, 12},
789
790       {NULL, false, 0},
791     };
792
793   if (!force_have_char (i))
794     return false;
795   
796   if (isdigit ((unsigned char) *i->s))
797     {
798       if (!parse_int (i, month))
799         return false;
800       if (*month >= 1 && *month <= 12)
801         return true;
802       
803       dls_error (i, _("Month (%ld) must be between 1 and 12."), *month);
804       return false;
805     }
806   else 
807     return parse_enum (i, _("month"), month_names, month);
808 }
809
810 static bool
811 parse_year (struct data_in *i, long *year)
812 {
813   if (!parse_int (i, year))
814     return false;
815   
816   if (*year >= 0 && *year <= 199)
817     *year += 1900;
818   if (*year >= 1582 || *year <= 19999)
819     return true;
820
821   dls_error (i, _("Year (%ld) must be between 1582 and 19999."), *year);
822   return false;
823 }
824
825 static bool
826 parse_trailer (struct data_in *i)
827 {
828   skip_whitespace (i);
829   if (!have_char (i))
830     return true;
831   
832   dls_error (i, _("Trailing garbage \"%.*s\" following date."),
833              (int) (i->e - i->s), i->s);
834   return false;
835 }
836
837 static bool
838 parse_julian (struct data_in *i, long *julian)
839 {
840   if (!parse_int (i, julian))
841     return false;
842    
843   {
844     int day = *julian % 1000;
845
846     if (day < 1 || day > 366)
847       {
848         dls_error (i, _("Julian day (%d) must be between 1 and 366."), day);
849         return false;
850       }
851   }
852   
853   {
854     int year = *julian / 1000;
855
856     if (year >= 0 && year <= 199)
857       *julian += 1900000L;
858     else if (year < 1582 || year > 19999)
859       {
860         dls_error (i, _("Year (%d) must be between 1582 and 19999."), year);
861         return false;
862       }
863   }
864
865   return true;
866 }
867
868 static bool
869 parse_quarter (struct data_in *i, long *quarter)
870 {
871   if (!parse_int (i, quarter))
872     return false;
873   if (*quarter >= 1 && *quarter <= 4)
874     return true;
875
876   dls_error (i, _("Quarter (%ld) must be between 1 and 4."), *quarter);
877   return false;
878 }
879
880 static bool
881 parse_q_delimiter (struct data_in *i)
882 {
883   skip_whitespace (i);
884   if (!have_char (i) || tolower ((unsigned char) *i->s) != 'q')
885     {
886       dls_error (i, _("`Q' expected between quarter and year."));
887       return false;
888     }
889   i->s++;
890   skip_whitespace (i);
891   return true;
892 }
893
894 static bool
895 parse_week (struct data_in *i, long *week)
896 {
897   if (!parse_int (i, week))
898     return false;
899   if (*week >= 1 && *week <= 53)
900     return true;
901
902   dls_error (i, _("Week (%ld) must be between 1 and 53."), *week);
903   return false;
904 }
905
906 static bool
907 parse_wk_delimiter (struct data_in *i)
908 {
909   skip_whitespace (i);
910   if (i->s + 1 >= i->e
911       || tolower ((unsigned char) i->s[0]) != 'w'
912       || tolower ((unsigned char) i->s[1]) != 'k')
913     {
914       dls_error (i, _("`WK' expected between week and year."));
915       return false;
916     }
917   i->s += 2;
918   skip_whitespace (i);
919   return true;
920 }
921
922 static bool
923 parse_time_delimiter (struct data_in *i)
924 {
925   bool delim = false;
926
927   while (have_char (i) && (*i->s == ':' || *i->s == '.'
928                            || isspace ((unsigned char) *i->s)))
929     {
930       delim = true;
931       i->s++;
932     }
933
934   if (delim)
935     return true;
936   
937   dls_error (i, _("Delimiter expected between fields in time."));
938   return false;
939 }
940
941 static bool
942 parse_hour (struct data_in *i, long *hour)
943 {
944   if (!parse_int (i, hour))
945     return false;
946   if (*hour >= 0)
947     return true;
948   
949   dls_error (i, _("Hour (%ld) must be positive."), *hour);
950   return false;
951 }
952
953 static bool
954 parse_minute (struct data_in *i, long *minute)
955 {
956   if (!parse_int (i, minute))
957     return false;
958   if (*minute >= 0 && *minute <= 59)
959     return true;
960   
961   dls_error (i, _("Minute (%ld) must be between 0 and 59."), *minute);
962   return false;
963 }
964
965 static bool
966 parse_opt_second (struct data_in *i, double *second)
967 {
968   bool delim = false;
969
970   char buf[64];
971   char *cp;
972
973   while (have_char (i)
974          && (*i->s == ':' || *i->s == '.' || isspace ((unsigned char) *i->s)))
975     {
976       delim = true;
977       i->s++;
978     }
979   
980   if (!delim || !isdigit ((unsigned char) *i->s))
981     {
982       *second = 0.0;
983       return true;
984     }
985
986   cp = buf;
987   while (have_char (i) && isdigit ((unsigned char) *i->s))
988     *cp++ = *i->s++;
989   if (have_char (i) && *i->s == '.')
990     *cp++ = *i->s++;
991   while (have_char (i) && isdigit ((unsigned char) *i->s))
992     *cp++ = *i->s++;
993   *cp = '\0';
994   
995   *second = strtod (buf, NULL);
996
997   return true;
998 }
999
1000 static bool
1001 parse_hour24 (struct data_in *i, long *hour24)
1002 {
1003   if (!parse_int (i, hour24))
1004     return false;
1005   if (*hour24 >= 0 && *hour24 <= 23)
1006     return true;
1007   
1008   dls_error (i, _("Hour (%ld) must be between 0 and 23."), *hour24);
1009   return false;
1010 }
1011
1012      
1013 static bool
1014 parse_weekday (struct data_in *i, long *weekday)
1015 {
1016   static const struct enum_name weekday_names[] = 
1017     {
1018       {"sunday", true, 1},
1019       {"su", true, 1},
1020       {"monday", true, 2},
1021       {"mo", true, 2},
1022       {"tuesday", true, 3},
1023       {"tu", true, 3},
1024       {"wednesday", true, 4},
1025       {"we", true, 4},
1026       {"thursday", true, 5},
1027       {"th", true, 5},
1028       {"friday", true, 6},
1029       {"fr", true, 6},
1030       {"saturday", true, 7},
1031       {"sa", true, 7},
1032       
1033       {NULL, false, 0},
1034     };
1035
1036   return parse_enum (i, _("weekday"), weekday_names, weekday);
1037 }
1038
1039 static bool
1040 parse_spaces (struct data_in *i)
1041 {
1042   skip_whitespace (i);
1043   return true;
1044 }
1045
1046 static bool
1047 parse_sign (struct data_in *i, int *sign)
1048 {
1049   if (!force_have_char (i))
1050     return false;
1051
1052   switch (*i->s)
1053     {
1054     case '-':
1055       i->s++;
1056       *sign = -1;
1057       break;
1058
1059     case '+':
1060       i->s++;
1061       /* fall through */
1062
1063     default:
1064       *sign = 1;
1065       break;
1066     }
1067
1068   return true;
1069 }
1070 \f
1071 /* Date & time formats. */
1072
1073 static void
1074 calendar_error (void *i_, const char *format, ...) 
1075 {
1076   struct data_in *i = i_;
1077   va_list args;
1078
1079   va_start (args, format);
1080   vdls_error (i, format, args);
1081   va_end (args);
1082 }
1083
1084 static bool
1085 ymd_to_ofs (struct data_in *i, int year, int month, int day, double *ofs) 
1086 {
1087   *ofs = calendar_gregorian_to_offset (year, month, day, calendar_error, i);
1088   return *ofs != SYSMIS;
1089 }
1090
1091 static bool
1092 ymd_to_date (struct data_in *i, int year, int month, int day, double *date) 
1093 {
1094   if (ymd_to_ofs (i, year, month, day, date)) 
1095     {
1096       *date *= 60. * 60. * 24.;
1097       return true; 
1098     }
1099   else
1100     return false;
1101 }
1102
1103 static bool
1104 parse_DATE (struct data_in *i)
1105 {
1106   long day, month, year;
1107
1108   return (parse_leader (i)
1109           && parse_day (i, &day)
1110           && parse_date_delimiter (i)
1111           && parse_month (i, &month)
1112           && parse_date_delimiter (i)
1113           && parse_year (i, &year)
1114           && parse_trailer (i)
1115           && ymd_to_date (i, year, month, day, &i->v->f));
1116 }
1117
1118 static bool
1119 parse_ADATE (struct data_in *i)
1120 {
1121   long month, day, year;
1122
1123   return (parse_leader (i)
1124           && parse_month (i, &month)
1125           && parse_date_delimiter (i)
1126           && parse_day (i, &day)
1127           && parse_date_delimiter (i)
1128           && parse_year (i, &year)
1129           && parse_trailer (i)
1130           && ymd_to_date (i, year, month, day, &i->v->f));
1131 }
1132
1133 static bool
1134 parse_EDATE (struct data_in *i)
1135 {
1136   long month, day, year;
1137
1138   return (parse_leader (i)
1139           && parse_day (i, &day)
1140           && parse_date_delimiter (i)
1141           && parse_month (i, &month)
1142           && parse_date_delimiter (i)
1143           && parse_year (i, &year)
1144           && parse_trailer (i)
1145           && ymd_to_date (i, year, month, day, &i->v->f));
1146 }
1147
1148 static bool
1149 parse_SDATE (struct data_in *i)
1150 {
1151   long month, day, year;
1152
1153   return (parse_leader (i)
1154           && parse_year (i, &year)
1155           && parse_date_delimiter (i)
1156           && parse_month (i, &month)
1157           && parse_date_delimiter (i)
1158           && parse_day (i, &day)
1159           && parse_trailer (i)
1160           && ymd_to_date (i, year, month, day, &i->v->f));
1161 }
1162
1163 static bool
1164 parse_JDATE (struct data_in *i)
1165 {
1166   long julian;
1167   double ofs;
1168   
1169   if (!parse_leader (i)
1170       || !parse_julian (i, &julian)
1171       || !parse_trailer (i)
1172       || !ymd_to_ofs (i, julian / 1000, 1, 1, &ofs))
1173     return false;
1174
1175   i->v->f = (ofs + julian % 1000 - 1) * 60. * 60. * 24.;
1176   return true;
1177 }
1178
1179 static bool
1180 parse_QYR (struct data_in *i)
1181 {
1182   long quarter, year;
1183
1184   return (parse_leader (i)
1185           && parse_quarter (i, &quarter)
1186           && parse_q_delimiter (i)
1187           && parse_year (i, &year)
1188           && parse_trailer (i)
1189           && ymd_to_date (i, year, (quarter - 1) * 3 + 1, 1, &i->v->f));
1190 }
1191
1192 static bool
1193 parse_MOYR (struct data_in *i)
1194 {
1195   long month, year;
1196
1197   return (parse_leader (i)
1198           && parse_month (i, &month)
1199           && parse_date_delimiter (i)
1200           && parse_year (i, &year)
1201           && parse_trailer (i)
1202           && ymd_to_date (i, year, month, 1, &i->v->f));
1203 }
1204
1205 static bool
1206 parse_WKYR (struct data_in *i)
1207 {
1208   long week, year;
1209   double ofs;
1210
1211   if (!parse_leader (i)
1212       || !parse_week (i, &week)
1213       || !parse_wk_delimiter (i)
1214       || !parse_year (i, &year)
1215       || !parse_trailer (i))
1216     return false;
1217
1218   if (year != 1582) 
1219     {
1220       if (!ymd_to_ofs (i, year, 1, 1, &ofs))
1221         return false;
1222     }
1223   else 
1224     {
1225       if (ymd_to_ofs (i, 1583, 1, 1, &ofs))
1226         return false;
1227       ofs -= 365;
1228     }
1229
1230   i->v->f = (ofs + (week - 1) * 7) * 60. * 60. * 24.;
1231   return true;
1232 }
1233
1234 static bool
1235 parse_TIME (struct data_in *i)
1236 {
1237   int sign;
1238   double second;
1239   long hour, minute;
1240
1241   if (!parse_leader (i)
1242       || !parse_sign (i, &sign)
1243       || !parse_spaces (i)
1244       || !parse_hour (i, &hour)
1245       || !parse_time_delimiter (i)
1246       || !parse_minute (i, &minute)
1247       || !parse_opt_second (i, &second))
1248     return false;
1249
1250   i->v->f = (hour * 60. * 60. + minute * 60. + second) * sign;
1251   return true;
1252 }
1253
1254 static bool
1255 parse_DTIME (struct data_in *i)
1256 {
1257   int sign;
1258   long day_count, hour;
1259   double second;
1260   long minute;
1261
1262   if (!parse_leader (i)
1263       || !parse_sign (i, &sign)
1264       || !parse_spaces (i)
1265       || !parse_day_count (i, &day_count)
1266       || !parse_time_delimiter (i)
1267       || !parse_hour (i, &hour)
1268       || !parse_time_delimiter (i)
1269       || !parse_minute (i, &minute)
1270       || !parse_opt_second (i, &second))
1271     return false;
1272
1273   i->v->f = (day_count * 60. * 60. * 24.
1274              + hour * 60. * 60.
1275              + minute * 60.
1276              + second) * sign;
1277   return true;
1278 }
1279
1280 static bool
1281 parse_DATETIME (struct data_in *i)
1282 {
1283   long day, month, year;
1284   long hour24;
1285   double second;
1286   long minute;
1287
1288   if (!parse_leader (i)
1289       || !parse_day (i, &day)
1290       || !parse_date_delimiter (i)
1291       || !parse_month (i, &month)
1292       || !parse_date_delimiter (i)
1293       || !parse_year (i, &year)
1294       || !parse_time_delimiter (i)
1295       || !parse_hour24 (i, &hour24)
1296       || !parse_time_delimiter (i)
1297       || !parse_minute (i, &minute)
1298       || !parse_opt_second (i, &second)
1299       || !ymd_to_date (i, year, month, day, &i->v->f))
1300     return false;
1301
1302   i->v->f += hour24 * 60. * 60. + minute * 60. + second;
1303   return true;
1304 }
1305
1306 static bool
1307 parse_WKDAY (struct data_in *i)
1308 {
1309   long weekday;
1310
1311   if (!parse_leader (i)
1312       || !parse_weekday (i, &weekday)
1313       || !parse_trailer (i))
1314     return false;
1315
1316   i->v->f = weekday;
1317   return true;
1318 }
1319
1320 static bool
1321 parse_MONTH (struct data_in *i)
1322 {
1323   long month;
1324
1325   if (!parse_leader (i)
1326       || !parse_month (i, &month)
1327       || !parse_trailer (i))
1328     return false;
1329
1330   i->v->f = month;
1331   return true;
1332 }
1333 \f
1334 /* Main dispatcher. */
1335
1336 static void
1337 default_result (struct data_in *i)
1338 {
1339   /* Default to SYSMIS or blanks. */
1340   if (fmt_is_string (i->format.type))
1341     memset (i->v->s, ' ', i->format.w);
1342   else
1343     i->v->f = get_blanks();
1344 }
1345
1346 bool
1347 data_in (struct data_in *i)
1348 {
1349   bool success;
1350
1351   assert (fmt_check_input (&i->format));
1352
1353   /* Check that we've got a string to work with. */
1354   if (i->e == i->s || i->format.w <= 0)
1355     {
1356       default_result (i);
1357       return true;
1358     }
1359
1360   i->f2 = i->f1 + (i->e - i->s) - 1;
1361
1362   /* Make sure that the string isn't too long. */
1363   if (i->format.w > fmt_max_input_width (i->format.type))
1364     {
1365       dls_error (i, _("Field too long (%d characters).  Truncated after "
1366                       "character %d."),
1367                  i->format.w, fmt_max_input_width (i->format.type));
1368       i->format.w = fmt_max_input_width (i->format.type);
1369     }
1370
1371   if (!(fmt_get_category (i->format.type)
1372         & (FMT_CAT_STRING | FMT_CAT_BINARY | FMT_CAT_HEXADECIMAL)))
1373     {
1374       const char *cp;
1375
1376       cp = i->s;
1377       for (;;)
1378         {
1379           if (!isspace ((unsigned char) *cp))
1380             break;
1381
1382           if (++cp == i->e)
1383             {
1384               i->v->f = get_blanks();
1385               return true;
1386             }
1387         }
1388     }
1389   
1390
1391   switch (i->format.type) 
1392     {
1393     case FMT_F:
1394     case FMT_COMMA:
1395     case FMT_DOT:
1396     case FMT_DOLLAR:
1397     case FMT_PCT:
1398     case FMT_E:
1399       success = parse_numeric (i);
1400       break;
1401     case FMT_CCA:
1402     case FMT_CCB:
1403     case FMT_CCC:
1404     case FMT_CCD:
1405     case FMT_CCE:
1406       NOT_REACHED ();
1407     case FMT_N:
1408       success = parse_N (i);
1409       break;
1410     case FMT_Z:
1411       success = parse_Z (i);
1412       break;
1413     case FMT_P:
1414       success = parse_P (i);
1415       break;
1416     case FMT_PK:
1417       success = parse_PK (i);
1418       break;
1419     case FMT_IB:
1420       success = parse_IB (i);
1421       break;
1422     case FMT_PIB:
1423       success = parse_PIB (i);
1424       break;
1425     case FMT_PIBHEX:
1426       success = parse_PIBHEX (i);
1427       break;
1428     case FMT_RB:
1429       success = parse_RB (i);
1430       break;
1431     case FMT_RBHEX:
1432       success = parse_RBHEX (i);
1433       break;
1434     case FMT_DATE:
1435       success = parse_DATE (i);
1436       break;
1437     case FMT_ADATE:
1438       success = parse_ADATE (i);
1439       break;
1440     case FMT_EDATE:
1441       success = parse_EDATE (i);
1442       break;
1443     case FMT_JDATE:
1444       success = parse_JDATE (i);
1445       break;
1446     case FMT_SDATE:
1447       success = parse_SDATE (i);
1448       break;
1449     case FMT_QYR:
1450       success = parse_QYR (i);
1451       break;
1452     case FMT_MOYR:
1453       success = parse_MOYR (i);
1454       break;
1455     case FMT_WKYR:
1456       success = parse_WKYR (i);
1457       break;
1458     case FMT_DATETIME:
1459       success = parse_DATETIME (i);
1460       break;
1461     case FMT_TIME:
1462       success = parse_TIME (i);
1463       break;
1464     case FMT_DTIME:
1465       success = parse_DTIME (i);
1466       break;
1467     case FMT_WKDAY:
1468       success = parse_WKDAY (i);
1469       break;
1470     case FMT_MONTH:
1471       success = parse_MONTH (i);
1472       break;
1473     case FMT_A:
1474       success = parse_A (i);
1475       break;
1476     case FMT_AHEX:
1477       success = parse_AHEX (i);
1478       break;
1479     default:
1480       NOT_REACHED ();
1481     }
1482   if (!success)
1483     default_result (i);
1484
1485   return success;
1486 }
1487 \f
1488 /* Utility function. */
1489
1490 /* Sets DI->{s,e} appropriately given that LINE has length LEN and the
1491    field starts at one-based column FC and ends at one-based column
1492    LC, inclusive. */
1493 void
1494 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1495                      int fc, int lc)
1496 {
1497   di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1498   di->e = line + ((size_t) lc <= len ? lc : len);
1499 }