formats, n_formats);
else if (lex_match (lexer, T_LPAREN))
{
- size_t n_assignments;
- size_t i;
-
+ int start_ofs = lex_ofs (lexer);
if (!fixed_parse_fortran (lexer, pool, use, formats, n_formats))
return false;
+ int end_ofs = lex_ofs (lexer) - 1;
- n_assignments = 0;
- for (i = 0; i < *n_formats; i++)
+ size_t n_assignments = 0;
+ for (size_t i = 0; i < *n_formats; i++)
n_assignments += (*formats)[i].type < FMT_NUMBER_OF_FORMATS;
if (n_assignments != n_vars)
{
- msg (SE, _("Number of variables specified (%zu) "
- "differs from number of variable formats (%zu)."),
- n_vars, n_assignments);
+ lex_ofs_error (lexer, start_ofs, end_ofs,
+ _("Number of variables specified (%zu) "
+ "differs from number of variable formats (%zu)."),
+ n_vars, n_assignments);
return false;
}
}
else
{
- msg (SE, _("SPSS-like or Fortran-like format "
- "specification expected after variable names."));
+ lex_error (lexer, _("SPSS-like or Fortran-like format "
+ "specification expected after variable names."));
return false;
}
}
enum fmt_use use,
struct fmt_spec **formats, size_t *n_formats)
{
- struct fmt_spec format;
- int fc, lc;
- size_t i;
+ int start_ofs = lex_ofs (lexer);
+ int fc, lc;
if (!parse_column_range (lexer, 1, &fc, &lc, NULL))
return false;
/* Divide columns evenly. */
- format.w = (lc - fc + 1) / n_vars;
+ int w = (lc - fc + 1) / n_vars;
if ((lc - fc + 1) % n_vars)
{
- msg (SE, _("The %d columns %d-%d "
- "can't be evenly divided into %zu fields."),
- lc - fc + 1, fc, lc, n_vars);
+ lex_ofs_error (lexer, start_ofs, lex_ofs (lexer) - 1,
+ _("The %d columns %d-%d "
+ "can't be evenly divided into %zu fields."),
+ lc - fc + 1, fc, lc, n_vars);
return false;
}
/* Format specifier. */
+ enum fmt_type type;
+ int d;
if (lex_match (lexer, T_LPAREN))
{
/* Get format type. */
if (lex_token (lexer) == T_ID)
{
- if (!parse_format_specifier_name (lexer, &format.type))
+ if (!parse_format_specifier_name (lexer, &type))
return false;
lex_match (lexer, T_COMMA);
}
else
- format.type = FMT_F;
+ type = FMT_F;
/* Get decimal places. */
if (lex_is_integer (lexer))
{
- format.d = lex_integer (lexer);
+ d = lex_integer (lexer);
lex_get (lexer);
}
else
- format.d = 0;
+ d = 0;
if (!lex_force_match (lexer, T_RPAREN))
return false;
}
else
{
- format.type = FMT_F;
- format.d = 0;
+ type = FMT_F;
+ d = 0;
+ }
+ int end_ofs = lex_ofs (lexer) - 1;
+
+ struct fmt_spec format = { .type = type, .w = w, .d = d };
+ char *error = fmt_check__ (&format, use);
+ if (error)
+ {
+ lex_ofs_error (lexer, start_ofs, end_ofs, "%s", error);
+ free (error);
+ return false;
}
- if (!fmt_check (&format, use))
- return false;
*formats = pool_nalloc (pool, n_vars + 1, sizeof **formats);
*n_formats = n_vars + 1;
(*formats)[0].type = (enum fmt_type) PRS_TYPE_T;
(*formats)[0].w = fc;
- for (i = 1; i <= n_vars; i++)
+ for (size_t i = 1; i <= n_vars; i++)
(*formats)[i] = format;
return true;
}
f.type = (enum fmt_type) PRS_TYPE_NEW_REC;
else
{
+ int ofs = lex_ofs (lexer);
char type[FMT_TYPE_LEN_MAX + 1];
-
if (!parse_abstract_format_specifier (lexer, type, &f.w, &f.d))
return false;
{
if (!fmt_from_name (type, &f.type))
{
- msg (SE, _("Unknown format type `%s'."), type);
+ lex_ofs_error (lexer, ofs, ofs,
+ _("Unknown format type `%s'."), type);
+ return false;
+ }
+ char *error = fmt_check__ (&f, use);
+ if (error)
+ {
+ lex_ofs_error (lexer, ofs, ofs, "%s", error);
+ free (error);
return false;
}
- if (!fmt_check (&f, use))
- return false;
}
}
}
}
static bool
-parse_column__ (int value, int base, int *column)
+parse_column__ (struct lexer *lexer, bool negative, int base, int *column)
{
assert (base == 0 || base == 1);
+
+ if (!lex_force_int (lexer))
+ return false;
+ long int value = lex_integer (lexer);
+ if (negative)
+ value = -value;
+ lex_get (lexer);
+
*column = value - base + 1;
if (*column < 1)
{
if (base == 1)
- msg (SE, _("Column positions for fields must be positive."));
+ lex_next_error (lexer, -1, -1,
+ _("Column positions for fields must be positive."));
else
- msg (SE, _("Column positions for fields must not be negative."));
+ lex_next_error (lexer, -1, -1,
+ _("Column positions for fields must not be negative."));
return false;
}
return true;
bool
parse_column (struct lexer *lexer, int base, int *column)
{
- assert (base == 0 || base == 1);
-
- if (!lex_force_int (lexer)
- || !parse_column__ (lex_integer (lexer), base, column))
- return false;
-
- lex_get (lexer);
- return true;
+ return parse_column__ (lexer, false, base, column);
}
/* Parse a column or a range of columns, specified as a single
int *first_column, int *last_column,
bool *range_specified)
{
+ int start_ofs = lex_ofs (lexer);
+
/* First column. */
- if (!lex_force_int (lexer)
- || !parse_column__ (lex_integer (lexer), base, first_column))
+ if (!parse_column__ (lexer, false, base, first_column))
return false;
- lex_get (lexer);
/* Last column. */
if (lex_is_integer (lexer) && lex_integer (lexer) < 0)
{
- if (!parse_column__ (-lex_integer (lexer), base, last_column))
+ if (!parse_column__ (lexer, true, base, last_column))
return false;
- lex_get (lexer);
if (*last_column < *first_column)
{
- msg (SE, _("The ending column for a field must be "
- "greater than the starting column."));
+ lex_ofs_error (lexer, start_ofs, lex_ofs (lexer) - 1,
+ _("The ending column for a field must be "
+ "greater than the starting column."));
return false;
}