diagnostic.h: New file.

2000-04-22  Gabriel Dos Reis  <gdr@codesourcery.com>

        * diagnostic.h: New file.

        * Makefile.in (diagnostic.o): Depends on diagnostic.h

        * diagnostic.c: Tweak.  Rationalize the output logic.  Adjust
        various function prototypes.
        (diagnostic.h): #include.
        (struct output_buffer): Move into diagnostic.h.
        (get_output_prefix): Rename to output_get_prefix.  Export.
        (init_output_buffer): Export. Break out.  Ajust intialization.
        (output_space_left, output_append): Export.
        (output_newline): Rename to output_add_newline.  Export.
        (output_clear): Nullify additional output_buffer fields.
        (output_puts): Rename to output_add_string.  Export.
        (dump_output): Rename to output_flush_on.  Export.
        (build_location_prefix): Constify return-type.
        (emit_output_prefix): Rename to output_emit_prefix. Export.
        (set_real_maximum_length): New function.
        (output_set_maximum_length): Ditto
        (output_clear): Ditto.
        (output_add_character): Ditto.
        (output_add_integer): Ditto.
        (output_add_space): Ditto.
        (output_format): Ditto.
        (output_printf): Adjust buffer initialization.
        (vline_wrapper_message_with_location): Ditto.
        (v_message_with_decl): Ditto.  Adjust call to output_puts
        and get_output_prefix.
        (default_print_error_function): Adjust buffer intialization.

From-SVN: r33337
This commit is contained in:
Gabriel Dos Reis 2000-04-22 11:49:16 +00:00 committed by Gabriel Dos Reis
parent 219fe89837
commit 345ed1fe96
4 changed files with 381 additions and 123 deletions

View File

@ -1,3 +1,35 @@
2000-04-22 Gabriel Dos Reis <gdr@codesourcery.com>
* diagnostic.h: New file.
* Makefile.in (diagnostic.o): Depends on diagnostic.h
* diagnostic.c: Tweak. Rationalize the output logic. Adjust
various function prototypes.
(diagnostic.h): #include.
(struct output_buffer): Move into diagnostic.h.
(get_output_prefix): Rename to output_get_prefix. Export.
(init_output_buffer): Export. Break out. Ajust intialization.
(output_space_left, output_append): Export.
(output_newline): Rename to output_add_newline. Export.
(output_clear): Nullify additional output_buffer fields.
(output_puts): Rename to output_add_string. Export.
(dump_output): Rename to output_flush_on. Export.
(build_location_prefix): Constify return-type.
(emit_output_prefix): Rename to output_emit_prefix. Export.
(set_real_maximum_length): New function.
(output_set_maximum_length): Ditto
(output_clear): Ditto.
(output_add_character): Ditto.
(output_add_integer): Ditto.
(output_add_space): Ditto.
(output_format): Ditto.
(output_printf): Adjust buffer initialization.
(vline_wrapper_message_with_location): Ditto.
(v_message_with_decl): Ditto. Adjust call to output_puts
and get_output_prefix.
(default_print_error_function): Adjust buffer intialization.
Sat Apr 22 06:45:04 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (preexpand_calls, case CALL_EXPR): Don't look at TYPE_SIZE

View File

@ -1497,9 +1497,10 @@ print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) $(GGC_H)
stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H)
fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
$(RTL_H) $(GGC_H)
diagnostic.o : diagnostic.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) tm_p.h flags.h \
input.h insn-attr.h insn-codes.h insn-config.h toplev.h intl.h
$(RTL_H) ggc.h
diagnostic.o : diagnostic.c diagnostic.h \
$(CONFIG_H) system.h $(TREE_H) $(RTL_H) tm_p.h flags.h \
$(GGC_H) input.h insn-attr.h insn-codes.h insn-config.h toplev.h intl.h
toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \

View File

