1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
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.
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.
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
22 #include <libpspp/message.h>
30 #include <libpspp/message.h>
32 #include <libpspp/compiler.h>
33 #include "identifier.h"
34 #include <libpspp/magic.h>
35 #include <libpspp/misc.h>
37 #include <libpspp/str.h>
41 #define _(msgid) gettext (msgid)
43 /* Specialized error routine. */
45 static void dls_error (const struct data_in *, const char *format, ...)
49 vdls_error (const struct data_in *i, const char *format, va_list args)
54 if (i->flags & DI_IGNORE_ERROR)
59 ds_printf (&text, _("(column %d"), i->f1);
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);
65 m.category = MSG_DATA;
66 m.severity = MSG_ERROR;
67 msg_location (&m.where);
68 m.text = ds_c_str (&text);
74 dls_error (const struct data_in *i, const char *format, ...)
78 va_start (args, format);
79 vdls_error (i, format, args);
83 /* Parsing utility functions. */
85 /* Excludes leading and trailing whitespace from I by adjusting
88 trim_whitespace (struct data_in *i)
90 while (i->s < i->e && isspace ((unsigned char) i->s[0]))
93 while (i->s < i->e && isspace ((unsigned char) i->e[-1]))
97 /* Returns nonzero if we're not at the end of the string being
100 have_char (struct data_in *i)
105 /* If implied decimal places are enabled, apply them to
108 apply_implied_decimals (struct data_in *i)
110 if ((i->flags & DI_IMPLIED_DECIMALS) && i->format.d > 0)
111 i->v->f /= pow (10., i->format.d);
114 /* Format parsers. */
116 static bool parse_int (struct data_in *i, long *result);
118 /* This function is based on strtod() from the GNU C library. */
120 parse_numeric (struct data_in *i)
122 int sign; /* +1 or -1. */
123 double num; /* The number so far. */
125 bool got_dot; /* Found a decimal point. */
126 size_t digit_cnt; /* Count of digits. */
128 int decimal; /* Decimal point character. */
129 int grouping; /* Grouping character. */
131 long int exponent; /* Number's exponent. */
132 int type; /* Usually same as i->format.type. */
136 type = i->format.type;
137 if (type == FMT_DOLLAR && have_char (i) && *i->s == '$')
146 sign = *i->s == '-' ? -1 : 1;
147 if (*i->s == '-' || *i->s == '+')
155 decimal = get_decimal();
156 grouping = get_grouping();
160 decimal = get_grouping();
161 grouping = get_decimal();
169 for (; have_char (i); i->s++)
171 if (isdigit ((unsigned char) *i->s))
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.
182 We just need to record that there was another
183 digit so that we can multiply by 10 later. */
186 num = (num * 10.0) + (*i->s - '0');
188 /* Keep track of the number of digits after the decimal point.
189 If we just divided by 10 here, we would lose precision. */
193 else if (!got_dot && *i->s == decimal)
194 /* Record that we have found the decimal point. */
196 else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
197 /* Any other character terminates the number. */
208 dls_error (i, _("Field does not form a valid floating-point constant."));
213 if (have_char (i) && strchr ("eEdD-+", *i->s))
215 /* Get the exponent specified after the `e' or `E'. */
218 if (isalpha ((unsigned char) *i->s))
220 if (!parse_int (i, &exp))
228 else if (!got_dot && (i->flags & DI_IMPLIED_DECIMALS))
229 exponent -= i->format.d;
231 if (type == FMT_PCT && have_char (i) && *i->s == '%')
235 dls_error (i, _("Field contents followed by garbage."));
246 /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
250 if (-exponent + digit_cnt > -(DBL_MIN_10_EXP) + 5
251 || num < DBL_MIN * pow (10.0, (double) -exponent))
253 dls_error (i, _("Underflow in floating-point constant."));
258 num *= pow (10.0, (double) exponent);
260 else if (exponent > 0)
262 if (num > DBL_MAX * pow (10.0, (double) -exponent))
264 dls_error (i, _("Overflow in floating-point constant."));
269 num *= pow (10.0, (double) exponent);
272 i->v->f = sign > 0 ? num : -num;
276 /* Returns the integer value of hex digit C. */
280 const char s[] = "0123456789abcdef";
281 const char *cp = strchr (s, tolower ((unsigned char) c));
288 parse_N (struct data_in *i)
293 for (cp = i->s; cp < i->e; cp++)
295 if (!isdigit ((unsigned char) *cp))
297 dls_error (i, _("All characters in field must be digits."));
301 i->v->f = i->v->f * 10.0 + (*cp - '0');
304 apply_implied_decimals (i);
309 parse_PIBHEX (struct data_in *i)
317 for (cp = i->s; cp < i->e; cp++)
319 if (!isxdigit ((unsigned char) *cp))
321 dls_error (i, _("Unrecognized character in field."));
325 n = n * 16.0 + hexit_value (*cp);
333 parse_RBHEX (struct data_in *i)
335 /* Validate input. */
337 if ((i->e - i->s) % 2)
339 dls_error (i, _("Field must have even length."));
346 for (cp = i->s; cp < i->e; cp++)
347 if (!isxdigit ((unsigned char) *cp))
349 dls_error (i, _("Field must contain only hex digits."));
359 unsigned char c[sizeof (double)];
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]);
376 parse_Z (struct data_in *i)
379 bool got_dot = false;
381 /* Warn user that we suck. */
388 _("Quality of zoned decimal (Z) input format code is "
389 "suspect. Check your results three times. Report bugs "
390 "to %s."),PACKAGE_BUGREPORT);
395 /* Validate input. */
400 dls_error (i, _("Zoned decimal field contains fewer than 2 "
405 /* Copy sign into buf[0]. */
406 if ((i->e[-1] & 0xc0) != 0xc0)
408 dls_error (i, _("Bad sign byte in zoned decimal number."));
411 buf[0] = (i->e[-1] ^ (i->e[-1] >> 1)) & 0x10 ? '-' : '+';
413 /* Copy digits into buf[1 ... len - 1] and terminate string. */
418 for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
424 else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
425 *dp = (*sp & 0xf) + '0';
428 dls_error (i, _("Format error in zoned decimal number."));
435 /* Parse as number. */
439 i->v->f = strtod (buf, &tail);
442 dls_error (i, _("Error in syntax of zoned decimal number."));
448 apply_implied_decimals (i);
454 parse_IB (struct data_in *i)
456 #ifndef WORDS_BIGENDIAN
459 const unsigned char *p;
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;
468 memcpy (buf, i->s, i->e - i->s);
469 buf_reverse (buf, i->e - i->s);
470 p = (const unsigned char *) buf;
473 /* If the value is negative, we need to logical-NOT each value
484 for (j = 0; j < i->e - i->s; j++)
485 i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
488 /* If the value is negative, add 1 and set the sign, to complete a
489 two's-complement negation. */
491 i->v->f = -(i->v->f + 1.0);
493 apply_implied_decimals (i);
499 parse_PIB (struct data_in *i)
505 for (j = 0; j < i->e - i->s; j++)
506 i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
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];
512 apply_implied_decimals (i);
518 parse_P (struct data_in *i)
523 for (cp = i->s; cp < i->e - 1; cp++)
525 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
526 i->v->f = i->v->f * 10 + (*cp & 15);
528 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
529 if ((*cp ^ (*cp >> 1)) & 0x10)
532 apply_implied_decimals (i);
538 parse_PK (struct data_in *i)
543 for (cp = i->s; cp < i->e; cp++)
545 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
546 i->v->f = i->v->f * 10 + (*cp & 15);
549 apply_implied_decimals (i);
555 parse_RB (struct data_in *i)
560 unsigned char c[sizeof (double)];
564 memset (u.c, 0, sizeof u.c);
565 memcpy (u.c, i->s, min (sizeof u.c, (size_t) (i->e - i->s)));
573 parse_A (struct data_in *i)
575 buf_copy_rpad (i->v->s, i->format.w, i->s, i->e - i->s);
581 parse_AHEX (struct data_in *i)
583 /* Validate input. */
585 if ((i->e - i->s) % 2)
587 dls_error (i, _("Field must have even length."));
594 for (cp = i->s; cp < i->e; cp++)
595 if (!isxdigit ((unsigned char) *cp))
597 dls_error (i, _("Field must contain only hex digits."));
606 for (j = 0; j < min (i->e - i->s, i->format.w); j += 2)
607 i->v->s[j / 2] = hexit_value (i->s[j]) * 16 + hexit_value (i->s[j + 1]);
608 memset (i->v->s + (i->e - i->s) / 2, ' ', (i->format.w - (i->e - i->s)) / 2);
614 /* Date & time format components. */
616 /* Advances *CP past any whitespace characters. */
618 skip_whitespace (struct data_in *i)
620 while (isspace ((unsigned char) *i->s))
625 parse_leader (struct data_in *i)
632 force_have_char (struct data_in *i)
637 dls_error (i, _("Unexpected end of field."));
642 parse_int (struct data_in *i, long *result)
644 bool negative = false;
646 if (!force_have_char (i))
654 else if (*i->s == '-')
661 if (!isdigit ((unsigned char) *i->s))
663 dls_error (i, _("Digit expected in field."));
670 *result = *result * 10 + (*i->s++ - '0');
671 if (!have_char (i) || !isdigit ((unsigned char) *i->s))
681 parse_day (struct data_in *i, long *day)
683 if (!parse_int (i, day))
685 if (*day >= 1 && *day <= 31)
688 dls_error (i, _("Day (%ld) must be between 1 and 31."), *day);
693 parse_day_count (struct data_in *i, long *day_count)
695 return parse_int (i, day_count);
699 parse_date_delimiter (struct data_in *i)
704 && (*i->s == '-' || *i->s == '/' || isspace ((unsigned char) *i->s)
705 || *i->s == '.' || *i->s == ','))
713 dls_error (i, _("Delimiter expected between fields in date."));
717 /* Association between a name and a value. */
720 const char *name; /* Name. */
721 bool can_abbreviate; /* True if name may be abbreviated. */
722 int value; /* Value associated with name. */
725 /* Reads a name from I and sets *OUTPUT to the value associated
726 with that name. Returns true if successful, false otherwise. */
728 parse_enum (struct data_in *i, const char *what,
729 const struct enum_name *enum_names,
734 const struct enum_name *ep;
736 /* Consume alphabetic characters. */
739 while (have_char (i) && isalpha ((unsigned char) *i->s))
746 dls_error (i, _("Parse error at `%c' expecting %s."), *i->s, what);
750 for (ep = enum_names; ep->name != NULL; ep++)
751 if ((ep->can_abbreviate
752 && lex_id_match_len (ep->name, strlen (ep->name), name, length))
753 || (!ep->can_abbreviate && length == strlen (ep->name)
754 && !buf_compare_case (name, ep->name, length)))
760 dls_error (i, _("Unknown %s `%.*s'."), what, (int) length, name);
765 parse_month (struct data_in *i, long *month)
767 static const struct enum_name month_names[] =
769 {"january", true, 1},
770 {"february", true, 2},
777 {"september", true, 9},
778 {"october", true, 10},
779 {"november", true, 11},
780 {"december", true, 12},
800 if (!force_have_char (i))
803 if (isdigit ((unsigned char) *i->s))
805 if (!parse_int (i, month))
807 if (*month >= 1 && *month <= 12)
810 dls_error (i, _("Month (%ld) must be between 1 and 12."), *month);
814 return parse_enum (i, _("month"), month_names, month);
818 parse_year (struct data_in *i, long *year)
820 if (!parse_int (i, year))
823 if (*year >= 0 && *year <= 199)
825 if (*year >= 1582 || *year <= 19999)
828 dls_error (i, _("Year (%ld) must be between 1582 and 19999."), *year);
833 parse_trailer (struct data_in *i)
839 dls_error (i, _("Trailing garbage \"%s\" following date."), i->s);
844 parse_julian (struct data_in *i, long *julian)
846 if (!parse_int (i, julian))
850 int day = *julian % 1000;
852 if (day < 1 || day > 366)
854 dls_error (i, _("Julian day (%d) must be between 1 and 366."), day);
860 int year = *julian / 1000;
862 if (year >= 0 && year <= 199)
864 else if (year < 1582 || year > 19999)
866 dls_error (i, _("Year (%d) must be between 1582 and 19999."), year);
875 parse_quarter (struct data_in *i, long *quarter)
877 if (!parse_int (i, quarter))
879 if (*quarter >= 1 && *quarter <= 4)
882 dls_error (i, _("Quarter (%ld) must be between 1 and 4."), *quarter);
887 parse_q_delimiter (struct data_in *i)
890 if (!have_char (i) || tolower ((unsigned char) *i->s) != 'q')
892 dls_error (i, _("`Q' expected between quarter and year."));
901 parse_week (struct data_in *i, long *week)
903 if (!parse_int (i, week))
905 if (*week >= 1 && *week <= 53)
908 dls_error (i, _("Week (%ld) must be between 1 and 53."), *week);
913 parse_wk_delimiter (struct data_in *i)
917 || tolower ((unsigned char) i->s[0]) != 'w'
918 || tolower ((unsigned char) i->s[1]) != 'k')
920 dls_error (i, _("`WK' expected between week and year."));
929 parse_time_delimiter (struct data_in *i)
933 while (have_char (i) && (*i->s == ':' || *i->s == '.'
934 || isspace ((unsigned char) *i->s)))
943 dls_error (i, _("Delimiter expected between fields in time."));
948 parse_hour (struct data_in *i, long *hour)
950 if (!parse_int (i, hour))
955 dls_error (i, _("Hour (%ld) must be positive."), *hour);
960 parse_minute (struct data_in *i, long *minute)
962 if (!parse_int (i, minute))
964 if (*minute >= 0 && *minute <= 59)
967 dls_error (i, _("Minute (%ld) must be between 0 and 59."), *minute);
972 parse_opt_second (struct data_in *i, double *second)
980 && (*i->s == ':' || *i->s == '.' || isspace ((unsigned char) *i->s)))
986 if (!delim || !isdigit ((unsigned char) *i->s))
993 while (have_char (i) && isdigit ((unsigned char) *i->s))
995 if (have_char (i) && *i->s == '.')
997 while (have_char (i) && isdigit ((unsigned char) *i->s))
1001 *second = strtod (buf, NULL);
1007 parse_hour24 (struct data_in *i, long *hour24)
1009 if (!parse_int (i, hour24))
1011 if (*hour24 >= 0 && *hour24 <= 23)
1014 dls_error (i, _("Hour (%ld) must be between 0 and 23."), *hour24);
1020 parse_weekday (struct data_in *i, long *weekday)
1022 static const struct enum_name weekday_names[] =
1024 {"sunday", true, 1},
1026 {"monday", true, 2},
1028 {"tuesday", true, 3},
1030 {"wednesday", true, 4},
1032 {"thursday", true, 5},
1034 {"friday", true, 6},
1036 {"saturday", true, 7},
1042 return parse_enum (i, _("weekday"), weekday_names, weekday);
1046 parse_spaces (struct data_in *i)
1048 skip_whitespace (i);
1053 parse_sign (struct data_in *i, int *sign)
1055 if (!force_have_char (i))
1077 /* Date & time formats. */
1080 calendar_error (void *i_, const char *format, ...)
1082 struct data_in *i = i_;
1085 va_start (args, format);
1086 vdls_error (i, format, args);
1091 ymd_to_ofs (struct data_in *i, int year, int month, int day, double *ofs)
1093 *ofs = calendar_gregorian_to_offset (year, month, day, calendar_error, i);
1094 return *ofs != SYSMIS;
1098 ymd_to_date (struct data_in *i, int year, int month, int day, double *date)
1100 if (ymd_to_ofs (i, year, month, day, date))
1102 *date *= 60. * 60. * 24.;
1110 parse_DATE (struct data_in *i)
1112 long day, month, year;
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));
1125 parse_ADATE (struct data_in *i)
1127 long month, day, year;
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));
1140 parse_EDATE (struct data_in *i)
1142 long month, day, year;
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));
1155 parse_SDATE (struct data_in *i)
1157 long month, day, year;
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));
1170 parse_JDATE (struct data_in *i)
1175 if (!parse_leader (i)
1176 || !parse_julian (i, &julian)
1177 || !parse_trailer (i)
1178 || !ymd_to_ofs (i, julian / 1000, 1, 1, &ofs))
1181 i->v->f = (ofs + julian % 1000 - 1) * 60. * 60. * 24.;
1186 parse_QYR (struct data_in *i)
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));
1199 parse_MOYR (struct data_in *i)
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));
1212 parse_WKYR (struct data_in *i)
1217 if (!parse_leader (i)
1218 || !parse_week (i, &week)
1219 || !parse_wk_delimiter (i)
1220 || !parse_year (i, &year)
1221 || !parse_trailer (i))
1226 if (!ymd_to_ofs (i, year, 1, 1, &ofs))
1231 if (ymd_to_ofs (i, 1583, 1, 1, &ofs))
1236 i->v->f = (ofs + (week - 1) * 7) * 60. * 60. * 24.;
1241 parse_TIME (struct data_in *i)
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))
1256 i->v->f = (hour * 60. * 60. + minute * 60. + second) * sign;
1261 parse_DTIME (struct data_in *i)
1264 long day_count, hour;
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))
1279 i->v->f = (day_count * 60. * 60. * 24.
1287 parse_DATETIME (struct data_in *i)
1289 long day, month, year;
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))
1308 i->v->f += hour24 * 60. * 60. + minute * 60. + second;
1313 parse_WKDAY (struct data_in *i)
1317 if (!parse_leader (i)
1318 || !parse_weekday (i, &weekday)
1319 || !parse_trailer (i))
1327 parse_MONTH (struct data_in *i)
1331 if (!parse_leader (i)
1332 || !parse_month (i, &month)
1333 || !parse_trailer (i))
1340 /* Main dispatcher. */
1343 default_result (struct data_in *i)
1345 const struct fmt_desc *const fmt = &formats[i->format.type];
1347 /* Default to SYSMIS or blanks. */
1348 if (fmt->cat & FCAT_STRING)
1349 memset (i->v->s, ' ', i->format.w);
1351 i->v->f = get_blanks();
1355 data_in (struct data_in *i)
1357 const struct fmt_desc *const fmt = &formats[i->format.type];
1359 assert (check_input_specifier (&i->format, 0));
1361 /* Check that we've got a string to work with. */
1362 if (i->e == i->s || i->format.w <= 0)
1368 i->f2 = i->f1 + (i->e - i->s) - 1;
1370 /* Make sure that the string isn't too long. */
1371 if (i->format.w > fmt->Imax_w)
1373 dls_error (i, _("Field too long (%d characters). Truncated after "
1375 i->format.w, fmt->Imax_w);
1376 i->format.w = fmt->Imax_w;
1379 if (fmt->cat & FCAT_BLANKS_SYSMIS)
1386 if (!isspace ((unsigned char) *cp))
1391 i->v->f = get_blanks();
1398 static bool (*const handlers[FMT_NUMBER_OF_FORMATS])(struct data_in *) =
1400 parse_numeric, parse_N, parse_numeric, parse_numeric,
1401 parse_numeric, parse_numeric, parse_numeric,
1402 parse_Z, parse_A, parse_AHEX, parse_IB, parse_P, parse_PIB,
1403 parse_PIBHEX, parse_PK, parse_RB, parse_RBHEX,
1404 NULL, NULL, NULL, NULL, NULL,
1405 parse_DATE, parse_EDATE, parse_SDATE, parse_ADATE, parse_JDATE,
1406 parse_QYR, parse_MOYR, parse_WKYR,
1407 parse_DATETIME, parse_TIME, parse_DTIME,
1408 parse_WKDAY, parse_MONTH,
1411 bool (*handler)(struct data_in *);
1414 handler = handlers[i->format.type];
1415 assert (handler != NULL);
1417 success = handler (i);
1425 /* Utility function. */
1427 /* Sets DI->{s,e} appropriately given that LINE has length LEN and the
1428 field starts at one-based column FC and ends at one-based column
1431 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1434 di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1435 di->e = line + ((size_t) lc <= len ? lc : len);