mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 02:20:27 +08:00
Move diagnostic_show_locus and friends out into a new source file
gcc/ChangeLog: * Makefile.in (OBJS-libcommon): Add diagnostic-show-locus.o. * diagnostic.c (adjust_line): Move to diagnostic-show-locus.c. (diagnostic_show_locus): Likewise. (diagnostic_print_caret_line): Likewise. * diagnostic-show-locus.c: New file. From-SVN: r227915
This commit is contained in:
parent
54f0c25b30
commit
57eb2d70a6
@ -1,3 +1,11 @@
|
||||
2015-09-18 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* Makefile.in (OBJS-libcommon): Add diagnostic-show-locus.o.
|
||||
* diagnostic.c (adjust_line): Move to diagnostic-show-locus.c.
|
||||
(diagnostic_show_locus): Likewise.
|
||||
(diagnostic_print_caret_line): Likewise.
|
||||
* diagnostic-show-locus.c: New file.
|
||||
|
||||
2015-09-18 David Edelsohn <dje.gcc@gmail.com>
|
||||
|
||||
* dwarf2out.c (switch_to_eh_frame_section): Add ATTRIBUTE_UNUSED to
|
||||
|
@ -1516,7 +1516,8 @@ OBJS = \
|
||||
|
||||
# Objects in libcommon.a, potentially used by all host binaries and with
|
||||
# no target dependencies.
|
||||
OBJS-libcommon = diagnostic.o diagnostic-color.o pretty-print.o intl.o \
|
||||
OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \
|
||||
pretty-print.o intl.o \
|
||||
vec.o input.o version.o hash-table.o ggc-none.o memory-block.o
|
||||
|
||||
# Objects in libcommon-target.a, used by drivers and by the core
|
||||
|
166
gcc/diagnostic-show-locus.c
Normal file
166
gcc/diagnostic-show-locus.c
Normal file
@ -0,0 +1,166 @@
|
||||
/* Diagnostic subroutines for printing source-code
|
||||
Copyright (C) 1999-2015 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC 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 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC 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 GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "version.h"
|
||||
#include "demangle.h"
|
||||
#include "intl.h"
|
||||
#include "backtrace.h"
|
||||
#include "diagnostic.h"
|
||||
#include "diagnostic-color.h"
|
||||
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#ifdef GWINSZ_IN_SYS_IOCTL
|
||||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than
|
||||
MAX_WIDTH by some margin, then adjust the start of the line such
|
||||
that the COLUMN is smaller than MAX_WIDTH minus the margin. The
|
||||
margin is either CARET_LINE_MARGIN characters or the difference
|
||||
between the column and the length of the line, whatever is smaller.
|
||||
The length of LINE is given by LINE_WIDTH. */
|
||||
static const char *
|
||||
adjust_line (const char *line, int line_width,
|
||||
int max_width, int *column_p)
|
||||
{
|
||||
int right_margin = CARET_LINE_MARGIN;
|
||||
int column = *column_p;
|
||||
|
||||
gcc_checking_assert (line_width >= column);
|
||||
right_margin = MIN (line_width - column, right_margin);
|
||||
right_margin = max_width - right_margin;
|
||||
if (line_width >= max_width && column > right_margin)
|
||||
{
|
||||
line += column - right_margin;
|
||||
*column_p = right_margin;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/* Print the physical source line corresponding to the location of
|
||||
this diagnostic, and a caret indicating the precise column. This
|
||||
function only prints two caret characters if the two locations
|
||||
given by DIAGNOSTIC are on the same line according to
|
||||
diagnostic_same_line(). */
|
||||
void
|
||||
diagnostic_show_locus (diagnostic_context * context,
|
||||
const diagnostic_info *diagnostic)
|
||||
{
|
||||
if (!context->show_caret
|
||||
|| diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
|
||||
|| diagnostic_location (diagnostic, 0) == context->last_location)
|
||||
return;
|
||||
|
||||
context->last_location = diagnostic_location (diagnostic, 0);
|
||||
expanded_location s0 = diagnostic_expand_location (diagnostic, 0);
|
||||
expanded_location s1 = { };
|
||||
/* Zero-initialized. This is checked later by diagnostic_print_caret_line. */
|
||||
|
||||
if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION)
|
||||
s1 = diagnostic_expand_location (diagnostic, 1);
|
||||
|
||||
diagnostic_print_caret_line (context, s0, s1,
|
||||
context->caret_chars[0],
|
||||
context->caret_chars[1]);
|
||||
}
|
||||
|
||||
/* Print (part) of the source line given by xloc1 with caret1 pointing
|
||||
at the column. If xloc2.column != 0 and it fits within the same
|
||||
line as xloc1 according to diagnostic_same_line (), then caret2 is
|
||||
printed at xloc2.colum. Otherwise, the caller has to set up things
|
||||
to print a second caret line for xloc2. */
|
||||
void
|
||||
diagnostic_print_caret_line (diagnostic_context * context,
|
||||
expanded_location xloc1,
|
||||
expanded_location xloc2,
|
||||
char caret1, char caret2)
|
||||
{
|
||||
if (!diagnostic_same_line (context, xloc1, xloc2))
|
||||
/* This will mean ignore xloc2. */
|
||||
xloc2.column = 0;
|
||||
else if (xloc1.column == xloc2.column)
|
||||
xloc2.column++;
|
||||
|
||||
int cmax = MAX (xloc1.column, xloc2.column);
|
||||
int line_width;
|
||||
const char *line = location_get_source_line (xloc1.file, xloc1.line,
|
||||
&line_width);
|
||||
if (line == NULL || cmax > line_width)
|
||||
return;
|
||||
|
||||
/* Center the interesting part of the source line to fit in
|
||||
max_width, and adjust all columns accordingly. */
|
||||
int max_width = context->caret_max_width;
|
||||
int offset = (int) cmax;
|
||||
line = adjust_line (line, line_width, max_width, &offset);
|
||||
offset -= cmax;
|
||||
cmax += offset;
|
||||
xloc1.column += offset;
|
||||
if (xloc2.column)
|
||||
xloc2.column += offset;
|
||||
|
||||
/* Print the source line. */
|
||||
pp_newline (context->printer);
|
||||
const char *saved_prefix = pp_get_prefix (context->printer);
|
||||
pp_set_prefix (context->printer, NULL);
|
||||
pp_space (context->printer);
|
||||
while (max_width > 0 && line_width > 0)
|
||||
{
|
||||
char c = *line == '\t' ? ' ' : *line;
|
||||
if (c == '\0')
|
||||
c = ' ';
|
||||
pp_character (context->printer, c);
|
||||
max_width--;
|
||||
line_width--;
|
||||
line++;
|
||||
}
|
||||
pp_newline (context->printer);
|
||||
|
||||
/* Print the caret under the line. */
|
||||
const char *caret_cs, *caret_ce;
|
||||
caret_cs = colorize_start (pp_show_color (context->printer), "caret");
|
||||
caret_ce = colorize_stop (pp_show_color (context->printer));
|
||||
int cmin = xloc2.column
|
||||
? MIN (xloc1.column, xloc2.column) : xloc1.column;
|
||||
int caret_min = cmin == xloc1.column ? caret1 : caret2;
|
||||
int caret_max = cmin == xloc1.column ? caret2 : caret1;
|
||||
|
||||
/* cmin is >= 1, but we indent with an extra space at the start like
|
||||
we did above. */
|
||||
int i;
|
||||
for (i = 0; i < cmin; i++)
|
||||
pp_space (context->printer);
|
||||
pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce);
|
||||
|
||||
if (xloc2.column)
|
||||
{
|
||||
for (i++; i < cmax; i++)
|
||||
pp_space (context->printer);
|
||||
pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce);
|
||||
}
|
||||
pp_set_prefix (context->printer, saved_prefix);
|
||||
pp_needs_newline (context->printer) = true;
|
||||
}
|
129
gcc/diagnostic.c
129
gcc/diagnostic.c
@ -307,135 +307,6 @@ diagnostic_build_prefix (diagnostic_context *context,
|
||||
locus_ce, text_cs, text, text_ce));
|
||||
}
|
||||
|
||||
/* If LINE is longer than MAX_WIDTH, and COLUMN is not smaller than
|
||||
MAX_WIDTH by some margin, then adjust the start of the line such
|
||||
that the COLUMN is smaller than MAX_WIDTH minus the margin. The
|
||||
margin is either CARET_LINE_MARGIN characters or the difference
|
||||
between the column and the length of the line, whatever is smaller.
|
||||
The length of LINE is given by LINE_WIDTH. */
|
||||
static const char *
|
||||
adjust_line (const char *line, int line_width,
|
||||
int max_width, int *column_p)
|
||||
{
|
||||
int right_margin = CARET_LINE_MARGIN;
|
||||
int column = *column_p;
|
||||
|
||||
gcc_checking_assert (line_width >= column);
|
||||
right_margin = MIN (line_width - column, right_margin);
|
||||
right_margin = max_width - right_margin;
|
||||
if (line_width >= max_width && column > right_margin)
|
||||
{
|
||||
line += column - right_margin;
|
||||
*column_p = right_margin;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/* Print the physical source line corresponding to the location of
|
||||
this diagnostic, and a caret indicating the precise column. This
|
||||
function only prints two caret characters if the two locations
|
||||
given by DIAGNOSTIC are on the same line according to
|
||||
diagnostic_same_line(). */
|
||||
void
|
||||
diagnostic_show_locus (diagnostic_context * context,
|
||||
const diagnostic_info *diagnostic)
|
||||
{
|
||||
if (!context->show_caret
|
||||
|| diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
|
||||
|| diagnostic_location (diagnostic, 0) == context->last_location)
|
||||
return;
|
||||
|
||||
context->last_location = diagnostic_location (diagnostic, 0);
|
||||
expanded_location s0 = diagnostic_expand_location (diagnostic, 0);
|
||||
expanded_location s1 = { };
|
||||
/* Zero-initialized. This is checked later by diagnostic_print_caret_line. */
|
||||
|
||||
if (diagnostic_location (diagnostic, 1) > BUILTINS_LOCATION)
|
||||
s1 = diagnostic_expand_location (diagnostic, 1);
|
||||
|
||||
diagnostic_print_caret_line (context, s0, s1,
|
||||
context->caret_chars[0],
|
||||
context->caret_chars[1]);
|
||||
}
|
||||
|
||||
/* Print (part) of the source line given by xloc1 with caret1 pointing
|
||||
at the column. If xloc2.column != 0 and it fits within the same
|
||||
line as xloc1 according to diagnostic_same_line (), then caret2 is
|
||||
printed at xloc2.colum. Otherwise, the caller has to set up things
|
||||
to print a second caret line for xloc2. */
|
||||
void
|
||||
diagnostic_print_caret_line (diagnostic_context * context,
|
||||
expanded_location xloc1,
|
||||
expanded_location xloc2,
|
||||
char caret1, char caret2)
|
||||
{
|
||||
if (!diagnostic_same_line (context, xloc1, xloc2))
|
||||
/* This will mean ignore xloc2. */
|
||||
xloc2.column = 0;
|
||||
else if (xloc1.column == xloc2.column)
|
||||
xloc2.column++;
|
||||
|
||||
int cmax = MAX (xloc1.column, xloc2.column);
|
||||
int line_width;
|
||||
const char *line = location_get_source_line (xloc1.file, xloc1.line,
|
||||
&line_width);
|
||||
if (line == NULL || cmax > line_width)
|
||||
return;
|
||||
|
||||
/* Center the interesting part of the source line to fit in
|
||||
max_width, and adjust all columns accordingly. */
|
||||
int max_width = context->caret_max_width;
|
||||
int offset = (int) cmax;
|
||||
line = adjust_line (line, line_width, max_width, &offset);
|
||||
offset -= cmax;
|
||||
cmax += offset;
|
||||
xloc1.column += offset;
|
||||
if (xloc2.column)
|
||||
xloc2.column += offset;
|
||||
|
||||
/* Print the source line. */
|
||||
pp_newline (context->printer);
|
||||
const char *saved_prefix = pp_get_prefix (context->printer);
|
||||
pp_set_prefix (context->printer, NULL);
|
||||
pp_space (context->printer);
|
||||
while (max_width > 0 && line_width > 0)
|
||||
{
|
||||
char c = *line == '\t' ? ' ' : *line;
|
||||
if (c == '\0')
|
||||
c = ' ';
|
||||
pp_character (context->printer, c);
|
||||
max_width--;
|
||||
line_width--;
|
||||
line++;
|
||||
}
|
||||
pp_newline (context->printer);
|
||||
|
||||
/* Print the caret under the line. */
|
||||
const char *caret_cs, *caret_ce;
|
||||
caret_cs = colorize_start (pp_show_color (context->printer), "caret");
|
||||
caret_ce = colorize_stop (pp_show_color (context->printer));
|
||||
int cmin = xloc2.column
|
||||
? MIN (xloc1.column, xloc2.column) : xloc1.column;
|
||||
int caret_min = cmin == xloc1.column ? caret1 : caret2;
|
||||
int caret_max = cmin == xloc1.column ? caret2 : caret1;
|
||||
|
||||
/* cmin is >= 1, but we indent with an extra space at the start like
|
||||
we did above. */
|
||||
int i;
|
||||
for (i = 0; i < cmin; i++)
|
||||
pp_space (context->printer);
|
||||
pp_printf (context->printer, "%s%c%s", caret_cs, caret_min, caret_ce);
|
||||
|
||||
if (xloc2.column)
|
||||
{
|
||||
for (i++; i < cmax; i++)
|
||||
pp_space (context->printer);
|
||||
pp_printf (context->printer, "%s%c%s", caret_cs, caret_max, caret_ce);
|
||||
}
|
||||
pp_set_prefix (context->printer, saved_prefix);
|
||||
pp_needs_newline (context->printer) = true;
|
||||
}
|
||||
|
||||
/* Functions at which to stop the backtrace print. It's not
|
||||
particularly helpful to print the callers of these functions. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user