Files
bison/src/location.c
Joel E. Denny 3fc65ead4d Provide warn_at, complain_at, and fatal_at function callbacks to the
skeletons, and use this for %code qualifier complaints.
* data/bison.m4 (b4_error_at): New, invoked by...
(b4_warn_at, b4_complain_at, b4_fatal_at): ... these new macros to wrap
the skeleton scanner's new @warn_at(...@), @complain_at(...@), and
@fatal_at(...@) directives.
(b4_check_percent_code_qualifiers): Rewrite to expect locations for
qualifiers in b4_used_percent_code_qualifiers and to use
b4_complain_at.
* src/location.c, src/location.h (boundary_set_from_string): New global
function.
* src/muscle_tab.c, src/muscle_tab.h (muscle_boundary_grow): New global
function.
* src/parse-gram.y (grammar_declaration): Add locations for qualifiers
to b4_used_percent_code_qualifiers.
* src/scan-skel.l (fail_for_at_directive_too_few_args): New static
function.
(AT_DIRECTIVE_ARGC_MAX): Increase for boundary arguments.
(lineno): Rename to...
(out_lineno): ... this so I don't misunderstand it again.
(SC_AT_DIRECTIVE_SKIP_WS): Don't increment out_lineno for newlines
here; these newlines are in the input but not the output file.
(SC_AT_DIRECTIVE_ARG): Likewise.  Extract directive execution to...
(at_directive_perform): ... this new static function, and add handling
of new @warn_at(...@), @complain_at(...@), and @fatal_at(...@)
directives.
* tests/input.at (Reject bad %code qualifiers): Update test output with
locations and extend.

* tests/output.at (Output file name: [, Output file name: ]): Remove
bogus comment about these tests failing.
2007-01-07 03:19:21 +00:00

135 lines
3.6 KiB
C

/* Locations for Bison
Copyright (C) 2002, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
Bison is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bison is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bison; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <config.h>
#include "system.h"
#include <mbswidth.h>
#include <quotearg.h>
#include "complain.h"
#include "location.h"
location const empty_location = EMPTY_LOCATION_INIT;
/* If BUF is null, add BUFSIZE (which in this case must be less than
INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
COLUMN. If an overflow occurs, or might occur but is undetectable,
return INT_MAX. Assume COLUMN is nonnegative. */
static inline int
add_column_width (int column, char const *buf, size_t bufsize)
{
size_t width;
unsigned int remaining_columns = INT_MAX - column;
if (buf)
{
if (INT_MAX / 2 <= bufsize)
return INT_MAX;
width = mbsnwidth (buf, bufsize, 0);
}
else
width = bufsize;
return width <= remaining_columns ? column + width : INT_MAX;
}
/* Set *LOC and adjust scanner cursor to account for token TOKEN of
size SIZE. */
void
location_compute (location *loc, boundary *cur, char const *token, size_t size)
{
int line = cur->line;
int column = cur->column;
char const *p0 = token;
char const *p = token;
char const *lim = token + size;
loc->start = *cur;
for (p = token; p < lim; p++)
switch (*p)
{
case '\n':
line += line < INT_MAX;
column = 1;
p0 = p + 1;
break;
case '\t':
column = add_column_width (column, p0, p - p0);
column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
p0 = p + 1;
break;
default:
break;
}
cur->line = line;
cur->column = column = add_column_width (column, p0, p - p0);
loc->end = *cur;
if (line == INT_MAX && loc->start.line != INT_MAX)
warn_at (*loc, _("line number overflow"));
if (column == INT_MAX && loc->start.column != INT_MAX)
warn_at (*loc, _("column number overflow"));
}
/* Output to OUT the location LOC.
Warning: it uses quotearg's slot 3. */
void
location_print (FILE *out, location loc)
{
int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
fprintf (out, "%s:%d.%d",
quotearg_n_style (3, escape_quoting_style, loc.start.file),
loc.start.line, loc.start.column);
if (loc.start.file != loc.end.file)
fprintf (out, "-%s:%d.%d",
quotearg_n_style (3, escape_quoting_style, loc.end.file),
loc.end.line, end_col);
else if (loc.start.line < loc.end.line)
fprintf (out, "-%d.%d", loc.end.line, end_col);
else if (loc.start.column < end_col)
fprintf (out, "-%d", end_col);
}
void
boundary_set_from_string (boundary *bound, char *loc_str)
{
/* Must search in reverse since the file name field may
* contain `.' or `:'. */
char *delim = strrchr (loc_str, '.');
aver (delim);
*delim = '\0';
bound->column = atoi (delim+1);
delim = strrchr (loc_str, ':');
aver (delim);
*delim = '\0';
bound->line = atoi (delim+1);
bound->file = uniqstr_new (loc_str);
}