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