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