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)
57 ds_init_empty (&text);
59 ds_put_format (&text, _("(column %d"), i->f1);
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);
65 m.category = MSG_DATA;
66 m.severity = MSG_ERROR;
67 m.text = ds_cstr (&text);
73 dls_error (const struct data_in *i, const char *format, ...)
77 va_start (args, format);
78 vdls_error (i, format, args);
82 /* Parsing utility functions. */
84 /* Excludes leading and trailing whitespace from I by adjusting
87 trim_whitespace (struct data_in *i)
89 while (i->s < i->e && isspace ((unsigned char) i->s[0]))
92 while (i->s < i->e && isspace ((unsigned char) i->e[-1]))
96 /* Returns nonzero if we're not at the end of the string being
99 have_char (struct data_in *i)
104 /* If implied decimal places are enabled, apply them to
107 apply_implied_decimals (struct data_in *i)
109 if ((i->flags & DI_IMPLIED_DECIMALS) && i->format.d > 0)
110 i->v->f /= pow (10., i->format.d);
113 /* Format parsers. */
115 static bool parse_int (struct data_in *i, long *result);
117 /* This function is based on strtod() from the GNU C library. */
119 parse_numeric (struct data_in *i)
121 int sign; /* +1 or -1. */
122 double num; /* The number so far. */
124 bool got_dot; /* Found a decimal point. */
125 size_t digit_cnt; /* Count of digits. */
127 int decimal; /* Decimal point character. */
128 int grouping; /* Grouping character. */
130 long int exponent; /* Number's exponent. */
131 int type; /* Usually same as i->format.type. */
135 type = i->format.type;
136 if (type == FMT_DOLLAR && have_char (i) && *i->s == '$')
145 sign = *i->s == '-' ? -1 : 1;
146 if (*i->s == '-' || *i->s == '+')
154 decimal = get_decimal();
155 grouping = get_grouping();
159 decimal = get_grouping();
160 grouping = get_decimal();
168 for (; have_char (i); i->s++)
170 if (isdigit ((unsigned char) *i->s))
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.
181 We just need to record that there was another
182 digit so that we can multiply by 10 later. */
185 num = (num * 10.0) + (*i->s - '0');
187 /* Keep track of the number of digits after the decimal point.
188 If we just divided by 10 here, we would lose precision. */
192 else if (!got_dot && *i->s == decimal)
193 /* Record that we have found the decimal point. */
195 else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
196 /* Any other character terminates the number. */
207 dls_error (i, _("Field does not form a valid floating-point constant."));
212 if (have_char (i) && strchr ("eEdD-+", *i->s))
214 /* Get the exponent specified after the `e' or `E'. */
217 if (isalpha ((unsigned char) *i->s))
219 if (!parse_int (i, &exp))
227 else if (!got_dot && (i->flags & DI_IMPLIED_DECIMALS))
228 exponent -= i->format.d;
230 if (type == FMT_PCT && have_char (i) && *i->s == '%')
234 dls_error (i, _("Field contents followed by garbage."));
245 /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
249 if (-exponent + digit_cnt > -(DBL_MIN_10_EXP) + 5
250 || num < DBL_MIN * pow (10.0, (double) -exponent))
252 dls_error (i, _("Underflow in floating-point constant."));
257 num *= pow (10.0, (double) exponent);
259 else if (exponent > 0)
261 if (num > DBL_MAX * pow (10.0, (double) -exponent))
263 dls_error (i, _("Overflow in floating-point constant."));
268 num *= pow (10.0, (double) exponent);
271 i->v->f = sign > 0 ? num : -num;
275 /* Returns the integer value of hex digit C. */
279 const char s[] = "0123456789abcdef";
280 const char *cp = strchr (s, tolower ((unsigned char) c));
287 parse_N (struct data_in *i)
292 for (cp = i->s; cp < i->e; cp++)
294 if (!isdigit ((unsigned char) *cp))
296 dls_error (i, _("All characters in field must be digits."));
300 i->v->f = i->v->f * 10.0 + (*cp - '0');
303 apply_implied_decimals (i);
308 parse_PIBHEX (struct data_in *i)
316 for (cp = i->s; cp < i->e; cp++)
318 if (!isxdigit ((unsigned char) *cp))
320 dls_error (i, _("Unrecognized character in field."));
324 n = n * 16.0 + hexit_value (*cp);
332 parse_RBHEX (struct data_in *i)
334 /* Validate input. */
336 if ((i->e - i->s) % 2)
338 dls_error (i, _("Field must have even length."));
345 for (cp = i->s; cp < i->e; cp++)
346 if (!isxdigit ((unsigned char) *cp))
348 dls_error (i, _("Field must contain only hex digits."));
358 unsigned char c[sizeof (double)];
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]);
375 parse_Z (struct data_in *i)
378 bool got_dot = false;
380 /* Warn user that we suck. */
387 _("Quality of zoned decimal (Z) input format code is "
388 "suspect. Check your results three times. Report bugs "
389 "to %s."),PACKAGE_BUGREPORT);
394 /* Validate input. */
399 dls_error (i, _("Zoned decimal field contains fewer than 2 "
404 /* Copy sign into buf[0]. */
405 if ((i->e[-1] & 0xc0) != 0xc0)
407 dls_error (i, _("Bad sign byte in zoned decimal number."));
410 buf[0] = (i->e[-1] ^ (i->e[-1] >> 1)) & 0x10 ? '-' : '+';
412 /* Copy digits into buf[1 ... len - 1] and terminate string. */
417 for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
423 else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
424 *dp = (*sp & 0xf) + '0';
427 dls_error (i, _("Format error in zoned decimal number."));
434 /* Parse as number. */
438 i->v->f = strtod (buf, &tail);
441 dls_error (i, _("Error in syntax of zoned decimal number."));
447 apply_implied_decimals (i);
453 parse_IB (struct data_in *i)
455 #ifndef WORDS_BIGENDIAN
458 const unsigned char *p;
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;
467 memcpy (buf, i->s, i->e - i->s);
468 buf_reverse (buf, i->e - i->s);
469 p = (const unsigned char *) buf;
472 /* If the value is negative, we need to logical-NOT each value
483 for (j = 0; j < i->e - i->s; j++)
484 i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
487 /* If the value is negative, add 1 and set the sign, to complete a
488 two's-complement negation. */
490 i->v->f = -(i->v->f + 1.0);
492 apply_implied_decimals (i);
498 parse_PIB (struct data_in *i)
504 for (j = 0; j < i->e - i->s; j++)
505 i->v->f = i->v->f * 256.0 + (unsigned char) i->s[j];
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];
511 apply_implied_decimals (i);
517 parse_P (struct data_in *i)
522 for (cp = i->s; cp < i->e - 1; cp++)
524 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
525 i->v->f = i->v->f * 10 + (*cp & 15);
527 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
528 if ((*cp ^ (*cp >> 1)) & 0x10)
531 apply_implied_decimals (i);
537 parse_PK (struct data_in *i)
542 for (cp = i->s; cp < i->e; cp++)
544 i->v->f = i->v->f * 10 + ((*cp >> 4) & 15);
545 i->v->f = i->v->f * 10 + (*cp & 15);
548 apply_implied_decimals (i);
554 parse_RB (struct data_in *i)
559 unsigned char c[sizeof (double)];
563 memset (u.c, 0, sizeof u.c);
564 memcpy (u.c, i->s, min (sizeof u.c, (size_t) (i->e - i->s)));
572 parse_A (struct data_in *i)
574 buf_copy_rpad (i->v->s, i->format.w, i->s, i->e - i->s);
580 parse_AHEX (struct data_in *i)
582 /* Validate input. */
584 if ((i->e - i->s) % 2)
586 dls_error (i, _("Field must have even length."));
593 for (cp = i->s; cp < i->e; cp++)
594 if (!isxdigit ((unsigned char) *cp))
596 dls_error (i, _("Field must contain only hex digits."));
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);
613 /* Date & time format components. */
615 /* Advances *CP past any whitespace characters. */
617 skip_whitespace (struct data_in *i)
619 while (isspace ((unsigned char) *i->s))
624 parse_leader (struct data_in *i)
631 force_have_char (struct data_in *i)
636 dls_error (i, _("Unexpected end of field."));
641 parse_int (struct data_in *i, long *result)
643 bool negative = false;
645 if (!force_have_char (i))
653 else if (*i->s == '-')
660 if (!isdigit ((unsigned char) *i->s))
662 dls_error (i, _("Digit expected in field."));
669 *result = *result * 10 + (*i->s++ - '0');
670 if (!have_char (i) || !isdigit ((unsigned char) *i->s))
680 parse_day (struct data_in *i, long *day)
682 if (!parse_int (i, day))
684 if (*day >= 1 && *day <= 31)
687 dls_error (i, _("Day (%ld) must be between 1 and 31."), *day);
692 parse_day_count (struct data_in *i, long *day_count)
694 return parse_int (i, day_count);
698 parse_date_delimiter (struct data_in *i)
703 && (*i->s == '-' || *i->s == '/' || isspace ((unsigned char) *i->s)
704 || *i->s == '.' || *i->s == ','))
712 dls_error (i, _("Delimiter expected between fields in date."));
716 /* Association between a name and a value. */
719 const char *name; /* Name. */
720 bool can_abbreviate; /* True if name may be abbreviated. */
721 int value; /* Value associated with name. */
724 /* Reads a name from I and sets *OUTPUT to the value associated
725 with that name. Returns true if successful, false otherwise. */
727 parse_enum (struct data_in *i, const char *what,
728 const struct enum_name *enum_names,
733 const struct enum_name *ep;
735 /* Consume alphabetic characters. */
738 while (have_char (i) && isalpha ((unsigned char) *i->s))
745 dls_error (i, _("Parse error at `%c' expecting %s."), *i->s, what);
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)))
759 dls_error (i, _("Unknown %s `%.*s'."), what, (int) length, name);
764 parse_month (struct data_in *i, long *month)
766 static const struct enum_name month_names[] =
768 {"january", true, 1},
769 {"february", true, 2},
776 {"september", true, 9},
777 {"october", true, 10},
778 {"november", true, 11},
779 {"december", true, 12},
799 if (!force_have_char (i))
802 if (isdigit ((unsigned char) *i->s))
804 if (!parse_int (i, month))
806 if (*month >= 1 && *month <= 12)
809 dls_error (i, _("Month (%ld) must be between 1 and 12."), *month);
813 return parse_enum (i, _("month"), month_names, month);
817 parse_year (struct data_in *i, long *year)
819 if (!parse_int (i, year))
822 if (*year >= 0 && *year <= 199)
824 if (*year >= 1582 || *year <= 19999)
827 dls_error (i, _("Year (%ld) must be between 1582 and 19999."), *year);
832 parse_trailer (struct data_in *i)
838 dls_error (i, _("Trailing garbage \"%s\" following date."), i->s);
843 parse_julian (struct data_in *i, long *julian)
845 if (!parse_int (i, julian))
849 int day = *julian % 1000;
851 if (day < 1 || day > 366)
853 dls_error (i, _("Julian day (%d) must be between 1 and 366."), day);
859 int year = *julian / 1000;
861 if (year >= 0 && year <= 199)
863 else if (year < 1582 || year > 19999)
865 dls_error (i, _("Year (%d) must be between 1582 and 19999."), year);
874 parse_quarter (struct data_in *i, long *quarter)
876 if (!parse_int (i, quarter))
878 if (*quarter >= 1 && *quarter <= 4)
881 dls_error (i, _("Quarter (%ld) must be between 1 and 4."), *quarter);
886 parse_q_delimiter (struct data_in *i)
889 if (!have_char (i) || tolower ((unsigned char) *i->s) != 'q')
891 dls_error (i, _("`Q' expected between quarter and year."));
900 parse_week (struct data_in *i, long *week)
902 if (!parse_int (i, week))
904 if (*week >= 1 && *week <= 53)
907 dls_error (i, _("Week (%ld) must be between 1 and 53."), *week);
912 parse_wk_delimiter (struct data_in *i)
916 || tolower ((unsigned char) i->s[0]) != 'w'
917 || tolower ((unsigned char) i->s[1]) != 'k')
919 dls_error (i, _("`WK' expected between week and year."));
928 parse_time_delimiter (struct data_in *i)
932 while (have_char (i) && (*i->s == ':' || *i->s == '.'
933 || isspace ((unsigned char) *i->s)))
942 dls_error (i, _("Delimiter expected between fields in time."));
947 parse_hour (struct data_in *i, long *hour)
949 if (!parse_int (i, hour))
954 dls_error (i, _("Hour (%ld) must be positive."), *hour);
959 parse_minute (struct data_in *i, long *minute)
961 if (!parse_int (i, minute))
963 if (*minute >= 0 && *minute <= 59)
966 dls_error (i, _("Minute (%ld) must be between 0 and 59."), *minute);
971 parse_opt_second (struct data_in *i, double *second)
979 && (*i->s == ':' || *i->s == '.' || isspace ((unsigned char) *i->s)))
985 if (!delim || !isdigit ((unsigned char) *i->s))
992 while (have_char (i) && isdigit ((unsigned char) *i->s))
994 if (have_char (i) && *i->s == '.')
996 while (have_char (i) && isdigit ((unsigned char) *i->s))
1000 *second = strtod (buf, NULL);
1006 parse_hour24 (struct data_in *i, long *hour24)
1008 if (!parse_int (i, hour24))
1010 if (*hour24 >= 0 && *hour24 <= 23)
1013 dls_error (i, _("Hour (%ld) must be between 0 and 23."), *hour24);
1019 parse_weekday (struct data_in *i, long *weekday)
1021 static const struct enum_name weekday_names[] =
1023 {"sunday", true, 1},
1025 {"monday", true, 2},
1027 {"tuesday", true, 3},
1029 {"wednesday", true, 4},
1031 {"thursday", true, 5},
1033 {"friday", true, 6},
1035 {"saturday", true, 7},
1041 return parse_enum (i, _("weekday"), weekday_names, weekday);
1045 parse_spaces (struct data_in *i)
1047 skip_whitespace (i);
1052 parse_sign (struct data_in *i, int *sign)
1054 if (!force_have_char (i))
1076 /* Date & time formats. */
1079 calendar_error (void *i_, const char *format, ...)
1081 struct data_in *i = i_;
1084 va_start (args, format);
1085 vdls_error (i, format, args);
1090 ymd_to_ofs (struct data_in *i, int year, int month, int day, double *ofs)
1092 *ofs = calendar_gregorian_to_offset (year, month, day, calendar_error, i);
1093 return *ofs != SYSMIS;
1097 ymd_to_date (struct data_in *i, int year, int month, int day, double *date)
1099 if (ymd_to_ofs (i, year, month, day, date))
1101 *date *= 60. * 60. * 24.;
1109 parse_DATE (struct data_in *i)
1111 long day, month, year;
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));
1124 parse_ADATE (struct data_in *i)
1126 long month, day, year;
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));
1139 parse_EDATE (struct data_in *i)
1141 long month, day, year;
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));
1154 parse_SDATE (struct data_in *i)
1156 long month, day, year;
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));
1169 parse_JDATE (struct data_in *i)
1174 if (!parse_leader (i)
1175 || !parse_julian (i, &julian)
1176 || !parse_trailer (i)
1177 || !ymd_to_ofs (i, julian / 1000, 1, 1, &ofs))
1180 i->v->f = (ofs + julian % 1000 - 1) * 60. * 60. * 24.;
1185 parse_QYR (struct data_in *i)
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));
1198 parse_MOYR (struct data_in *i)
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));
1211 parse_WKYR (struct data_in *i)
1216 if (!parse_leader (i)
1217 || !parse_week (i, &week)
1218 || !parse_wk_delimiter (i)
1219 || !parse_year (i, &year)
1220 || !parse_trailer (i))
1225 if (!ymd_to_ofs (i, year, 1, 1, &ofs))
1230 if (ymd_to_ofs (i, 1583, 1, 1, &ofs))
1235 i->v->f = (ofs + (week - 1) * 7) * 60. * 60. * 24.;
1240 parse_TIME (struct data_in *i)
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))
1255 i->v->f = (hour * 60. * 60. + minute * 60. + second) * sign;
1260 parse_DTIME (struct data_in *i)
1263 long day_count, hour;
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))
1278 i->v->f = (day_count * 60. * 60. * 24.
1286 parse_DATETIME (struct data_in *i)
1288 long day, month, year;
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))
1307 i->v->f += hour24 * 60. * 60. + minute * 60. + second;
1312 parse_WKDAY (struct data_in *i)
1316 if (!parse_leader (i)
1317 || !parse_weekday (i, &weekday)
1318 || !parse_trailer (i))
1326 parse_MONTH (struct data_in *i)
1330 if (!parse_leader (i)
1331 || !parse_month (i, &month)
1332 || !parse_trailer (i))
1339 /* Main dispatcher. */
1342 default_result (struct data_in *i)
1344 const struct fmt_desc *const fmt = &formats[i->format.type];
1346 /* Default to SYSMIS or blanks. */
1347 if (fmt->cat & FCAT_STRING)
1348 memset (i->v->s, ' ', i->format.w);
1350 i->v->f = get_blanks();
1354 data_in (struct data_in *i)
1356 const struct fmt_desc *const fmt = &formats[i->format.type];
1358 assert (check_input_specifier (&i->format, 0));
1360 /* Check that we've got a string to work with. */
1361 if (i->e == i->s || i->format.w <= 0)
1367 i->f2 = i->f1 + (i->e - i->s) - 1;
1369 /* Make sure that the string isn't too long. */
1370 if (i->format.w > fmt->Imax_w)
1372 dls_error (i, _("Field too long (%d characters). Truncated after "
1374 i->format.w, fmt->Imax_w);
1375 i->format.w = fmt->Imax_w;
1378 if (fmt->cat & FCAT_BLANKS_SYSMIS)
1385 if (!isspace ((unsigned char) *cp))
1390 i->v->f = get_blanks();
1397 static bool (*const handlers[FMT_NUMBER_OF_FORMATS])(struct data_in *) =
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,
1410 bool (*handler)(struct data_in *);
1413 handler = handlers[i->format.type];
1414 assert (handler != NULL);
1416 success = handler (i);
1424 /* Utility function. */
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
1430 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1433 di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1434 di->e = line + ((size_t) lc <= len ? lc : len);