@ -1,4 +1,4 @@
/* Top level of GNU C compiler
/* Language-independent diagnostic subroutines for the GNU C compiler
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -37,38 +37,19 @@ Boston, MA 02111-1307, USA. */
#include "insn-config.h"
#include "toplev.h"
#include "intl.h"
#include "obstack.h"
#include "diagnostic.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
struct output_buffer
{
struct obstack obstack; /* where we build the text to output */
char *prefix; /* prefix of every new line */
int line_length; /* current line length (in characters) */
int max_length; /* maximum characters per line */
};
/* Prototypes. */
static int doing_line_wrapping PARAMS ((void));
static void init_output_buffer PARAMS ((struct output_buffer*, char *, int));
static char *get_output_prefix PARAMS ((const struct output_buffer *));
static int output_space_left PARAMS ((const struct output_buffer *));
static void emit_output_prefix PARAMS ((struct output_buffer *));
static void output_newline PARAMS ((struct output_buffer *));
static void output_append PARAMS ((struct output_buffer *, const char *,
const char *));
static void output_puts PARAMS ((struct output_buffer *, const char *));
static void dump_output PARAMS ((struct output_buffer *, FILE *));
static char *vbuild_message_string PARAMS ((const char *, va_list));
static char *build_message_string PARAMS ((const char *, ...))
static const char *vbuild_message_string PARAMS ((const char *, va_list));
static const char *build_message_string PARAMS ((const char *, ...))
ATTRIBUTE_PRINTF_1;
static char *build_location_prefix PARAMS ((const char *, int, int));
static void voutput_notice PARAMS ((struct output_buffer *, const char *,
va_list));
static void output_printf PARAMS ((struct output_buffer *, const char *, ...))
ATTRIBUTE_PRINTF_2;
static const char *build_location_prefix PARAMS ((const char *, int, int));
static void output_notice PARAMS ((output_buffer *, const char *));
static void line_wrapper_printf PARAMS ((FILE *, const char *, ...))
ATTRIBUTE_PRINTF_2;
static void vline_wrapper_message_with_location PARAMS ((const char *, int,
@ -98,13 +79,15 @@ static void vsorry PARAMS ((const char *, va_list));
static void report_file_and_line PARAMS ((const char *, int, int));
static void vnotice PARAMS ((FILE *, const char *, va_list));
extern int rtl_dump_and_exit;
extern int inhibit_warnings;
extern int warnings_are_errors;
extern int warningcount;
extern int errorcount;
/* Front-end specific tree formatter, if non-NULL. */
printer_fn lang_printer = NULL;
static int need_error_newline;
/* Function of last error message;
@ -143,52 +126,115 @@ set_message_length (n)
output_maximum_width = n;
}
/* Construct an output BUFFER with PREFIX and of MAX_LENGTH characters
per line. */
static void
init_output_buffer (buffer, prefix, max_length)
struct output_buffer *buffer;
char *prefix;
int max_length;
/* Returns true if BUFFER is in line-wrappind mode. */
int
output_is_line_wrapping (buffer)
output_buffer *buffer;
{
int prefix_length = prefix == 0 ? 0 : strlen (prefix);
obstack_init (&buffer->obstack);
buffer->prefix = prefix;
buffer->line_length = 0;
/* If the prefix is ridiculously too long, output at least
32 characters. */
if (max_length - prefix_length < 32)
buffer->max_length = max_length + 32;
else
buffer->max_length = max_length;
return buffer->ideal_maximum_length > 0;
}
/* Return BUFFER's prefix. */
static char *
get_output_prefix (buffer)
const struct output_buffer *buffer;
const char *
output_get_prefix (buffer)
const output_buffer *buffer;
{
return buffer->prefix;
}
/* Return the amount of characters BUFFER can accept to
make a full line. */
static int
output_space_left (buffer)
const struct output_buffer *buffer;
/* Subroutine of output_set_maximum_length. Set up BUFFER's
internal maximum characters per line. */
static void
set_real_maximum_length (buffer)
output_buffer *buffer;
{
return buffer->max_length - buffer->line_length;
/* If we're told not to wrap lines then do the obvious thing. */
if (! output_is_line_wrapping (buffer))
buffer->maximum_length = buffer->ideal_maximum_length;
else
{
int prefix_length = buffer->prefix ? strlen (buffer->prefix) : 0;
/* If the prefix is ridiculously too long, output at least
32 characters. */
if (buffer->ideal_maximum_length - prefix_length < 32)
buffer->maximum_length = buffer->ideal_maximum_length + 32;
else
buffer->maximum_length = buffer->ideal_maximum_length;
}
}
/* Dump BUFFER's prefix. */
/* Sets the number of maximum characters per line BUFFER can output
in line-wrapping mode. A LENGTH value 0 suppresses line-wrapping. */
void
output_set_maximum_length (buffer, length)
output_buffer *buffer;
int length;
{
buffer->ideal_maximum_length = length;
set_real_maximum_length (buffer);
}
static void
emit_output_prefix (buffer)
struct output_buffer *buffer;
/* Sets BUFFER's PREFIX. */
void
output_set_prefix (buffer, prefix)
output_buffer *buffer;
const char *prefix;
{
buffer->prefix = prefix;
set_real_maximum_length (buffer);
}
/* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
characters per line. */
void
init_output_buffer (buffer, prefix, maximum_length)
output_buffer *buffer;
const char *prefix;
int maximum_length;
{
obstack_init (&buffer->obstack);
buffer->ideal_maximum_length = maximum_length;
buffer->line_length = 0;
output_set_prefix (buffer, prefix);
buffer->cursor = NULL;
buffer->format_args = NULL;
}
/* Reinitialize BUFFER. */
void
output_clear (buffer)
output_buffer *buffer;
{
obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
buffer->line_length = 0;
buffer->cursor = NULL;
buffer->format_args = NULL;
}
/* Finishes to construct a NULL-terminated character string representing
the BUFFERed message. */
const char *
output_finish (buffer)
output_buffer *buffer;
{
obstack_1grow (&buffer->obstack, '\0');
return (const char *) obstack_finish (&buffer->obstack);
}
/* Return the amount of characters BUFFER can accept to
make a full line. */
int
output_space_left (buffer)
const output_buffer *buffer;
{
return buffer->maximum_length - buffer->line_length;
}
/* Write out BUFFER's prefix. */
void
output_emit_prefix (buffer)
output_buffer *buffer;
{
if (buffer->prefix)
{
@ -198,21 +244,60 @@ emit_output_prefix (buffer)
}
/* Have BUFFER start a new line. */
static void
output_newline (buffer)
struct output_buffer *buffer;
void
output_add_newline (buffer)
output_buffer *buffer;
{
obstack_1grow (&buffer->obstack, '\n');
buffer->line_length = 0;
}
/* Appends a character to BUFFER. */
void
output_add_character (buffer, c)
output_buffer *buffer;
int c;
{
if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
output_add_newline (buffer);
obstack_1grow (&buffer->obstack, c);
++buffer->line_length;
}
/* Adds a space to BUFFER. */
void
output_add_space (buffer)
output_buffer *buffer;
{
if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
{
output_add_newline (buffer);
return;
}
obstack_1grow (&buffer->obstack, ' ');
++buffer->line_length;
}
/* Add the stringified version of an integer to BUFFER. */
void
output_add_integer (buffer, i)
output_buffer *buffer;
HOST_WIDE_INT i;
{
/* This must be large enough to hold any printed integer or
floating-point value. */
static char digit_buffer[128];
sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, i);
output_add_string (buffer, digit_buffer);
}
/* Append a string deliminated by START and END to BUFFER. No wrapping is
done. The caller must ensure that it is safe to do so. */
static void
void
output_append (buffer, start, end)
struct output_buffer *buffer;
output_buffer *buffer;
const char *start;
const char *end;
{
@ -221,7 +306,7 @@ output_append (buffer, start, end)
/* Emit prefix and skip whitespace if we're starting a new line. */
if (buffer->line_length == 0)
{
emit_output_prefix (buffer);
output_emit_prefix (buffer);
while (start != end && *start == ' ')
++start;
}
@ -232,14 +317,16 @@ output_append (buffer, start, end)
/* Wrap a STRing into BUFFER. */
static void
output_puts (buffer, str)
struct output_buffer *buffer;
void
output_add_string (buffer, str)
output_buffer *buffer;
const char *str;
{
const char *p = str;
while (*str)
if (!output_is_line_wrapping (buffer))
output_append (buffer, str, str + strlen (str));
else while (*str)
{
while (*p && *p != ' ' && *p != '\n')
++p;
@ -248,13 +335,13 @@ output_puts (buffer, str)
output_append (buffer, str, p);
else
{
output_newline (buffer);
output_add_newline (buffer);
output_append (buffer, str, p);
}
while (*p && *p == '\n')
{
output_newline (buffer);
output_add_newline (buffer);
++p;
}
@ -262,23 +349,57 @@ output_puts (buffer, str)
}
}
/* Dump the content of BUFFER into FILE. */
/* Flush the content of BUFFER onto FILE and reinitialize BUFFER. */
static void
dump_output (buffer, file)
struct output_buffer *buffer;
void
output_flush_on (buffer, file)
output_buffer *buffer;
FILE *file;
{
char *text;
obstack_1grow (&buffer->obstack, '\0');
text = obstack_finish (&buffer->obstack);
const char *text = output_finish (buffer);
fputs (text, file);
obstack_free (&buffer->obstack, text);
buffer->line_length = 0;
output_clear (buffer);
}
static char *
/* Format MESSAGE into BUFFER. */
void
output_format (buffer, msg)
output_buffer *buffer;
const char *msg;
{
for (buffer->cursor = msg; *buffer->cursor; ++buffer->cursor)
{
/* Ignore text. */
if (*buffer->cursor != '%')
{
output_add_character (buffer, *buffer->cursor);
continue;
}
/* We got a '%'. Let's see what happens. */
++buffer->cursor;
/* Let's handle the traditional cases. */
if (*buffer->cursor == 's')
output_add_string (buffer, va_arg (buffer->format_args, const char *));
else if (*buffer->cursor == 'd')
output_add_integer (buffer, va_arg (buffer->format_args, int));
else if (*buffer->cursor == '%')
/* It was a '%%'. Just output a '%'. */
output_add_character (buffer, '%');
else if (lang_printer)
(*lang_printer) (buffer);
else
{
/* Hmmm. The front-end failed to install a format translator
but called us with an unrecognized format. Sorry. */
abort();
}
}
output_finish (buffer);
}
static const char *
vbuild_message_string (msgid, ap)
const char *msgid;
va_list ap;
@ -292,14 +413,14 @@ vbuild_message_string (msgid, ap)
/* Return a malloc'd string containing MSGID formatted a la
printf. The caller is reponsible for freeing the memory. */
static char *
static const char *
build_message_string VPARAMS ((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
char *str;
const char *str;
VA_START (ap, msgid);
@ -318,7 +439,7 @@ build_message_string VPARAMS ((const char *msgid, ...))
/* Return a malloc'd string describing a location. The caller is
responsible for freeing the memory. */
static char *
static const char *
build_location_prefix (file, line, warn)
const char *file;
int line;
@ -343,21 +464,20 @@ build_location_prefix (file, line, warn)
/* Format a MESSAGE into BUFFER. Automatically wrap lines. */
static void
voutput_notice (buffer, msgid, ap)
struct output_buffer *buffer;
output_notice (buffer, msgid)
output_buffer *buffer;
const char *msgid;
va_list ap;
{
char *message = vbuild_message_string (msgid, ap);
const char *message = vbuild_message_string (msgid, buffer->format_args);
output_puts (buffer, message);
free (message);
output_add_string (buffer, message);
free ((char *) message);
}
/* Format a message into BUFFER a la printf. */
static void
void
output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
@ -373,8 +493,9 @@ output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
voutput_notice (buffer, msgid, ap);
va_end (ap);
buffer->format_args = ap;
output_notice (buffer, msgid);
va_end (buffer->format_args);
}
@ -388,7 +509,7 @@ line_wrapper_printf VPARAMS ((FILE *file, const char *msgid, ...))
FILE *file;
const char *msgid;
#endif
struct output_buffer buffer;
output_buffer buffer;
va_list ap;
VA_START (ap, msgid);
@ -399,10 +520,11 @@ line_wrapper_printf VPARAMS ((FILE *file, const char *msgid, ...))
#endif
init_output_buffer (&buffer, NULL, output_maximum_width);
voutput_notice (&buffer, msgid, ap);
dump_output (&buffer, file);
buffer.format_args = ap;
output_notice (&buffer, msgid);
output_flush_on (&buffer, file);
va_end (ap);
va_end (buffer.format_args);
}
@ -414,13 +536,15 @@ vline_wrapper_message_with_location (file, line, warn, msgid, ap)
const char *msgid;
va_list ap;
{
struct output_buffer buffer;
output_buffer buffer;
init_output_buffer
(&buffer, build_location_prefix (file, line, warn), output_maximum_width);
voutput_notice (&buffer, msgid, ap);
dump_output (&buffer, stderr);
free ((char*)get_output_prefix (&buffer));
buffer.format_args = ap;
output_notice (&buffer, msgid);
output_flush_on (&buffer, stderr);
free ((char*) output_get_prefix (&buffer));
fputc ('\n', stderr);
}
@ -498,14 +622,15 @@ v_message_with_decl (decl, warn, msgid, ap)
va_list ap;
{
const char *p;
struct output_buffer buffer;
output_buffer buffer;
if (doing_line_wrapping ())
init_output_buffer
(&buffer,
build_location_prefix (DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl), warn),
output_maximum_width);
{
init_output_buffer
(&buffer, build_location_prefix
(DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn),
output_maximum_width);
}
else
report_file_and_line (DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl), warn);
@ -541,7 +666,7 @@ v_message_with_decl (decl, warn, msgid, ap)
? (*decl_printable_name) (decl, 2)
: "((anonymous))");
if (doing_line_wrapping ())
output_puts (&buffer, n);
output_add_string (&buffer, n);
else
fputs (n, stderr);
while (*p)
@ -555,15 +680,19 @@ v_message_with_decl (decl, warn, msgid, ap)
if (*p) /* Print the rest of the message. */
{
if (doing_line_wrapping ())
voutput_notice (&buffer, p, ap);
{
buffer.format_args = ap;
output_notice (&buffer, p);
ap = buffer.format_args;
}
else
vfprintf (stderr, p, ap);
}
if (doing_line_wrapping())
{
dump_output (&buffer, stderr);
free ((char *)get_output_prefix (&buffer));
output_flush_on (&buffer, stderr);
free ((char *) output_get_prefix (&buffer));
}
fputc ('\n', stderr);
@ -1012,8 +1141,8 @@ default_print_error_function (file)
{
if (last_error_function != current_function_decl)
{
char *prefix = NULL;
struct output_buffer buffer;
const char *prefix = NULL;
output_buffer buffer;
if (file)
prefix = build_message_string ("%s: ", file);
@ -1060,9 +1189,9 @@ default_print_error_function (file)
last_error_function = current_function_decl;
if (doing_line_wrapping ())
dump_output (&buffer, stderr);
output_flush_on (&buffer, stderr);
free (prefix);
free ((char*) prefix);
}
}

96
gcc/diagnostic.h Normal file
View File

@ -0,0 +1,96 @@
/* Various declarations for language-independent diagnostics subroutines.
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GNU CC.
GNU CC 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.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef __GCC_DIAGNOSTIC_H__
#define __GCC_DIAGNOSTIC_H__
#include "obstack.h"
/* Forward declarations. */
typedef struct output_buffer output_buffer;
/* The type of front-end specific hook that formats trees into an
output_buffer. */
typedef void (*printer_fn) PARAMS ((output_buffer *));
/* The output buffer datatype. This is best seen as an abstract datatype. */
struct output_buffer
{
/* Internal data. These fields should not be accessed directly by
front-ends. */
/* The obstack where the text is built up. */
struct obstack obstack;
/* The prefix for each new line. */
const char *prefix;
/* The amount of characters output so far. */
int line_length;
/* The real upper bound of number of characters per line, taking into
accompt the case of a very very looong prefix. */
int maximum_length;
/* The ideal upper bound of number of characters per line, as suggested
by front-end. */
int ideal_maximum_length;
/* Public fields. These are used by front-ends to extract formats and
arguments from the variable argument-list passed to output_format. */
/* The current char to output. Updated by front-end (*format_map) when
it is called to report front-end printer for a specified format. */
const char *cursor;
/* Variable argument-list for formatting. */
va_list format_args;
};
/* If non-NULL, this function formats data in the BUFFER.
BUFFER->CURSOR points to a format code. LANG_PRINTER should
call output_add_string (and related functions) to add data to
the BUFFER. LANG_PRINTER can read arguments from
BUFFER->FORMAT_ARGS using VA_ARG. If the BUFFER needs
additional characters from the format string, it should advance
the BUFFER->CURSOR as it goes. When LANG_PRINTER returns,
BUFFER->CURSOR should point to the last character processed. */
extern printer_fn lang_printer;
/* Prototypes */
void init_output_buffer PARAMS ((output_buffer *, const char *, int));
void output_clear PARAMS ((output_buffer *));
const char *output_get_prefix PARAMS ((const output_buffer *));
void output_set_prefix PARAMS ((output_buffer *, const char *));
void output_set_maximum_length PARAMS ((output_buffer *, int));
void output_emit_prefix PARAMS ((output_buffer *));
void output_add_newline PARAMS ((output_buffer *));
void output_add_space PARAMS ((output_buffer *));
int output_space_left PARAMS ((const output_buffer *));
void output_append PARAMS ((output_buffer *, const char *,
const char *));
void output_add_character PARAMS ((output_buffer *, int));
void output_add_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
void output_add_string PARAMS ((output_buffer *, const char *));
const char *output_finish PARAMS ((output_buffer *));
void output_flush_on PARAMS ((output_buffer *, FILE *));
void output_printf PARAMS ((output_buffer *, const char *,
...)) ATTRIBUTE_PRINTF_2;
void output_format PARAMS ((output_buffer *, const char *));
int output_is_line_wrapping PARAMS ((output_buffer *));
#endif /* __GCC_DIAGNOSTIC_H__ */