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