Fix error messages and comment.
[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 msg m;
52   struct string text;
53
54   if (i->flags & DI_IGNORE_ERROR)
55     return;
56
57   ds_init_empty (&text);
58   if (i->f1 == i->f2)
59     ds_put_format (&text, _("(column %d"), i->f1);
60   else
61     ds_put_format (&text, _("(columns %d-%d"), i->f1, i->f2);
62   ds_put_format (&text, _(", field type %s) "), fmt_to_string (&i->format));
63   ds_put_vformat (&text, format, args);
64
65   m.category = MSG_DATA;
66   m.severity = MSG_ERROR;
67   m.text = ds_cstr (&text);
68
69   msg_emit (&m);
70 }
71
72 static void
73 dls_error (const struct data_in *i, const char *format, ...) 
74 {
75   va_list args;
76
77   va_start (args, format);
78   vdls_error (i, format, args);
79   va_end (args);
80 }
81 \f
82 /* Parsing utility functions. */
83
84 /* Excludes leading and trailing whitespace from I by adjusting
85    pointers. */
86 static void
87 trim_whitespace (struct data_in *i)
88 {
89   while (i->s < i->e && isspace ((unsigned char) i->s[0])) 
90     i->s++;
91
92   while (i->s < i->e && isspace ((unsigned char) i->e[-1]))
93     i->e--;
94 }
95
96 /* Returns true if we're not at the end of the string being
97    parsed. */
98 static inline bool
99 have_char (struct data_in *i)
100 {
101   return i->s < i->e;
102 }
103
104 /* If implied decimal places are enabled, apply them to
105    I->v->f. */
106 static void
107 apply_implied_decimals (struct data_in *i) 
108 {
109   if ((i->flags & DI_IMPLIED_DECIMALS) && i->format.d > 0)
110     i->v->f /= pow (10., i->format.d);
111 }
112 \f
113 /* Format parsers. */ 
114
115 static bool parse_int (struct data_in *i, long *result);
116
117 /* This function is based on strtod() from the GNU C library. */
118 static bool
119 parse_numeric (struct data_in *i)
120 {
121   int sign;                     /* +1 or -1. */
122   double num;                   /* The number so far.  */
123
124   bool got_dot;                 /* Found a decimal point.  */
125   size_t digit_cnt;             /* Count of digits.  */
126
127   int decimal;                  /* Decimal point character. */
128   int grouping;                 /* Grouping character. */
129
130   long int exponent;            /* Number's exponent. */
131   int type;                     /* Usually same as i->format.type. */
132
133   trim_whitespace (i);
134
135   type = i->format.type;
136   if (type == FMT_DOLLAR && have_char (i) && *i->s == '$')
137     {
138       i->s++;
139       type = FMT_COMMA;
140     }
141
142   /* Get the sign.  */
143   if (have_char (i))
144     {
145       sign = *i->s == '-' ? -1 : 1;
146       if (*i->s == '-' || *i->s == '+')
147         i->s++;
148     }
149   else
150     sign = 1;
151   
152   if (type != FMT_DOT)
153     {
154       decimal = get_decimal();
155       grouping = get_grouping();
156     }
157   else
158     {
159       decimal = get_grouping();
160       grouping = get_decimal();
161     }
162
163   i->v->f = SYSMIS;
164   num = 0.0;
165   got_dot = false;
166   digit_cnt = 0;
167   exponent = 0;
168   for (; have_char (i); i->s++)
169     {
170       if (isdigit ((unsigned char) *i->s))
171         {
172           digit_cnt++;
173
174           /* Make sure that multiplication by 10 will not overflow.  */
175           if (num > DBL_MAX * 0.1)
176             /* The value of the digit doesn't matter, since we have already
177                gotten as many digits as can be represented in a `double'.
178                This doesn't necessarily mean the result will overflow.
179                The exponent may reduce it to within range.
180
181                We just need to record that there was another
182                digit so that we can multiply by 10 later.  */
183             ++exponent;
184           else
185             num = (num * 10.0) + (*i->s - '0');
186
187           /* Keep track of the number of digits after the decimal point.
188              If we just divided by 10 here, we would lose precision.  */
189           if (got_dot)
190             --exponent;
191         }
192       else if (!got_dot && *i->s == decimal)
193         /* Record that we have found the decimal point.  */
194         got_dot = true;
195       else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
196         /* Any other character terminates the number.  */
197         break;
198     }
199
200   if (!digit_cnt)
201     {
202       if (got_dot)
203         {
204           i->v->f = SYSMIS;
205           return true;
206         }
207       dls_error (i, _("Field does not form a valid floating-point constant."));
208       i->v->f = SYSMIS;
209       return false;
210     }
211   
212   if (have_char (i) && strchr ("eEdD-+", *i->s))
213     {
214       /* Get the exponent specified after the `e' or `E'.  */
215       long exp;
216
217       if (isalpha ((unsigned char) *i->s))
218         i->s++;
219       if (!parse_int (i, &exp))
220         {
221           i->v->f = SYSMIS;
222           return false;
223         }
224
225       exponent += exp;
226     }
227   else if (!got_dot && (i->flags & DI_IMPLIED_DECIMALS))
228     exponent -= i->format.d;
229
230   if (type == FMT_PCT && have_char (i) && *i->s == '%')
231     i->s++;
232   if (i->s < i->e)
233     {
234       dls_error (i, _("Field contents followed by garbage."));
235       i->v->f = SYSMIS;
236       return false;
237     }
238
239   if (num == 0.0)
240     {
241       i->v->f = 0.0;
242       return true;
243     }
244
245   /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
246      and underflow.  */
247   if (exponent < 0)
248     {
249       if (-exponent + digit_cnt > -(DBL_MIN_10_EXP) + 5
250           || num < DBL_MIN * pow (10.0, (double) -exponent)) 
251         {
252           dls_error (i, _("Underflow in floating-point constant."));
253           i->v->f = 0.0;
254           return false;
255         }
256
257       num *= pow (10.0, (double) exponent);
258     }
259   else if (exponent > 0)
260     {
261       if (num > DBL_MAX * pow (10.0, (double) -exponent))
262         {
263           dls_error (i, _("Overflow in floating-point constant."));
264           i->v->f = SYSMIS;
265           return false;
266         }
267       
268       num *= pow (10.0, (double) exponent);
269     }
270
271   i->v->f = sign > 0 ? num : -num;
272   return true;
273 }
274
275 /* Returns the integer value of hex digit C. */
276 static inline int
277 hexit_value (int c)
278 {
279   const char s[] = "0123456789abcdef";
280   const char *cp = strchr (s, tolower ((unsigned char) c));
281
282   assert (cp != NULL);
283   return cp - s;
284 }
285
286 static inline bool
287 parse_N (struct data_in *i)
288 {
289   const char *cp;
290
291   i->v->f = 0;
292   for (cp = i->s; cp < i->e; cp++)
293     {
294       if (!isdigit ((unsigned char) *cp))
295         {
296           dls_error (i, _("All characters in field must be digits."));
297           return false;
298         }
299
300       i->v->f = i->v->f * 10.0 + (*cp - '0');
301     }
302
303   apply_implied_decimals (i);
304   return true;
305 }
306
307 static inline bool
308 parse_PIBHEX (struct data_in *i)
309 {
310   double n;
311   const char *cp;
312
313   trim_whitespace (i);
314
315   n = 0.0;
316   for (cp = i->s; cp < i->e; cp++)
317     {
318       if (!isxdigit ((unsigned char) *cp))
319         {
320           dls_error (i, _("Unrecognized character in field."));
321           return false;
322         }
323
324       n = n * 16.0 + hexit_value (*cp);
325     }
326   
327   i->v->f = n;
328   return true;
329 }
330
331 static inline bool
332 parse_RBHEX (struct data_in *i)
333 {
334   /* Validate input. */
335   trim_whitespace (i);
336   if ((i->e - i->s) % 2)
337     {
338       dls_error (i, _("Field must have even length."));
339       return false;
340     }
341   
342   {
343     const char *cp;
344     
345     for (cp = i->s; cp < i->e; cp++)
346       if (!isxdigit ((unsigned char) *cp))
347         {
348           dls_error (i, _("Field must contain only hex digits."));
349           return false;
350         }
351   }
352   
353   /* Parse input. */
354   {
355     union
356       {
357         double d;
358         unsigned char c[sizeof (double)];
359       }
360     u;
361
362     int j;
363
364     memset (u.c, 0, sizeof u.c);
365     for (j = 0; j < min ((i->e - i->s) / 2, sizeof u.d); j++)
366       u.c[j] = 16 * hexit_value (i->s[j * 2]) + hexit_value (i->s[j * 2 + 1]);
367
368     i->v->f = u.d;
369   }
370   
371   return true;
372 }
373
374 static inline bool
375 parse_Z (struct data_in *i)
376 {
377   char buf[64];
378   bool got_dot = false;
379
380   /* Warn user that we suck. */
381   {
382     static bool warned;
383
384     if (!warned)
385       {
386         msg (MW, 
387              _("Quality of zoned decimal (Z) input format code is "
388                "suspect.  Check your results three times. Report bugs "
389                 "to %s."),PACKAGE_BUGREPORT);
390         warned = true;
391       }
392   }
393
394   /* Validate input. */
395   trim_whitespace (i);
396
397   if (i->e - i->s < 2)
398     {
399       dls_error (i, _("Zoned decimal field contains fewer than 2 "
400                       "characters."));
401       return false;
402     }
403
404   /* Copy sign into buf[0]. */
405   if ((i->e[-1] & 0xc0) != 0xc0)
406     {
407       dls_error (i, _("Bad sign byte in zoned decimal number."));
408       return false;
409     }
410   buf[0] = (i->e[-1] ^ (i->e[-1] >> 1)) & 0x10 ? '-' : '+';
411
412   /* Copy digits into buf[1 ... len - 1] and terminate string. */
413   {
414     const char *sp;
415     char *dp;
416
417     for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
418       if (*sp == '.') 
419         {
420           *dp = '.';
421           got_dot = true;
422         }
423       else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
424         *dp = (*sp & 0xf) + '0';
425       else
426         {
427           dls_error (i, _("Format error in zoned decimal number."));
428           return false;
429         }
430
431     *dp = '\0';
432   }
433
434   /* Parse as number. */
435   {
436     char *tail;
437     
438     i->v->f = strtod (buf, &tail);
439     if (tail != i->e)
440       {
441         dls_error (i, _("Error in syntax of zoned decimal number."));
442         return false;
443       }
444   }
445
446   if (!got_dot)
447     apply_implied_decimals (i);
448
449   return true;
450 }
451
452 static inline bool
453 parse_IB (struct data_in *i)
454 {
455 #ifndef WORDS_BIGENDIAN
456   char buf[64];
457 #endif
458   const unsigned char *p;
459
460   unsigned char xor;
461
462   /* We want the data to be in big-endian format.  If this is a
463      little-endian machine, reverse the byte order. */
464 #ifdef WORDS_BIGENDIAN
465   p = (const unsigned char *) i->s;
466 #else
467   memcpy (buf, i->s, i->e - i->s);
468   buf_reverse (buf, i->e - i->s);
469   p = (const unsigned char *) buf;
470 #endif
471
472   /* If the value is negative, we need to logical-NOT each value
473      before adding it. */
474   if (p[0] & 0x80)
475     xor = 0xff;
476   else
477     xor = 0x00;
478   
479   {
480     int j;
481
482     i->v->f = 0.0;
483     for (j = 0; j < i->e - i->s; j++)
484       i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
485   }
486
487   /* If the value is negative, add 1 and set the sign, to complete a
488      two's-complement negation. */
489   if (p[0] & 0x80)
490     i->v->f = -(i->v->f + 1.0);
491
492   apply_implied_decimals (i);
493
494   return true;
495 }
496
497 static inline bool
498 parse_PIB (struct data_in *i)
499 {
500   int j;
501
502   i->v->f = 0.0;
503 #if WORDS_BIGENDIAN
504   for (j = 0; j < i->e - i->s; j++)
505     i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
506 #else
507   for (j = i->e - i->s - 1; j >= 0; j--)
508     i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
509 #endif
510
511   apply_implied_decimals (i);
512
513   return true;
514 }
515
516 static inline bool
517 parse_P (struct data_in *i)
518 {
519   const char *cp;
520
521   i->v->f = 0.0;
522   for (cp = i->s; cp < i->e - 1; cp++)
523     {
524       i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
525       i->v->f = i->v->f * 10 + (*cp & 15);
526     }
527   i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
528   if ((*cp ^ (*cp >> 1)) & 0x10)
529       i->v->f = -i->v->f;
530
531   apply_implied_decimals (i);
532
533   return true;
534 }
535
536 static inline bool
537 parse_PK (struct data_in *i)
538 {
539   const char *cp;
540
541   i->v->f = 0.0;
542   for (cp = i->s; cp < i->e; cp++)
543     {
544       i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
545       i->v->f = i->v->f * 10 + (*cp & 15);
546     }
547
548   apply_implied_decimals (i);
549
550   return true;
551 }
552
553 static inline bool
554 parse_RB (struct data_in *i)
555 {
556   union
557     {
558       double d;
559       unsigned char c[sizeof (double)];
560     }
561   u;
562
563   memset (u.c, 0, sizeof u.c);
564   memcpy (u.c, i->s, min (sizeof u.c, (size_t) (i->e - i->s)));
565   i->v->f = u.d;
566
567   return true;
568 }
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   
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."),
839              (int) (i->e - i->s), 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     typedef bool (*handler_t) (struct data_in *);
1399     static const handler_t handlers[FMT_NUMBER_OF_FORMATS] = 
1400       {
1401         parse_numeric, parse_N, parse_numeric, parse_numeric,
1402         parse_numeric, parse_numeric, parse_numeric,
1403         parse_Z, parse_A, parse_AHEX, parse_IB, parse_P, parse_PIB,
1404         parse_PIBHEX, parse_PK, parse_RB, parse_RBHEX,
1405         NULL, NULL, NULL, NULL, NULL,
1406         parse_DATE, parse_EDATE, parse_SDATE, parse_ADATE, parse_JDATE,
1407         parse_QYR, parse_MOYR, parse_WKYR,
1408         parse_DATETIME, parse_TIME, parse_DTIME,
1409         parse_WKDAY, parse_MONTH,
1410       };
1411
1412     handler_t handler;
1413     bool success;
1414
1415     handler = handlers[i->format.type];
1416     assert (handler != NULL);
1417
1418     success = handler (i);
1419     if (!success)
1420       default_result (i);
1421
1422     return success;
1423   }
1424 }
1425 \f
1426 /* Utility function. */
1427
1428 /* Sets DI->{s,e} appropriately given that LINE has length LEN and the
1429    field starts at one-based column FC and ends at one-based column
1430    LC, inclusive. */
1431 void
1432 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1433                      int fc, int lc)
1434 {
1435   di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1436   di->e = line + ((size_t) lc <= len ? lc : len);
1437 }