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., 59 Temple Place - Suite 330, Boston, MA
31 #include "julcal/julcal.h"
39 #include "debug-print.h"
42 /* Specialized error routine. */
44 static void dls_error (const struct data_in *, const char *format, ...)
48 dls_error (const struct data_in *i, const char *format, ...)
52 if (i->flags & DI_IGNORE_ERROR)
58 va_start (args, format);
59 snprintf (buf, 1024, format, args);
68 if (!getl_reading_script)
69 ds_puts (&title, _("data-file error: "));
71 ds_printf (&title, _("(column %d"), i->f1);
73 ds_printf (&title, _("(columns %d-%d"), i->f1, i->f2);
74 ds_printf (&title, _(", field type %s) "), fmt_to_string (&i->format));
77 err_location (&e.where);
78 e.title = ds_c_str (&title);
87 /* Excludes leading and trailing whitespace from I by adjusting
90 trim_whitespace (struct data_in *i)
92 while (i->s < i->e && isspace (i->s[0]))
95 while (i->s < i->e && isspace (i->e[-1]))
99 /* Returns nonzero if we're not at the end of the string being
102 have_char (struct data_in *i)
107 /* Format parsers. */
109 static int parse_int (struct data_in *i, long *result);
111 /* This function is based on strtod() from the GNU C library. */
113 parse_numeric (struct data_in *i)
115 short int sign; /* +1 or -1. */
116 double num; /* The number so far. */
118 int got_dot; /* Found a decimal point. */
119 int got_digit; /* Count of digits. */
121 int decimal; /* Decimal point character. */
122 int grouping; /* Grouping character. */
124 long int exponent; /* Number's exponent. */
125 int type; /* Usually same as i->format.type. */
129 type = i->format.type;
130 if (type == FMT_DOLLAR && have_char (i) && *i->s == '$')
139 sign = *i->s == '-' ? -1 : 1;
140 if (*i->s == '-' || *i->s == '+')
148 decimal = get_decimal();
149 grouping = get_grouping();
153 decimal = get_grouping();
154 grouping = get_decimal();
162 for (; have_char (i); i->s++)
168 /* Make sure that multiplication by 10 will not overflow. */
169 if (num > DBL_MAX * 0.1)
170 /* The value of the digit doesn't matter, since we have already
171 gotten as many digits as can be represented in a `double'.
172 This doesn't necessarily mean the result will overflow.
173 The exponent may reduce it to within range.
175 We just need to record that there was another
176 digit so that we can multiply by 10 later. */
179 num = (num * 10.0) + (*i->s - '0');
181 /* Keep track of the number of digits after the decimal point.
182 If we just divided by 10 here, we would lose precision. */
186 else if (!got_dot && *i->s == decimal)
187 /* Record that we have found the decimal point. */
189 else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
190 /* Any other character terminates the number. */
205 && (tolower (*i->s) == 'e' || tolower (*i->s) == 'd'
206 || (type == FMT_E && (*i->s == '+' || *i->s == '-'))))
208 /* Get the exponent specified after the `e' or `E'. */
213 if (!parse_int (i, &exp))
219 exponent -= i->format.d;
221 if (type == FMT_PCT && have_char (i) && *i->s == '%')
225 dls_error (i, _("Field contents followed by garbage."));
236 /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
241 if (-exponent + got_digit > -(DBL_MIN_10_EXP) + 5
242 || num < DBL_MIN * pow (10.0, (double) -exponent))
244 num *= pow (10.0, (double) exponent);
246 else if (exponent > 0)
248 if (num > DBL_MAX * pow (10.0, (double) -exponent))
250 num *= pow (10.0, (double) exponent);
253 i->v->f = sign * num;
257 /* Return an overflow error. */
258 dls_error (i, _("Overflow in floating-point constant."));
263 /* Return an underflow error. */
264 dls_error (i, _("Underflow in floating-point constant."));
269 /* There was no number. */
270 dls_error (i, _("Field does not form a valid floating-point constant."));
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)
289 const unsigned char *cp;
292 for (cp = i->s; cp < i->e; cp++)
296 dls_error (i, _("All characters in field must be digits."));
300 i->v->f = i->v->f * 10.0 + *cp - '0';
304 i->v->f /= pow (10.0, i->format.d);
309 parse_PIBHEX (struct data_in *i)
312 const unsigned char *cp;
317 for (cp = i->s; cp < i->e; 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."));
344 const unsigned char *cp;
346 for (cp = i->s; cp < i->e; 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)
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. */
414 const unsigned char *sp;
417 for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
420 else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
421 *dp = (*sp & 0xf) + '0';
424 dls_error (i, _("Format error in zoned decimal number."));
431 /* Parse as number. */
435 i->v->f = strtod ((char *) buf, (char **) &tail);
436 if ((unsigned char *) tail != i->e)
438 dls_error (i, _("Error in syntax of zoned decimal number."));
447 parse_IB (struct data_in *i)
454 /* We want the data to be in big-endian format. If this is a
455 little-endian machine, reverse the byte order. */
456 #ifdef WORDS_BIGENDIAN
459 memcpy (buf, i->s, i->e - i->s);
460 mm_reverse (buf, i->e - i->s);
464 /* If the value is negative, we need to logical-NOT each value
475 for (j = 0; j < i->e - i->s; j++)
476 i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
479 /* If the value is negative, add 1 and set the sign, to complete a
480 two's-complement negation. */
482 i->v->f = -(i->v->f + 1.0);
485 i->v->f /= pow (10.0, i->format.d);
491 parse_PIB (struct data_in *i)
497 for (j = 0; j < i->e - i->s; j++)
498 i->v->f = i->v->f * 256.0 + i->s[j];
500 for (j = i->e - i->s - 1; j >= 0; j--)
501 i->v->f = i->v->f * 256.0 + i->s[j];
505 i->v->f /= pow (10.0, i->format.d);
511 parse_P (struct data_in *i)
513 const unsigned char *cp;
516 for (cp = i->s; cp < i->e - 1; cp++)
518 i->v->f = i->v->f * 10 + (*cp >> 4);
519 i->v->f = i->v->f * 10 + (*cp & 15);
521 i->v->f = i->v->f * 10 + (*cp >> 4);
522 if ((*cp ^ (*cp >> 1)) & 0x10)
526 i->v->f /= pow (10.0, i->format.d);
532 parse_PK (struct data_in *i)
534 const unsigned char *cp;
537 for (cp = i->s; cp < i->e; cp++)
539 i->v->f = i->v->f * 10 + (*cp >> 4);
540 i->v->f = i->v->f * 10 + (*cp & 15);
544 i->v->f /= pow (10.0, i->format.d);
550 parse_RB (struct data_in *i)
555 unsigned char c[sizeof (double)];
559 memset (u.c, 0, sizeof u.c);
560 memcpy (u.c, i->s, min ((int) sizeof (u.c), i->e - i->s));
567 parse_A (struct data_in *i)
569 ptrdiff_t len = i->e - i->s;
571 if (len >= i->format.w)
572 memcpy (i->v->s, i->s, i->format.w);
575 memcpy (i->v->s, i->s, len);
576 memset (i->v->s + len, ' ', i->format.w - len);
583 parse_AHEX (struct data_in *i)
585 /* Validate input. */
587 if ((i->e - i->s) % 2)
589 dls_error (i, _("Field must have even length."));
594 const unsigned char *cp;
596 for (cp = i->s; cp < i->e; cp++)
599 dls_error (i, _("Field must contain only hex digits."));
608 for (j = 0; j < min (i->e - i->s, i->format.w); j += 2)
609 i->v->s[j / 2] = hexit_value (i->s[j]) * 16 + hexit_value (i->s[j + 1]);
610 memset (i->v->s + (i->e - i->s) / 2, ' ', (i->format.w - (i->e - i->s)) / 2);
616 /* Date & time format components. */
618 /* Advances *CP past any whitespace characters. */
620 skip_whitespace (struct data_in *i)
622 while (isspace ((unsigned char) *i->s))
627 parse_leader (struct data_in *i)
634 force_have_char (struct data_in *i)
639 dls_error (i, _("Unexpected end of field."));
644 parse_int (struct data_in *i, long *result)
648 if (!force_have_char (i))
656 else if (*i->s == '-')
663 if (!isdigit (*i->s))
665 dls_error (i, _("Digit expected in field."));
672 *result = *result * 10 + *i->s++ - '0';
673 if (!have_char (i) || !isdigit (*i->s))
683 parse_day (struct data_in *i, long *day)
685 if (!parse_int (i, day))
687 if (*day >= 1 && *day <= 31)
690 dls_error (i, _("Day (%ld) must be between 1 and 31."), *day);
695 parse_day_count (struct data_in *i, long *day_count)
697 return parse_int (i, day_count);
701 parse_date_delimiter (struct data_in *i)
706 && (*i->s == '-' || *i->s == '/' || isspace (*i->s)
707 || *i->s == '.' || *i->s == ','))
715 dls_error (i, _("Delimiter expected between fields in date."));
719 /* Formats NUMBER as Roman numerals in ROMAN, or as Arabic numerals if
720 the Roman expansion would be too long. */
722 to_roman (int number, char roman[32])
724 int save_number = number;
728 int value; /* Value corresponding to this digit. */
729 char name; /* Digit name. */
732 static const struct roman_digit roman_tab[7] =
747 assert (32 >= INT_DIGITS + 1);
757 for (i = 0; i < 7; i++)
759 int digit = roman_tab[i].value;
760 while (number >= digit)
765 *cp++ = roman_tab[i].name;
768 for (j = i + 1; j < 7; j++)
770 if (i == 4 && j == 5) /* VX is not a shortened form of V. */
773 digit = roman_tab[i].value - roman_tab[j].value;
774 while (number >= digit)
779 *cp++ = roman_tab[j].name;
780 *cp++ = roman_tab[i].name;
788 sprintf (roman, "%d", save_number);
791 /* Returns true if C is a (lowercase) roman numeral. */
792 #define CHAR_IS_ROMAN(C) \
793 ((C) == 'x' || (C) == 'v' || (C) == 'i')
795 /* Returns the value of a single (lowercase) roman numeral. */
796 #define ROMAN_VALUE(C) \
797 ((C) == 'x' ? 10 : ((C) == 'v' ? 5 : 1))
800 parse_month (struct data_in *i, long *month)
802 if (!force_have_char (i))
807 if (!parse_int (i, month))
809 if (*month >= 1 && *month <= 12)
812 dls_error (i, _("Month (%ld) must be between 1 and 12."), *month);
816 if (CHAR_IS_ROMAN (tolower (*i->s)))
818 int last = ROMAN_VALUE (tolower (*i->s));
826 if (!have_char || !CHAR_IS_ROMAN (tolower (*i->s)))
833 value = ROMAN_VALUE (tolower (*i->s));
836 else if (value > last)
838 *month += value - last;
848 if (*month < 1 || *month > 12)
852 to_roman (*month, buf);
853 dls_error (i, _("Month (%s) must be between I and XII."), buf);
861 static const char *months[12] =
863 "january", "february", "march", "april", "may", "june",
864 "july", "august", "september", "october", "november", "december",
873 have_char (i) && isalpha (*i->s) && mp < &month_buf[31];
875 *mp++ = tolower (*i->s);
878 if (have_char (i) && isalpha (*i->s))
880 dls_error (i, _("Month name (%s...) is too long."), month_buf);
884 for (j = 0; j < 12; j++)
885 if (lex_id_match (months[j], month_buf))
891 dls_error (i, _("Bad month name (%s)."), month_buf);
897 parse_year (struct data_in *i, long *year)
899 if (!parse_int (i, year))
902 if (*year >= 0 && *year <= 199)
904 if (*year >= 1582 || *year <= 19999)
907 dls_error (i, _("Year (%ld) must be between 1582 and 19999."), *year);
912 parse_trailer (struct data_in *i)
918 dls_error (i, _("Trailing garbage \"%s\" following date."), i->s);
923 parse_julian (struct data_in *i, long *julian)
925 if (!parse_int (i, julian))
929 int day = *julian % 1000;
931 if (day < 1 || day > 366)
933 dls_error (i, _("Julian day (%d) must be between 1 and 366."), day);
939 int year = *julian / 1000;
941 if (year >= 0 && year <= 199)
943 else if (year < 1582 || year > 19999)
945 dls_error (i, _("Year (%d) must be between 1582 and 19999."), year);
954 parse_quarter (struct data_in *i, long *quarter)
956 if (!parse_int (i, quarter))
958 if (*quarter >= 1 && *quarter <= 4)
961 dls_error (i, _("Quarter (%ld) must be between 1 and 4."), *quarter);
966 parse_q_delimiter (struct data_in *i)
969 if (!have_char (i) || tolower (*i->s) != 'q')
971 dls_error (i, _("`Q' expected between quarter and year."));
980 parse_week (struct data_in *i, long *week)
982 if (!parse_int (i, week))
984 if (*week >= 1 && *week <= 53)
987 dls_error (i, _("Week (%ld) must be between 1 and 53."), *week);
992 parse_wk_delimiter (struct data_in *i)
996 || tolower (i->s[0]) != 'w' || tolower (i->s[1]) != 'k')
998 dls_error (i, _("`WK' expected between week and year."));
1002 skip_whitespace (i);
1007 parse_time_delimiter (struct data_in *i)
1011 while (have_char (i)
1012 && (*i->s == ':' || *i->s == '.' || isspace (*i->s)))
1021 dls_error (i, _("Delimiter expected between fields in time."));
1026 parse_hour (struct data_in *i, long *hour)
1028 if (!parse_int (i, hour))
1033 dls_error (i, _("Hour (%ld) must be positive."), *hour);
1038 parse_minute (struct data_in *i, long *minute)
1040 if (!parse_int (i, minute))
1042 if (*minute >= 0 && *minute <= 59)
1045 dls_error (i, _("Minute (%ld) must be between 0 and 59."), *minute);
1050 parse_opt_second (struct data_in *i, double *second)
1057 while (have_char (i)
1058 && (*i->s == ':' || *i->s == '.' || isspace (*i->s)))
1064 if (!delim || !isdigit (*i->s))
1071 while (have_char (i) && isdigit (*i->s))
1073 if (have_char (i) && *i->s == '.')
1075 while (have_char (i) && isdigit (*i->s))
1079 *second = strtod (buf, NULL);
1085 parse_hour24 (struct data_in *i, long *hour24)
1087 if (!parse_int (i, hour24))
1089 if (*hour24 >= 0 && *hour24 <= 23)
1092 dls_error (i, _("Hour (%ld) must be between 0 and 23."), *hour24);
1098 parse_weekday (struct data_in *i, int *weekday)
1101 #define TUPLE(A,B) \
1104 if (i->s + 1 >= i->e)
1106 dls_error (i, _("Day of the week expected in date value."));
1110 switch (TUPLE (tolower (i->s[0]), tolower (i->s[1])))
1112 case TUPLE ('s', 'u'):
1116 case TUPLE ('m', 'o'):
1120 case TUPLE ('t', 'u'):
1124 case TUPLE ('w', 'e'):
1128 case TUPLE ('t', 'h'):
1132 case TUPLE ('f', 'r'):
1136 case TUPLE ('s', 'a'):
1141 dls_error (i, _("Day of the week expected in date value."));
1145 while (have_char (i) && isalpha (*i->s))
1154 parse_spaces (struct data_in *i)
1156 skip_whitespace (i);
1161 parse_sign (struct data_in *i, int *sign)
1163 if (!force_have_char (i))
1185 /* Date & time formats. */
1188 valid_date (struct data_in *i)
1190 if (i->v->f == SYSMIS)
1192 dls_error (i, _("Date is not in valid range between "
1193 "15 Oct 1582 and 31 Dec 19999."));
1201 parse_DATE (struct data_in *i)
1203 long day, month, year;
1205 if (!parse_leader (i)
1206 || !parse_day (i, &day)
1207 || !parse_date_delimiter (i)
1208 || !parse_month (i, &month)
1209 || !parse_date_delimiter (i)
1210 || !parse_year (i, &year)
1211 || !parse_trailer (i))
1214 i->v->f = calendar_to_julian (year, month, day);
1215 if (!valid_date (i))
1217 i->v->f *= 60. * 60. * 24.;
1223 parse_ADATE (struct data_in *i)
1225 long month, day, year;
1227 if (!parse_leader (i)
1228 || !parse_month (i, &month)
1229 || !parse_date_delimiter (i)
1230 || !parse_day (i, &day)
1231 || !parse_date_delimiter (i)
1232 || !parse_year (i, &year)
1233 || !parse_trailer (i))
1236 i->v->f = calendar_to_julian (year, month, day);
1237 if (!valid_date (i))
1239 i->v->f *= 60. * 60. * 24.;
1245 parse_EDATE (struct data_in *i)
1247 long month, day, year;
1249 if (!parse_leader (i)
1250 || !parse_day (i, &day)
1251 || !parse_date_delimiter (i)
1252 || !parse_month (i, &month)
1253 || !parse_date_delimiter (i)
1254 || !parse_year (i, &year)
1255 || !parse_trailer (i))
1258 i->v->f = calendar_to_julian (year, month, day);
1259 if (!valid_date (i))
1261 i->v->f *= 60. * 60. * 24.;
1267 parse_SDATE (struct data_in *i)
1269 long month, day, year;
1271 if (!parse_leader (i)
1272 || !parse_year (i, &year)
1273 || !parse_date_delimiter (i)
1274 || !parse_month (i, &month)
1275 || !parse_date_delimiter (i)
1276 || !parse_day (i, &day)
1277 || !parse_trailer (i))
1280 i->v->f = calendar_to_julian (year, month, day);
1281 if (!valid_date (i))
1283 i->v->f *= 60. * 60. * 24.;
1289 parse_JDATE (struct data_in *i)
1293 if (!parse_leader (i)
1294 || !parse_julian (i, &julian)
1295 || !parse_trailer (i))
1298 if (julian / 1000 == 1582)
1299 i->v->f = calendar_to_julian (1583, 1, 1) - 365;
1301 i->v->f = calendar_to_julian (julian / 1000, 1, 1);
1305 i->v->f = (i->v->f + julian % 1000 - 1) * 60. * 60. * 24.;
1310 return valid_date (i);
1314 parse_QYR (struct data_in *i)
1318 if (!parse_leader (i)
1319 || !parse_quarter (i, &quarter)
1320 || !parse_q_delimiter (i)
1321 || !parse_year (i, &year)
1322 || !parse_trailer (i))
1325 i->v->f = calendar_to_julian (year, (quarter - 1) * 3 + 1, 1);
1326 if (!valid_date (i))
1328 i->v->f *= 60. * 60. * 24.;
1334 parse_MOYR (struct data_in *i)
1338 if (!parse_leader (i)
1339 || !parse_month (i, &month)
1340 || !parse_date_delimiter (i)
1341 || !parse_year (i, &year)
1342 || !parse_trailer (i))
1345 i->v->f = calendar_to_julian (year, month, 1);
1346 if (!valid_date (i))
1348 i->v->f *= 60. * 60. * 24.;
1354 parse_WKYR (struct data_in *i)
1358 if (!parse_leader (i)
1359 || !parse_week (i, &week)
1360 || !parse_wk_delimiter (i)
1361 || !parse_year (i, &year)
1362 || !parse_trailer (i))
1365 i->v->f = calendar_to_julian (year, 1, 1);
1366 if (!valid_date (i))
1368 i->v->f = (i->v->f + (week - 1) * 7) * 60. * 60. * 24.;
1374 parse_TIME (struct data_in *i)
1380 if (!parse_leader (i)
1381 || !parse_sign (i, &sign)
1382 || !parse_spaces (i)
1383 || !parse_hour (i, &hour)
1384 || !parse_time_delimiter (i)
1385 || !parse_minute (i, &minute)
1386 || !parse_opt_second (i, &second))
1389 i->v->f = hour * 60. * 60. + minute * 60. + second;
1396 parse_DTIME (struct data_in *i)
1399 long day_count, hour;
1403 if (!parse_leader (i)
1404 || !parse_sign (i, &sign)
1405 || !parse_spaces (i)
1406 || !parse_day_count (i, &day_count)
1407 || !parse_time_delimiter (i)
1408 || !parse_hour (i, &hour)
1409 || !parse_time_delimiter (i)
1410 || !parse_minute (i, &minute)
1411 || !parse_opt_second (i, &second))
1414 i->v->f = (day_count * 60. * 60. * 24.
1424 parse_DATETIME (struct data_in *i)
1426 long day, month, year;
1431 if (!parse_leader (i)
1432 || !parse_day (i, &day)
1433 || !parse_date_delimiter (i)
1434 || !parse_month (i, &month)
1435 || !parse_date_delimiter (i)
1436 || !parse_year (i, &year)
1437 || !parse_time_delimiter (i)
1438 || !parse_hour24 (i, &hour24)
1439 || !parse_time_delimiter (i)
1440 || !parse_minute (i, &minute)
1441 || !parse_opt_second (i, &second))
1444 i->v->f = calendar_to_julian (year, month, day);
1445 if (!valid_date (i))
1447 i->v->f = (i->v->f * 60. * 60. * 24.
1448 + hour24 * 60. * 60.
1456 parse_WKDAY (struct data_in *i)
1460 if (!parse_leader (i)
1461 || !parse_weekday (i, &weekday)
1462 || !parse_trailer (i))
1470 parse_MONTH (struct data_in *i)
1474 if (!parse_leader (i)
1475 || !parse_month (i, &month)
1476 || !parse_trailer (i))
1483 /* Main dispatcher. */
1486 default_result (struct data_in *i)
1488 const struct fmt_desc *const fmt = &formats[i->format.type];
1490 /* Default to SYSMIS or blanks. */
1491 if (fmt->cat & FCAT_STRING)
1492 memset (i->v->s, ' ', i->format.w);
1494 i->v->f = get_blanks();
1498 data_in (struct data_in *i)
1500 const struct fmt_desc *const fmt = &formats[i->format.type];
1502 /* Check that we've got a string to work with. */
1503 if (i->e == i->s || i->format.w <= 0)
1509 i->f2 = i->f1 + (i->e - i->s) - 1;
1511 /* Make sure that the string isn't too long. */
1512 if (i->format.w > fmt->Imax_w)
1514 dls_error (i, _("Field too long (%d characters). Truncated after "
1516 i->format.w, fmt->Imax_w);
1517 i->format.w = fmt->Imax_w;
1520 if (fmt->cat & FCAT_BLANKS_SYSMIS)
1522 const unsigned char *cp;
1532 i->v->f = get_blanks();
1539 static int (*const handlers[FMT_NUMBER_OF_FORMATS])(struct data_in *) =
1541 parse_numeric, parse_N, parse_numeric, parse_numeric,
1542 parse_numeric, parse_numeric, parse_numeric,
1543 parse_Z, parse_A, parse_AHEX, parse_IB, parse_P, parse_PIB,
1544 parse_PIBHEX, parse_PK, parse_RB, parse_RBHEX,
1545 NULL, NULL, NULL, NULL, NULL,
1546 parse_DATE, parse_EDATE, parse_SDATE, parse_ADATE, parse_JDATE,
1547 parse_QYR, parse_MOYR, parse_WKYR,
1548 parse_DATETIME, parse_TIME, parse_DTIME,
1549 parse_WKDAY, parse_MONTH,
1552 int (*handler)(struct data_in *);
1555 handler = handlers[i->format.type];
1556 assert (handler != NULL);
1558 success = handler (i);
1566 /* Utility function. */
1568 /* Sets DI->{s,e} appropriately given that LINE has length LEN and the
1569 field starts at one-based column FC and ends at one-based column
1572 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1575 di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1576 di->e = line + ((size_t) lc <= len ? lc : len);