2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
Implement automatic line wrapping mode in the g++ front-end. From-SVN: r31343
This commit is contained in:
parent
40c79d58a3
commit
b903d81e07
|
@ -1,3 +1,25 @@
|
|||
2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
* toplev.h (set_message_length): Declare.
|
||||
|
||||
* diagnostic.c (obstack_chunk_alloc): Define macro.
|
||||
(obstack_chunk_free): Likewise.
|
||||
(struct output_buffer): New data structure.
|
||||
(vmessage): Remove.
|
||||
(output_maximum_width): New variable.
|
||||
(doing_line_wrapping, set_message_length, init_output_buffer,
|
||||
get_output_prefix, output_space_left, emit_output_prefix,
|
||||
output_newline, output_append, output_puts, dump_output,
|
||||
vbuild_message_string, build_message_string, build_location_prefix,
|
||||
voutput_notice, output_printf, line_wrapper_printf,
|
||||
vline_wrapper_message_with_location): New functions. Implement
|
||||
automatic line wrapping.
|
||||
(v_message_with_decl): Make it handle automatic line wrapping.
|
||||
(v_error_with_file_and_line): Likewise.
|
||||
(v_warning_with_file_and_line): Likewise.
|
||||
(announce_function): Likewise.
|
||||
(default_print_error_function): Likewise.
|
||||
|
||||
2000-01-11 16:24 -0800 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* cpplib.h (struct cpp_options): Change lang_asm to char.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
|
||||
|
||||
* decl2.c (lang_decode_option): Handle automatic line wrapping
|
||||
option.
|
||||
|
||||
2000-01-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* friend.c (do_friend): Don't resolve scopes when processing
|
||||
|
|
437
gcc/diagnostic.c
437
gcc/diagnostic.c
|
@ -37,11 +37,41 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "insn-config.h"
|
||||
#include "toplev.h"
|
||||
#include "intl.h"
|
||||
#include "obstack.h"
|
||||
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
#define obstack_chunk_free free
|
||||
|
||||
struct output_buffer
|
||||
{
|
||||
struct obstack obstack; /* where we build the text to output */
|
||||
const 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 PROTO((void));
|
||||
static void init_output_buffer PROTO((struct output_buffer*,
|
||||
const char *, int));
|
||||
static const char *get_output_prefix PROTO((const struct output_buffer *));
|
||||
static int output_space_left PROTO((const struct output_buffer *));
|
||||
static void emit_output_prefix PROTO((struct output_buffer *));
|
||||
static void output_newline PROTO((struct output_buffer *));
|
||||
static void output_append PROTO((struct output_buffer *, const char *,
|
||||
const char *));
|
||||
static void output_puts PROTO((struct output_buffer *, const char *));
|
||||
static void dump_output PROTO((struct output_buffer *, FILE *));
|
||||
static const char *vbuild_message_string PROTO((const char *, va_list));
|
||||
static const char *build_message_string PVPROTO((const char *, ...));
|
||||
static const char *build_location_prefix PROTO((const char *, int, int));
|
||||
static void voutput_notice PROTO((struct output_buffer *, const char *,
|
||||
va_list));
|
||||
static void output_printf PVPROTO((struct output_buffer *, const char *, ...));
|
||||
static void line_wrapper_printf PVPROTO((FILE *, const char *, ...));
|
||||
static void vline_wrapper_message_with_location PROTO((const char *, int, int,
|
||||
const char *, va_list));
|
||||
static void notice PVPROTO((const char *s, ...)) ATTRIBUTE_PRINTF_1;
|
||||
static void vmessage PROTO((const char *, const char *, va_list));
|
||||
static void v_message_with_file_and_line PROTO((const char *, int, int,
|
||||
const char *, va_list));
|
||||
static void v_message_with_decl PROTO((tree, int, const char *, va_list));
|
||||
|
@ -88,7 +118,296 @@ static int last_error_tick;
|
|||
void (*print_error_function) PROTO((const char *)) =
|
||||
default_print_error_function;
|
||||
|
||||
/* Maximum characters per line in automatic line wrapping mode.
|
||||
Non Zero means don't wrap lines. */
|
||||
|
||||
static int output_maximum_width = 0;
|
||||
|
||||
/* Predicate. Return 1 if we're in automatic line wrapping mode. */
|
||||
|
||||
static int
|
||||
doing_line_wrapping ()
|
||||
{
|
||||
return output_maximum_width > 0;
|
||||
}
|
||||
|
||||
/* Set Maximum characters per line in automatic line wrapping mode. */
|
||||
|
||||
void
|
||||
set_message_length (n)
|
||||
int 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;
|
||||
const char *prefix;
|
||||
int max_length;
|
||||
{
|
||||
obstack_init (&buffer->obstack);
|
||||
buffer->prefix = prefix;
|
||||
buffer->line_length = 0;
|
||||
buffer->max_length = max_length;
|
||||
}
|
||||
|
||||
/* Return BUFFER's prefix. */
|
||||
|
||||
static const char *
|
||||
get_output_prefix (buffer)
|
||||
const struct 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;
|
||||
{
|
||||
return buffer->max_length - buffer->line_length;
|
||||
}
|
||||
|
||||
/* Dump BUFFER's prefix. */
|
||||
|
||||
static void
|
||||
emit_output_prefix (buffer)
|
||||
struct output_buffer *buffer;
|
||||
{
|
||||
if (buffer->prefix)
|
||||
{
|
||||
buffer->line_length = strlen (buffer->prefix);
|
||||
obstack_grow (&buffer->obstack, buffer->prefix, buffer->line_length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Have BUFFER start a new line. */
|
||||
|
||||
static void
|
||||
output_newline (buffer)
|
||||
struct output_buffer *buffer;
|
||||
{
|
||||
obstack_1grow (&buffer->obstack, '\n');
|
||||
buffer->line_length = 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
output_append (buffer, start, end)
|
||||
struct output_buffer *buffer;
|
||||
const char *start;
|
||||
const char *end;
|
||||
{
|
||||
int n;
|
||||
|
||||
/* Emit prefix and skip whitespace if we're starting a new line. */
|
||||
if (buffer->line_length == 0)
|
||||
{
|
||||
emit_output_prefix (buffer);
|
||||
while (start != end && *start == ' ')
|
||||
++start;
|
||||
}
|
||||
n = end - start;
|
||||
obstack_grow (&buffer->obstack, start, n);
|
||||
buffer->line_length += n;
|
||||
}
|
||||
|
||||
/* Wrap a STRing into BUFFER. */
|
||||
|
||||
static void
|
||||
output_puts (buffer, str)
|
||||
struct output_buffer *buffer;
|
||||
const char *str;
|
||||
{
|
||||
const char *p = str;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
while (*p && *p != ' ' && *p != '\n')
|
||||
++p;
|
||||
|
||||
if (p - str < output_space_left (buffer))
|
||||
output_append (buffer, str, p);
|
||||
else
|
||||
{
|
||||
output_newline (buffer);
|
||||
output_append (buffer, str, p);
|
||||
}
|
||||
|
||||
while (*p && *p == '\n')
|
||||
{
|
||||
output_newline (buffer);
|
||||
++p;
|
||||
}
|
||||
|
||||
str = p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the content of BUFFER into FILE. */
|
||||
|
||||
static void
|
||||
dump_output (buffer, file)
|
||||
struct output_buffer *buffer;
|
||||
FILE *file;
|
||||
{
|
||||
const char *text;
|
||||
|
||||
obstack_1grow (&buffer->obstack, '\0');
|
||||
text = obstack_finish (&buffer->obstack);
|
||||
fputs (text, file);
|
||||
obstack_free (&buffer->obstack, (char *)text);
|
||||
buffer->line_length = 0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
vbuild_message_string (msgid, ap)
|
||||
const char *msgid;
|
||||
va_list ap;
|
||||
{
|
||||
char *str;
|
||||
|
||||
vasprintf (&str, msgid, ap);
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Return a malloc'd string containing MSGID formatted a la
|
||||
printf. The caller is reponsible for freeing the memory. */
|
||||
|
||||
static const char *
|
||||
build_message_string VPROTO((const char *msgid, ...))
|
||||
{
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
const char *msgid;
|
||||
#endif
|
||||
va_list ap;
|
||||
const char *str;
|
||||
|
||||
VA_START (ap, msgid);
|
||||
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
msgid = va_arg (ap, const char *);
|
||||
#endif
|
||||
|
||||
str = vbuild_message_string (msgid, ap);
|
||||
|
||||
va_end (ap);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/* Return a malloc'd string describing a location. The caller is
|
||||
responsible for freeing the memory. */
|
||||
|
||||
static const char *
|
||||
build_location_prefix (file, line, warn)
|
||||
const char *file;
|
||||
int line;
|
||||
int warn;
|
||||
{
|
||||
const char *fmt = file
|
||||
? (warn ? "%s:%d: warning: " : "%s:%d: ")
|
||||
: (warn ? "%s: warning: " : "%s: ");
|
||||
|
||||
return file
|
||||
? build_message_string (fmt, file, line)
|
||||
: build_message_string (fmt, progname);
|
||||
}
|
||||
|
||||
/* Format a MESSAGE into BUFFER. Automatically wrap lines. */
|
||||
|
||||
static void
|
||||
voutput_notice (buffer, msgid, ap)
|
||||
struct output_buffer *buffer;
|
||||
const char *msgid;
|
||||
va_list ap;
|
||||
{
|
||||
const char *message = vbuild_message_string (msgid, ap);
|
||||
|
||||
output_puts (buffer, message);
|
||||
free ((char *)message);
|
||||
}
|
||||
|
||||
|
||||
/* Format a message into BUFFER a la printf. */
|
||||
|
||||
static void
|
||||
output_printf VPROTO((struct output_buffer *buffer, const char *msgid, ...))
|
||||
{
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
struct output_buffer *buffer;
|
||||
const char *msgid;
|
||||
#endif
|
||||
va_list ap;
|
||||
|
||||
VA_START (ap, msgid);
|
||||
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
buffer = va_arg (ap, struct output_buffer *);
|
||||
msgid = va_arg (ap, const char *);
|
||||
#endif
|
||||
|
||||
voutput_notice (buffer, msgid, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
/* Format a MESSAGE into FILE. Do line wrapping, starting new lines
|
||||
with PREFIX. */
|
||||
|
||||
static void
|
||||
line_wrapper_printf VPROTO((FILE *file, const char *msgid, ...))
|
||||
{
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
FILE *file;
|
||||
const char *msgid;
|
||||
#endif
|
||||
struct output_buffer buffer;
|
||||
va_list ap;
|
||||
|
||||
VA_START (ap, msgid);
|
||||
|
||||
#ifndef ANSI_PROTOTYPES
|
||||
file = va_arg (ap, FILE *);
|
||||
msgid = va_arg (ap, const char *);
|
||||
#endif
|
||||
|
||||
init_output_buffer (&buffer, (const char *)NULL, output_maximum_width);
|
||||
voutput_notice (&buffer, msgid, ap);
|
||||
dump_output (&buffer, file);
|
||||
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vline_wrapper_message_with_location (file, line, warn, msgid, ap)
|
||||
const char *file;
|
||||
int line;
|
||||
int warn;
|
||||
const char *msgid;
|
||||
va_list ap;
|
||||
{
|
||||
struct 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));
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
|
||||
|
||||
/* Print the message MSGID in FILE. */
|
||||
|
||||
static void
|
||||
|
@ -137,20 +456,6 @@ report_file_and_line (file, line, warn)
|
|||
notice ("warning: ");
|
||||
}
|
||||
|
||||
/* Print a PREFIXed MSGID. */
|
||||
|
||||
static void
|
||||
vmessage (prefix, msgid, ap)
|
||||
const char *prefix;
|
||||
const char *msgid;
|
||||
va_list ap;
|
||||
{
|
||||
if (prefix)
|
||||
fprintf (stderr, "%s: ", prefix);
|
||||
|
||||
vfprintf (stderr, msgid, ap);
|
||||
}
|
||||
|
||||
/* Print a message relevant to line LINE of file FILE. */
|
||||
|
||||
static void
|
||||
|
@ -176,9 +481,17 @@ v_message_with_decl (decl, warn, msgid, ap)
|
|||
va_list ap;
|
||||
{
|
||||
const char *p;
|
||||
struct output_buffer buffer;
|
||||
|
||||
report_file_and_line (DECL_SOURCE_FILE (decl),
|
||||
DECL_SOURCE_LINE (decl), warn);
|
||||
if (doing_line_wrapping ())
|
||||
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);
|
||||
|
||||
/* Do magic to get around lack of varargs support for insertion
|
||||
of arguments into existing list. We know that the decl is first;
|
||||
|
@ -198,14 +511,22 @@ v_message_with_decl (decl, warn, msgid, ap)
|
|||
}
|
||||
|
||||
if (p > _(msgid)) /* Print the left-hand substring. */
|
||||
fprintf (stderr, "%.*s", (int)(p - _(msgid)), _(msgid));
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
output_printf (&buffer, "%.*s", (int)(p - _(msgid)), _(msgid));
|
||||
else
|
||||
fprintf (stderr, "%.*s", (int)(p - _(msgid)), _(msgid));
|
||||
}
|
||||
|
||||
if (*p == '%') /* Print the name. */
|
||||
{
|
||||
const char *n = (DECL_NAME (decl)
|
||||
? (*decl_printable_name) (decl, 2)
|
||||
: "((anonymous))");
|
||||
fputs (n, stderr);
|
||||
if (doing_line_wrapping ())
|
||||
output_puts (&buffer, n);
|
||||
else
|
||||
fputs (n, stderr);
|
||||
while (*p)
|
||||
{
|
||||
++p;
|
||||
|
@ -215,8 +536,19 @@ v_message_with_decl (decl, warn, msgid, ap)
|
|||
}
|
||||
|
||||
if (*p) /* Print the rest of the message. */
|
||||
vmessage ((char *)NULL, p, ap);
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
voutput_notice (&buffer, p, ap);
|
||||
else
|
||||
vfprintf (stderr, p, ap);
|
||||
}
|
||||
|
||||
if (doing_line_wrapping())
|
||||
{
|
||||
dump_output (&buffer, stderr);
|
||||
free ((char *)get_output_prefix (&buffer));
|
||||
}
|
||||
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
|
||||
|
@ -268,7 +600,10 @@ v_error_with_file_and_line (file, line, msgid, ap)
|
|||
{
|
||||
count_error (0);
|
||||
report_error_function (file);
|
||||
v_message_with_file_and_line (file, line, 0, msgid, ap);
|
||||
if (doing_line_wrapping ())
|
||||
vline_wrapper_message_with_location (file, line, 0, msgid, ap);
|
||||
else
|
||||
v_message_with_file_and_line (file, line, 0, msgid, ap);
|
||||
}
|
||||
|
||||
/* Report an error at the declaration DECL.
|
||||
|
@ -347,7 +682,10 @@ v_warning_with_file_and_line (file, line, msgid, ap)
|
|||
if (count_error (1))
|
||||
{
|
||||
report_error_function (file);
|
||||
v_message_with_file_and_line (file, line, 1, msgid, ap);
|
||||
if (doing_line_wrapping ())
|
||||
vline_wrapper_message_with_location (file, line, 1, msgid, ap);
|
||||
else
|
||||
v_message_with_file_and_line (file, line, 1, msgid, ap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,7 +973,13 @@ announce_function (decl)
|
|||
if (rtl_dump_and_exit)
|
||||
fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
|
||||
else
|
||||
fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
line_wrapper_printf
|
||||
(stderr, " %s", (*decl_printable_name) (decl, 2));
|
||||
else
|
||||
fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
|
||||
}
|
||||
fflush (stderr);
|
||||
need_error_newline = 1;
|
||||
last_error_function = current_function_decl;
|
||||
|
@ -651,22 +995,57 @@ default_print_error_function (file)
|
|||
{
|
||||
if (last_error_function != current_function_decl)
|
||||
{
|
||||
const char *prefix = NULL;
|
||||
struct output_buffer buffer;
|
||||
|
||||
if (file)
|
||||
fprintf (stderr, "%s: ", file);
|
||||
prefix = build_message_string ("%s: ", file);
|
||||
|
||||
if (doing_line_wrapping ())
|
||||
init_output_buffer (&buffer, prefix, output_maximum_width);
|
||||
else
|
||||
{
|
||||
if (file)
|
||||
fprintf (stderr, "%s: ", file);
|
||||
}
|
||||
|
||||
if (current_function_decl == NULL)
|
||||
notice ("At top level:\n");
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
output_printf (&buffer, "At top level:\n");
|
||||
else
|
||||
notice ("At top level:\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
|
||||
notice ("In method `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
output_printf
|
||||
(&buffer, "In method `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
else
|
||||
notice ("In method `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
}
|
||||
else
|
||||
notice ("In function `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
{
|
||||
if (doing_line_wrapping ())
|
||||
output_printf
|
||||
(&buffer, "In function `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
else
|
||||
notice ("In function `%s':\n",
|
||||
(*decl_printable_name) (current_function_decl, 2));
|
||||
}
|
||||
}
|
||||
|
||||
last_error_function = current_function_decl;
|
||||
|
||||
if (doing_line_wrapping ())
|
||||
dump_output (&buffer, stderr);
|
||||
|
||||
free ((char *)prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ extern void fnotice PROTO ((FILE *, const char *, ...))
|
|||
extern int wrapup_global_declarations PROTO ((union tree_node **, int));
|
||||
extern void check_global_declarations PROTO ((union tree_node **, int));
|
||||
extern void note_deferral_of_defined_inline_function PROTO ((union tree_node *));
|
||||
extern void set_message_length PROTO ((int));
|
||||
extern int errorcount;
|
||||
extern int warningcount;
|
||||
extern int sorrycount;
|
||||
|
|
Loading…
Reference in New Issue