re PR c++/24985 (caret diagnostics)
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org> PR 24985 gcc/ * diagnostic.h (show_caret): Declare. (caret_max_width): Declare. (diagnostic_show_locus): Declare. * diagnostic.c (diagnostic_initialize): Initialize to false. (diagnostic_show_locus): New. (diagnostic_report_diagnostic): Call it. (getenv_columns): New. (adjust_line): New. (diagnostic_set_caret_max_width): New. * input.c (read_line): New. (location_get_source_line): New. * input.h (location_get_source_line): Declare. * toplev.c (general_init): Initialize show_caret from options. * dwarf2out.c (gen_producer_string): Handle fdiagnostics-show-caret. * opts.c (common_handle_option): Likewise. * pretty-print.h (pp_get_prefix): New. (pp_base_get_prefix): New. * common.opt (fdiagnostics-show-caret): New option. * doc/invoke.texi (fdiagnostics-show-caret): Document it. testsuite/ * lib/prune.exp: Add -fno-diagnostics-show-caret. libstdc++-v3/ * testsuite/lib/prune.exp: Handle caret. libmudflap/ * testsuite/lib/libmudflap.exp: Handle caret. From-SVN: r186305
This commit is contained in:
parent
13a7578b18
commit
9fec00429d
@ -1,3 +1,26 @@
|
||||
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 24985
|
||||
* diagnostic.h (show_caret): Declare.
|
||||
(caret_max_width): Declare.
|
||||
(diagnostic_show_locus): Declare.
|
||||
* diagnostic.c (diagnostic_initialize): Initialize to false.
|
||||
(diagnostic_show_locus): New.
|
||||
(diagnostic_report_diagnostic): Call it.
|
||||
(getenv_columns): New.
|
||||
(adjust_line): New.
|
||||
(diagnostic_set_caret_max_width): New.
|
||||
* input.c (read_line): New.
|
||||
(location_get_source_line): New.
|
||||
* input.h (location_get_source_line): Declare.
|
||||
* toplev.c (general_init): Initialize show_caret from options.
|
||||
* dwarf2out.c (gen_producer_string): Handle fdiagnostics-show-caret.
|
||||
* opts.c (common_handle_option): Likewise.
|
||||
* pretty-print.h (pp_get_prefix): New.
|
||||
(pp_base_get_prefix): New.
|
||||
* common.opt (fdiagnostics-show-caret): New option.
|
||||
* doc/invoke.texi (fdiagnostics-show-caret): Document it.
|
||||
|
||||
2012-04-11 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR rtl-optimization/52881
|
||||
|
@ -999,6 +999,10 @@ Enum(diagnostic_prefixing_rule) String(once) Value(DIAGNOSTICS_SHOW_PREFIX_ONCE)
|
||||
EnumValue
|
||||
Enum(diagnostic_prefixing_rule) String(every-line) Value(DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE)
|
||||
|
||||
fdiagnostics-show-caret
|
||||
Common Var(flag_diagnostics_show_caret) Init(1)
|
||||
Show the source line with a caret indicating the column
|
||||
|
||||
fdiagnostics-show-option
|
||||
Common Var(flag_diagnostics_show_option) Init(1)
|
||||
Amend appropriate diagnostic messages with the command line option that controls them
|
||||
|
@ -78,6 +78,35 @@ file_name_as_prefix (const char *f)
|
||||
|
||||
|
||||
|
||||
/* Return the value of the getenv("COLUMNS") as an integer. If the
|
||||
value is not set to a positive integer, then return INT_MAX. */
|
||||
static int
|
||||
getenv_columns (void)
|
||||
{
|
||||
const char * s = getenv ("COLUMNS");
|
||||
if (s != NULL) {
|
||||
int n = atoi (s);
|
||||
if (n > 0)
|
||||
return n;
|
||||
}
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
/* Set caret_max_width to value. */
|
||||
void
|
||||
diagnostic_set_caret_max_width (diagnostic_context *context, int value)
|
||||
{
|
||||
/* One minus to account for the leading empty space. */
|
||||
value = value ? value - 1
|
||||
: (isatty (fileno (context->printer->buffer->stream))
|
||||
? getenv_columns () - 1: INT_MAX);
|
||||
|
||||
if (value <= 0)
|
||||
value = INT_MAX;
|
||||
|
||||
context->caret_max_width = value;
|
||||
}
|
||||
|
||||
/* Initialize the diagnostic message outputting machinery. */
|
||||
void
|
||||
diagnostic_initialize (diagnostic_context *context, int n_opts)
|
||||
@ -100,6 +129,8 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
|
||||
context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
|
||||
for (i = 0; i < n_opts; i++)
|
||||
context->classify_diagnostic[i] = DK_UNSPECIFIED;
|
||||
context->show_caret = false;
|
||||
diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
|
||||
context->show_option_requested = false;
|
||||
context->abort_on_error = false;
|
||||
context->show_column = false;
|
||||
@ -196,6 +227,72 @@ diagnostic_build_prefix (diagnostic_context *context,
|
||||
: build_message_string ("%s:%d: %s", s.file, s.line, text));
|
||||
}
|
||||
|
||||
/* 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 10 characters or the difference between the column
|
||||
and the length of the line, whatever is smaller. */
|
||||
static const char *
|
||||
adjust_line (const char *line, int max_width, int *column_p)
|
||||
{
|
||||
int right_margin = 10;
|
||||
int line_width = strlen (line);
|
||||
int column = *column_p;
|
||||
|
||||
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 diagnostics, and a caret indicating the precise column. */
|
||||
void
|
||||
diagnostic_show_locus (diagnostic_context * context,
|
||||
const diagnostic_info *diagnostic)
|
||||
{
|
||||
const char *line;
|
||||
char *buffer;
|
||||
expanded_location s;
|
||||
int max_width;
|
||||
const char *saved_prefix;
|
||||
|
||||
|
||||
if (!context->show_caret
|
||||
|| diagnostic->location <= BUILTINS_LOCATION)
|
||||
return;
|
||||
|
||||
s = expand_location(diagnostic->location);
|
||||
line = location_get_source_line (s);
|
||||
if (line == NULL)
|
||||
return;
|
||||
|
||||
max_width = context->caret_max_width;
|
||||
line = adjust_line (line, max_width, &(s.column));
|
||||
|
||||
pp_newline (context->printer);
|
||||
saved_prefix = pp_get_prefix (context->printer);
|
||||
pp_set_prefix (context->printer, NULL);
|
||||
pp_character (context->printer, ' ');
|
||||
while (max_width > 0 && *line != '\0')
|
||||
{
|
||||
char c = *line == '\t' ? ' ' : *line;
|
||||
pp_character (context->printer, c);
|
||||
max_width--;
|
||||
line++;
|
||||
}
|
||||
pp_newline (context->printer);
|
||||
/* pp_printf does not implement %*c. */
|
||||
buffer = XALLOCAVEC (char, s.column + 3);
|
||||
snprintf (buffer, s.column + 3, " %*c", s.column, '^');
|
||||
pp_string (context->printer, buffer);
|
||||
pp_set_prefix (context->printer, saved_prefix);
|
||||
}
|
||||
|
||||
/* Take any action which is expected to happen after the diagnostic
|
||||
is written out. This function does not always return. */
|
||||
static void
|
||||
@ -547,6 +644,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
|
||||
pp_format (context->printer, &diagnostic->message);
|
||||
(*diagnostic_starter (context)) (context, diagnostic);
|
||||
pp_output_formatted_text (context->printer);
|
||||
diagnostic_show_locus (context, diagnostic);
|
||||
(*diagnostic_finalizer (context)) (context, diagnostic);
|
||||
pp_flush (context->printer);
|
||||
diagnostic_action_after_output (context, diagnostic);
|
||||
|
@ -99,6 +99,13 @@ struct diagnostic_context
|
||||
int *push_list;
|
||||
int n_push;
|
||||
|
||||
/* True if we should print the source line with a caret indicating
|
||||
the location. */
|
||||
bool show_caret;
|
||||
|
||||
/* Maximum width of the source line printed. */
|
||||
int caret_max_width;
|
||||
|
||||
/* True if we should print the command line option which controls
|
||||
each diagnostic, if known. */
|
||||
bool show_option_requested;
|
||||
@ -254,6 +261,7 @@ extern diagnostic_context *global_dc;
|
||||
extern void diagnostic_initialize (diagnostic_context *, int);
|
||||
extern void diagnostic_finish (diagnostic_context *);
|
||||
extern void diagnostic_report_current_module (diagnostic_context *, location_t);
|
||||
extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *);
|
||||
|
||||
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
|
||||
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
|
||||
@ -275,6 +283,8 @@ extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
|
||||
extern char *diagnostic_build_prefix (diagnostic_context *, diagnostic_info *);
|
||||
void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
|
||||
void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
|
||||
void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
|
||||
|
||||
|
||||
/* Pure text formatting support functions. */
|
||||
extern char *file_name_as_prefix (const char *);
|
||||
|
@ -230,7 +230,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
@xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
|
||||
@gccoptlist{-fmessage-length=@var{n} @gol
|
||||
-fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]} @gol
|
||||
-fno-diagnostics-show-option}
|
||||
-fno-diagnostics-show-option -fno-diagnostics-show-caret}
|
||||
|
||||
@item Warning Options
|
||||
@xref{Warning Options,,Options to Request or Suppress Warnings}.
|
||||
@ -2894,6 +2894,13 @@ command-line option that directly controls the diagnostic (if such an
|
||||
option is known to the diagnostic machinery). Specifying the
|
||||
@option{-fno-diagnostics-show-option} flag suppresses that behavior.
|
||||
|
||||
@item -fno-diagnostics-show-caret
|
||||
@opindex fno-diagnostics-show-caret
|
||||
@opindex fdiagnostics-show-caret
|
||||
By default, each diagnostic emitted includes the original source line
|
||||
and a caret '^' indicating the column. This option suppresses this
|
||||
information.
|
||||
|
||||
@end table
|
||||
|
||||
@node Warning Options
|
||||
|
@ -18369,6 +18369,7 @@ gen_producer_string (void)
|
||||
case OPT__output_pch_:
|
||||
case OPT_fdiagnostics_show_location_:
|
||||
case OPT_fdiagnostics_show_option:
|
||||
case OPT_fdiagnostics_show_caret:
|
||||
case OPT_fverbose_asm:
|
||||
case OPT____:
|
||||
case OPT__sysroot_:
|
||||
|
59
gcc/input.c
59
gcc/input.c
@ -50,6 +50,65 @@ expand_location (source_location loc)
|
||||
return xloc;
|
||||
}
|
||||
|
||||
/* Reads one line from file into a static buffer. */
|
||||
static const char *
|
||||
read_line (FILE *file)
|
||||
{
|
||||
static char *string;
|
||||
static size_t string_len;
|
||||
size_t pos = 0;
|
||||
char *ptr;
|
||||
|
||||
if (!string_len)
|
||||
{
|
||||
string_len = 200;
|
||||
string = XNEWVEC (char, string_len);
|
||||
}
|
||||
|
||||
while ((ptr = fgets (string + pos, string_len - pos, file)))
|
||||
{
|
||||
size_t len = strlen (string + pos);
|
||||
|
||||
if (string[pos + len - 1] == '\n')
|
||||
{
|
||||
string[pos + len - 1] = 0;
|
||||
return string;
|
||||
}
|
||||
pos += len;
|
||||
ptr = XNEWVEC (char, string_len * 2);
|
||||
if (ptr)
|
||||
{
|
||||
memcpy (ptr, string, pos);
|
||||
string = ptr;
|
||||
string_len += 2;
|
||||
}
|
||||
else
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
return pos ? string : NULL;
|
||||
}
|
||||
|
||||
/* Return the physical source line that corresponds to xloc in a
|
||||
buffer that is statically allocated. The newline is replaced by
|
||||
the null character. */
|
||||
|
||||
const char *
|
||||
location_get_source_line(expanded_location xloc)
|
||||
{
|
||||
const char *buffer;
|
||||
int lines = 1;
|
||||
FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
while ((buffer = read_line (stream)) && lines < xloc.line)
|
||||
lines++;
|
||||
|
||||
fclose (stream);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#define ONE_K 1024
|
||||
#define ONE_M (ONE_K * ONE_K)
|
||||
|
||||
|
@ -38,6 +38,7 @@ extern char builtins_location_check[(BUILTINS_LOCATION
|
||||
< RESERVED_LOCATION_COUNT) ? 1 : -1];
|
||||
|
||||
extern expanded_location expand_location (source_location);
|
||||
extern const char * location_get_source_line(expanded_location xloc);
|
||||
|
||||
/* Historically GCC used location_t, while cpp used source_location.
|
||||
This could be removed but it hardly seems worth the effort. */
|
||||
|
@ -1499,6 +1499,10 @@ common_handle_option (struct gcc_options *opts,
|
||||
case OPT_fdiagnostics_show_location_:
|
||||
diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
|
||||
break;
|
||||
|
||||
case OPT_fdiagnostics_show_caret:
|
||||
dc->show_caret = value;
|
||||
break;
|
||||
|
||||
case OPT_fdiagnostics_show_option:
|
||||
dc->show_option_requested = value;
|
||||
@ -1539,6 +1543,7 @@ common_handle_option (struct gcc_options *opts,
|
||||
|
||||
case OPT_fmessage_length_:
|
||||
pp_set_line_maximum_length (dc->printer, value);
|
||||
diagnostic_set_caret_max_width (dc, value);
|
||||
break;
|
||||
|
||||
case OPT_fpack_struct_:
|
||||
|
@ -201,6 +201,9 @@ struct pretty_print_info
|
||||
#define pp_set_line_maximum_length(PP, L) \
|
||||
pp_base_set_line_maximum_length (pp_base (PP), L)
|
||||
#define pp_set_prefix(PP, P) pp_base_set_prefix (pp_base (PP), P)
|
||||
#define pp_get_prefix(PP) pp_base_get_prefix (pp_base (PP))
|
||||
static inline const char *
|
||||
pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
|
||||
#define pp_destroy_prefix(PP) pp_base_destroy_prefix (pp_base (PP))
|
||||
#define pp_remaining_character_count_for_line(PP) \
|
||||
pp_base_remaining_character_count_for_line (pp_base (PP))
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 24985
|
||||
* lib/prune.exp: Add -fno-diagnostics-show-caret.
|
||||
|
||||
2012-04-11 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR rtl-optimization/52881
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
# Prune messages from gcc that aren't useful.
|
||||
|
||||
set TEST_ALWAYS_FLAGS "-fno-diagnostics-show-caret $TEST_ALWAYS_FLAGS"
|
||||
|
||||
proc prune_gcc_output { text } {
|
||||
#send_user "Before:$text\n"
|
||||
|
||||
|
@ -1169,6 +1169,8 @@ general_init (const char *argv0)
|
||||
/* Set a default printer. Language specific initializations will
|
||||
override it later. */
|
||||
pp_format_decoder (global_dc->printer) = &default_tree_printer;
|
||||
global_dc->show_caret
|
||||
= global_options_init.x_flag_diagnostics_show_caret;
|
||||
global_dc->show_option_requested
|
||||
= global_options_init.x_flag_diagnostics_show_option;
|
||||
global_dc->show_column
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 24985
|
||||
* testsuite/lib/libmudflap.exp: Handle caret.
|
||||
|
||||
2012-01-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR libmudflap/40778
|
||||
|
@ -298,6 +298,9 @@ proc libmudflap-dg-prune { system text } {
|
||||
|
||||
|
||||
proc prune_gcc_output { text } {
|
||||
# Ignore caret diagnostics. Unfortunately dejaGNU trims leading
|
||||
# spaces, so one cannot rely on them being present.
|
||||
regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
|
||||
regsub -all {(^|\n)[^\n]*ld: warning: libgcc_s[^\n]*not found[^\n]*try using[^\n]*} $text "" text
|
||||
regsub -all {(^|\n)[^\n]*In function.*pthread_create[^\n]*} $text "" text
|
||||
regsub -all {(^|\n)[^\n]*the use of .pthread.*is deprecated[^\n]*} $text "" text
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-04-11 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 24985
|
||||
* testsuite/lib/prune.exp: Handle caret.
|
||||
|
||||
2012-04-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
Partially revert:
|
||||
|
@ -32,6 +32,12 @@ proc dg-prune-output { args } {
|
||||
proc libstdc++-dg-prune { system text } {
|
||||
global additional_prunes
|
||||
|
||||
# send_user "Before:$text\n"
|
||||
|
||||
# Ignore caret diagnostics. Unfortunately dejaGNU trims leading
|
||||
# spaces, so one cannot rely on them being present.
|
||||
regsub -all "(^|\n)\[^\n\]+\n *\\^\n" $text "\n" text
|
||||
|
||||
# Cygwin warns about -ffunction-sections
|
||||
regsub -all "(^|\n)\[^\n\]*: -ffunction-sections may affect debugging on some targets\[^\n\]*" $text "" text
|
||||
|
||||
@ -68,5 +74,6 @@ proc libstdc++-dg-prune { system text } {
|
||||
}
|
||||
}
|
||||
|
||||
# send_user "After:$text\n"
|
||||
return $text
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user