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, ...)
45 __attribute__ ((format (printf, 2, 3)));
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);
67 ds_init (NULL, &title, 64);
68 if (!getl_reading_script)
69 ds_concat (&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_value (&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 == '+')
146 decimal = set_decimal;
147 grouping = set_grouping;
151 decimal = set_grouping;
152 grouping = set_decimal;
160 for (; have_char (i); i->s++)
166 /* Make sure that multiplication by 10 will not overflow. */
167 if (num > DBL_MAX * 0.1)
168 /* The value of the digit doesn't matter, since we have already
169 gotten as many digits as can be represented in a `double'.
170 This doesn't necessarily mean the result will overflow.
171 The exponent may reduce it to within range.
173 We just need to record that there was another
174 digit so that we can multiply by 10 later. */
177 num = (num * 10.0) + (*i->s - '0');
179 /* Keep track of the number of digits after the decimal point.
180 If we just divided by 10 here, we would lose precision. */
184 else if (!got_dot && *i->s == decimal)
185 /* Record that we have found the decimal point. */
187 else if ((type != FMT_COMMA && type != FMT_DOT) || *i->s != grouping)
188 /* Any other character terminates the number. */
203 && (tolower (*i->s) == 'e' || tolower (*i->s) == 'd'
204 || (type == FMT_E && (*i->s == '+' || *i->s == '-'))))
206 /* Get the exponent specified after the `e' or `E'. */
211 if (!parse_int (i, &exp))
217 exponent -= i->format.d;
219 if (type == FMT_PCT && have_char (i) && *i->s == '%')
223 dls_error (i, _("Field contents followed by garbage."));
234 /* Multiply NUM by 10 to the EXPONENT power, checking for overflow
239 if (-exponent + got_digit > -(DBL_MIN_10_EXP) + 5
240 || num < DBL_MIN * pow (10.0, (double) -exponent))
242 num *= pow (10.0, (double) exponent);
244 else if (exponent > 0)
246 if (num > DBL_MAX * pow (10.0, (double) -exponent))
248 num *= pow (10.0, (double) exponent);
251 i->v->f = sign * num;
255 /* Return an overflow error. */
256 dls_error (i, _("Overflow in floating-point constant."));
261 /* Return an underflow error. */
262 dls_error (i, _("Underflow in floating-point constant."));
267 /* There was no number. */
268 dls_error (i, _("Field does not form a valid floating-point constant."));
273 /* Returns the integer value of hex digit C. */
277 const char s[] = "0123456789abcdef";
278 const char *cp = strchr (s, tolower ((unsigned char) c));
285 parse_N (struct data_in *i)
287 const unsigned char *cp;
290 for (cp = i->s; cp < i->e; cp++)
294 dls_error (i, _("All characters in field must be digits."));
298 i->v->f = i->v->f * 10.0 + *cp - '0';
302 i->v->f /= pow (10.0, i->format.d);
307 parse_PIBHEX (struct data_in *i)
310 const unsigned char *cp;
315 for (cp = i->s; cp < i->e; cp++)
319 dls_error (i, _("Unrecognized character in field."));
323 n = n * 16.0 + hexit_value (*cp);
331 parse_RBHEX (struct data_in *i)
333 /* Validate input. */
335 if ((i->e - i->s) % 2)
337 dls_error (i, _("Field must have even length."));
342 const unsigned char *cp;
344 for (cp = i->s; cp < i->e; cp++)
347 dls_error (i, _("Field must contain only hex digits."));
357 unsigned char c[sizeof (double)];
363 memset (u.c, 0, sizeof u.c);
364 for (j = 0; j < min ((i->e - i->s) / 2, sizeof u.d); j++)
365 u.c[j] = 16 * hexit_value (i->s[j * 2]) + hexit_value (i->s[j * 2 + 1]);
374 parse_Z (struct data_in *i)
378 /* Warn user that we suck. */
384 msg (MW, _("Quality of zoned decimal (Z) input format code is "
385 "suspect. Check your results three times, report bugs "
391 /* Validate input. */
396 dls_error (i, _("Zoned decimal field contains fewer than 2 "
401 /* Copy sign into buf[0]. */
402 if ((i->e[-1] & 0xc0) != 0xc0)
404 dls_error (i, _("Bad sign byte in zoned decimal number."));
407 buf[0] = (i->e[-1] ^ (i->e[-1] >> 1)) & 0x10 ? '-' : '+';
409 /* Copy digits into buf[1 ... len - 1] and terminate string. */
411 const unsigned char *sp;
414 for (sp = i->s, dp = buf + 1; sp < i->e - 1; sp++, dp++)
417 else if ((*sp & 0xf0) == 0xf0 && (*sp & 0xf) < 10)
418 *dp = (*sp & 0xf) + '0';
421 dls_error (i, _("Format error in zoned decimal number."));
428 /* Parse as number. */
432 i->v->f = strtod ((char *) buf, (char **) &tail);
433 if ((unsigned char *) tail != i->e)
435 dls_error (i, _("Error in syntax of zoned decimal number."));
444 parse_IB (struct data_in *i)
451 /* We want the data to be in big-endian format. If this is a
452 little-endian machine, reverse the byte order. */
453 #ifdef WORDS_BIGENDIAN
456 memcpy (buf, i->s, i->e - i->s);
457 mm_reverse (buf, i->e - i->s);
461 /* If the value is negative, we need to logical-NOT each value
472 for (j = 0; j < i->e - i->s; j++)
473 i->v->f = i->v->f * 256.0 + (p[j] ^ xor);
476 /* If the value is negative, add 1 and set the sign, to complete a
477 two's-complement negation. */
479 i->v->f = -(i->v->f + 1.0);
482 i->v->f /= pow (10.0, i->format.d);
488 parse_PIB (struct data_in *i)
494 for (j = 0; j < i->e - i->s; j++)
495 i->v->f = i->v->f * 256.0 + i->s[j];
497 for (j = i->e - i->s - 1; j >= 0; j--)
498 i->v->f = i->v->f * 256.0 + i->s[j];
502 i->v->f /= pow (10.0, i->format.d);
508 parse_P (struct data_in *i)
510 const unsigned char *cp;
513 for (cp = i->s; cp < i->e - 1; cp++)
515 i->v->f = i->v->f * 10 + (*cp >> 4);
516 i->v->f = i->v->f * 10 + (*cp & 15);
518 i->v->f = i->v->f * 10 + (*cp >> 4);
519 if ((*cp ^ (*cp >> 1)) & 0x10)
523 i->v->f /= pow (10.0, i->format.d);
529 parse_PK (struct data_in *i)
531 const unsigned char *cp;
534 for (cp = i->s; cp < i->e; cp++)
536 i->v->f = i->v->f * 10 + (*cp >> 4);
537 i->v->f = i->v->f * 10 + (*cp & 15);
541 i->v->f /= pow (10.0, i->format.d);
547 parse_RB (struct data_in *i)
552 unsigned char c[sizeof (double)];
556 memset (u.c, 0, sizeof u.c);
557 memcpy (u.c, i->s, min ((int) sizeof (u.c), i->e - i->s));
564 parse_A (struct data_in *i)
566 ptrdiff_t len = i->e - i->s;
568 if (len >= i->format.w)
569 memcpy (i->v->s, i->s, i->format.w);
572 memcpy (i->v->s, i->s, len);
573 memset (i->v->s + len, ' ', i->format.w - len);
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."));
591 const unsigned char *cp;
593 for (cp = i->s; cp < i->e; 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)
645 if (!force_have_char (i))
653 else if (*i->s == '-')
660 if (!isdigit (*i->s))
662 dls_error (i, _("Digit expected in field."));
669 *result = *result * 10 + *i->s++ - '0';
670 if (!have_char (i) || !isdigit (*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 (*i->s)
704 || *i->s == '.' || *i->s == ','))
712 dls_error (i, _("Delimiter expected between fields in date."));
716 /* Formats NUMBER as Roman numerals in ROMAN, or as Arabic numerals if
717 the Roman expansion would be too long. */
719 to_roman (int number, char roman[32])
721 int save_number = number;
725 int value; /* Value corresponding to this digit. */
726 char name; /* Digit name. */
729 static const struct roman_digit roman_tab[7] =
744 assert (32 >= INT_DIGITS + 1);
754 for (i = 0; i < 7; i++)
756 int digit = roman_tab[i].value;
757 while (number >= digit)
762 *cp++ = roman_tab[i].name;
765 for (j = i + 1; j < 7; j++)
767 if (i == 4 && j == 5) /* VX is not a shortened form of V. */
770 digit = roman_tab[i].value - roman_tab[j].value;
771 while (number >= digit)
776 *cp++ = roman_tab[j].name;
777 *cp++ = roman_tab[i].name;
785 sprintf (roman, "%d", save_number);
788 /* Returns true if C is a (lowercase) roman numeral. */
789 #define CHAR_IS_ROMAN(C) \
790 ((C) == 'x' || (C) == 'v' || (C) == 'i')
792 /* Returns the value of a single (lowercase) roman numeral. */
793 #define ROMAN_VALUE(C) \
794 ((C) == 'x' ? 10 : ((C) == 'v' ? 5 : 1))
797 parse_month (struct data_in *i, long *month)
799 if (!force_have_char (i))
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 if (CHAR_IS_ROMAN (tolower (*i->s)))
815 int last = ROMAN_VALUE (tolower (*i->s));
823 if (!have_char || !CHAR_IS_ROMAN (tolower (*i->s)))
830 value = ROMAN_VALUE (tolower (*i->s));
833 else if (value > last)
835 *month += value - last;
845 if (*month < 1 || *month > 12)
849 to_roman (*month, buf);
850 dls_error (i, _("Month (%s) must be between I and XII."), buf);
858 static const char *months[12] =
860 "january", "february", "march", "april", "may", "june",
861 "july", "august", "september", "october", "november", "december",
870 have_char (i) && isalpha (*i->s) && mp < &month_buf[31];
872 *mp++ = tolower (*i->s);
875 if (have_char (i) && isalpha (*i->s))
877 dls_error (i, _("Month name (%s...) is too long."), month_buf);
881 for (j = 0; j < 12; j++)
882 if (lex_id_match (months[j], month_buf))
888 dls_error (i, _("Bad month name (%s)."), month_buf);
894 parse_year (struct data_in *i, long *year)
896 if (!parse_int (i, year))
899 if (*year >= 0 && *year <= 199)
901 if (*year >= 1582 || *year <= 19999)
904 dls_error (i, _("Year (%ld) must be between 1582 and 19999."), *year);
909 parse_trailer (struct data_in *i)
915 dls_error (i, _("Trailing garbage \"%s\" following date."), i->s);
920 parse_julian (struct data_in *i, long *julian)
922 if (!parse_int (i, julian))
926 int day = *julian % 1000;
928 if (day < 1 || day > 366)
930 dls_error (i, _("Julian day (%d) must be between 1 and 366."), day);
936 int year = *julian / 1000;
938 if (year >= 0 && year <= 199)
940 else if (year < 1582 || year > 19999)
942 dls_error (i, _("Year (%d) must be between 1582 and 19999."), year);
951 parse_quarter (struct data_in *i, long *quarter)
953 if (!parse_int (i, quarter))
955 if (*quarter >= 1 && *quarter <= 4)
958 dls_error (i, _("Quarter (%ld) must be between 1 and 4."), *quarter);
963 parse_q_delimiter (struct data_in *i)
966 if (!have_char (i) || tolower (*i->s) != 'q')
968 dls_error (i, _("`Q' expected between quarter and year."));
977 parse_week (struct data_in *i, long *week)
979 if (!parse_int (i, week))
981 if (*week >= 1 && *week <= 53)
984 dls_error (i, _("Week (%ld) must be between 1 and 53."), *week);
989 parse_wk_delimiter (struct data_in *i)
993 || tolower (i->s[0]) != 'w' || tolower (i->s[1]) != 'k')
995 dls_error (i, _("`WK' expected between week and year."));
1004 parse_time_delimiter (struct data_in *i)
1008 while (have_char (i)
1009 && (*i->s == ':' || *i->s == '.' || isspace (*i->s)))
1018 dls_error (i, _("Delimiter expected between fields in time."));
1023 parse_hour (struct data_in *i, long *hour)
1025 if (!parse_int (i, hour))
1030 dls_error (i, _("Hour (%ld) must be positive."), *hour);
1035 parse_minute (struct data_in *i, long *minute)
1037 if (!parse_int (i, minute))
1039 if (*minute >= 0 && *minute <= 59)
1042 dls_error (i, _("Minute (%ld) must be between 0 and 59."), *minute);
1047 parse_opt_second (struct data_in *i, double *second)
1054 while (have_char (i)
1055 && (*i->s == ':' || *i->s == '.' || isspace (*i->s)))
1061 if (!delim || !isdigit (*i->s))
1068 while (have_char (i) && isdigit (*i->s))
1070 if (have_char (i) && *i->s == '.')
1072 while (have_char (i) && isdigit (*i->s))
1076 *second = strtod (buf, NULL);
1082 parse_hour24 (struct data_in *i, long *hour24)
1084 if (!parse_int (i, hour24))
1086 if (*hour24 >= 0 && *hour24 <= 23)
1089 dls_error (i, _("Hour (%ld) must be between 0 and 23."), *hour24);
1095 parse_weekday (struct data_in *i, int *weekday)
1098 #define TUPLE(A,B) \
1101 if (i->s + 1 >= i->e)
1103 dls_error (i, _("Day of the week expected in date value."));
1107 switch (TUPLE (tolower (i->s[0]), tolower (i->s[1])))
1109 case TUPLE ('s', 'u'):
1113 case TUPLE ('m', 'o'):
1117 case TUPLE ('t', 'u'):
1121 case TUPLE ('w', 'e'):
1125 case TUPLE ('t', 'h'):
1129 case TUPLE ('f', 'r'):
1133 case TUPLE ('s', 'a'):
1138 dls_error (i, _("Day of the week expected in date value."));
1142 while (have_char (i) && isalpha (*i->s))
1151 parse_spaces (struct data_in *i)
1153 skip_whitespace (i);
1158 parse_sign (struct data_in *i, int *sign)
1160 if (!force_have_char (i))
1182 /* Date & time formats. */
1185 valid_date (struct data_in *i)
1187 if (i->v->f == SYSMIS)
1189 dls_error (i, _("Date is not in valid range between "
1190 "15 Oct 1582 and 31 Dec 19999."));
1198 parse_DATE (struct data_in *i)
1200 long day, month, year;
1202 if (!parse_leader (i)
1203 || !parse_day (i, &day)
1204 || !parse_date_delimiter (i)
1205 || !parse_month (i, &month)
1206 || !parse_date_delimiter (i)
1207 || !parse_year (i, &year)
1208 || !parse_trailer (i))
1211 i->v->f = calendar_to_julian (year, month, day);
1212 if (!valid_date (i))
1214 i->v->f *= 60. * 60. * 24.;
1220 parse_ADATE (struct data_in *i)
1222 long month, day, year;
1224 if (!parse_leader (i)
1225 || !parse_month (i, &month)
1226 || !parse_date_delimiter (i)
1227 || !parse_day (i, &day)
1228 || !parse_date_delimiter (i)
1229 || !parse_year (i, &year)
1230 || !parse_trailer (i))
1233 i->v->f = calendar_to_julian (year, month, day);
1234 if (!valid_date (i))
1236 i->v->f *= 60. * 60. * 24.;
1242 parse_EDATE (struct data_in *i)
1244 long month, day, year;
1246 if (!parse_leader (i)
1247 || !parse_day (i, &day)
1248 || !parse_date_delimiter (i)
1249 || !parse_month (i, &month)
1250 || !parse_date_delimiter (i)
1251 || !parse_year (i, &year)
1252 || !parse_trailer (i))
1255 i->v->f = calendar_to_julian (year, month, day);
1256 if (!valid_date (i))
1258 i->v->f *= 60. * 60. * 24.;
1264 parse_SDATE (struct data_in *i)
1266 long month, day, year;
1268 if (!parse_leader (i)
1269 || !parse_year (i, &year)
1270 || !parse_date_delimiter (i)
1271 || !parse_month (i, &month)
1272 || !parse_date_delimiter (i)
1273 || !parse_day (i, &day)
1274 || !parse_trailer (i))
1277 i->v->f = calendar_to_julian (year, month, day);
1278 if (!valid_date (i))
1280 i->v->f *= 60. * 60. * 24.;
1286 parse_JDATE (struct data_in *i)
1290 if (!parse_leader (i)
1291 || !parse_julian (i, &julian)
1292 || !parse_trailer (i))
1295 if (julian / 1000 == 1582)
1296 i->v->f = calendar_to_julian (1583, 1, 1) - 365;
1298 i->v->f = calendar_to_julian (julian / 1000, 1, 1);
1302 i->v->f = (i->v->f + julian % 1000 - 1) * 60. * 60. * 24.;
1307 return valid_date (i);
1311 parse_QYR (struct data_in *i)
1315 if (!parse_leader (i)
1316 || !parse_quarter (i, &quarter)
1317 || !parse_q_delimiter (i)
1318 || !parse_year (i, &year)
1319 || !parse_trailer (i))
1322 i->v->f = calendar_to_julian (year, (quarter - 1) * 3 + 1, 1);
1323 if (!valid_date (i))
1325 i->v->f *= 60. * 60. * 24.;
1331 parse_MOYR (struct data_in *i)
1335 if (!parse_leader (i)
1336 || !parse_month (i, &month)
1337 || !parse_date_delimiter (i)
1338 || !parse_year (i, &year)
1339 || !parse_trailer (i))
1342 i->v->f = calendar_to_julian (year, month, 1);
1343 if (!valid_date (i))
1345 i->v->f *= 60. * 60. * 24.;
1351 parse_WKYR (struct data_in *i)
1355 if (!parse_leader (i)
1356 || !parse_week (i, &week)
1357 || !parse_wk_delimiter (i)
1358 || !parse_year (i, &year)
1359 || !parse_trailer (i))
1362 i->v->f = calendar_to_julian (year, 1, 1);
1363 if (!valid_date (i))
1365 i->v->f = (i->v->f + (week - 1) * 7) * 60. * 60. * 24.;
1371 parse_TIME (struct data_in *i)
1377 if (!parse_leader (i)
1378 || !parse_sign (i, &sign)
1379 || !parse_spaces (i)
1380 || !parse_hour (i, &hour)
1381 || !parse_time_delimiter (i)
1382 || !parse_minute (i, &minute)
1383 || !parse_opt_second (i, &second))
1386 i->v->f = hour * 60. * 60. + minute * 60. + second;
1393 parse_DTIME (struct data_in *i)
1396 long day_count, hour;
1400 if (!parse_leader (i)
1401 || !parse_sign (i, &sign)
1402 || !parse_spaces (i)
1403 || !parse_day_count (i, &day_count)
1404 || !parse_time_delimiter (i)
1405 || !parse_hour (i, &hour)
1406 || !parse_time_delimiter (i)
1407 || !parse_minute (i, &minute)
1408 || !parse_opt_second (i, &second))
1411 i->v->f = (day_count * 60. * 60. * 24.
1421 parse_DATETIME (struct data_in *i)
1423 long day, month, year;
1428 if (!parse_leader (i)
1429 || !parse_day (i, &day)
1430 || !parse_date_delimiter (i)
1431 || !parse_month (i, &month)
1432 || !parse_date_delimiter (i)
1433 || !parse_year (i, &year)
1434 || !parse_time_delimiter (i)
1435 || !parse_hour24 (i, &hour24)
1436 || !parse_time_delimiter (i)
1437 || !parse_minute (i, &minute)
1438 || !parse_opt_second (i, &second))
1441 i->v->f = calendar_to_julian (year, month, day);
1442 if (!valid_date (i))
1444 i->v->f = (i->v->f * 60. * 60. * 24.
1445 + hour24 * 60. * 60.
1453 parse_WKDAY (struct data_in *i)
1457 if (!parse_leader (i)
1458 || !parse_weekday (i, &weekday)
1459 || !parse_trailer (i))
1467 parse_MONTH (struct data_in *i)
1471 if (!parse_leader (i)
1472 || !parse_month (i, &month)
1473 || !parse_trailer (i))
1480 /* Main dispatcher. */
1483 default_result (struct data_in *i)
1485 const struct fmt_desc *const fmt = &formats[i->format.type];
1487 /* Default to SYSMIS or blanks. */
1488 if (fmt->cat & FCAT_STRING)
1489 memset (i->v->s, ' ', i->format.w);
1491 i->v->f = set_blanks;
1495 data_in (struct data_in *i)
1497 const struct fmt_desc *const fmt = &formats[i->format.type];
1499 /* Check that we've got a string to work with. */
1500 if (i->e == i->s || i->format.w <= 0)
1506 i->f2 = i->f1 + (i->e - i->s) - 1;
1508 /* Make sure that the string isn't too long. */
1509 if (i->format.w > fmt->Imax_w)
1511 dls_error (i, _("Field too long (%d characters). Truncated after "
1513 i->format.w, fmt->Imax_w);
1514 i->format.w = fmt->Imax_w;
1517 if (fmt->cat & FCAT_BLANKS_SYSMIS)
1519 const unsigned char *cp;
1529 i->v->f = set_blanks;
1536 static int (*const handlers[FMT_NUMBER_OF_FORMATS])(struct data_in *) =
1538 parse_numeric, parse_N, parse_numeric, parse_numeric,
1539 parse_numeric, parse_numeric, parse_numeric,
1540 parse_Z, parse_A, parse_AHEX, parse_IB, parse_P, parse_PIB,
1541 parse_PIBHEX, parse_PK, parse_RB, parse_RBHEX,
1542 NULL, NULL, NULL, NULL, NULL,
1543 parse_DATE, parse_EDATE, parse_SDATE, parse_ADATE, parse_JDATE,
1544 parse_QYR, parse_MOYR, parse_WKYR,
1545 parse_DATETIME, parse_TIME, parse_DTIME,
1546 parse_WKDAY, parse_MONTH,
1549 int (*handler)(struct data_in *);
1552 handler = handlers[i->format.type];
1553 assert (handler != NULL);
1555 success = handler (i);
1563 /* Utility function. */
1565 /* Sets DI->{s,e} appropriately given that LINE has length LEN and the
1566 field starts at one-based column FC and ends at one-based column
1569 data_in_finite_line (struct data_in *di, const char *line, size_t len,
1572 di->s = line + ((size_t) fc <= len ? fc - 1 : len);
1573 di->e = line + ((size_t) lc <= len ? lc : len);