Introduce bfd_print_error function

gdb likes to control its own output; for example, this is important
for gdb's pager, and for logging.  While BFD provides a way to
intercept error output, via bfd_set_error_handler, it turns out to be
difficult for this function to truly generate the desired output in a
gdb-friendly way -- the error handler is expected to implement some
BFD printf format extensions.

This patch introduces a new function that an error handler can use to
format the text.  This way, gdb can set the error handler and arrange
for the output to be displayed as it likes.

	* bfd.c (bfd_print_callback): Rename from print_func.  Move into
	comment.
	(_bfd_doprnt): Update.
	(bfd_print_error): New function.
	(error_handler_fprintf, error_handler_sprintf): Use
	bfd_print_error.
	* bfd-in2.h: Rebuild.
This commit is contained in:
Tom Tromey
2024-02-12 14:25:03 -07:00
parent 91095bcf28
commit 7417ccf08e
2 changed files with 41 additions and 13 deletions

View File

@@ -2557,6 +2557,10 @@ void bfd_perror (const char *message);
typedef void (*bfd_error_handler_type) (const char *, va_list);
typedef int (*bfd_print_callback) (void *, const char *, ...);
void bfd_print_error (bfd_print_callback print_func,
void *stream, const char *fmt, va_list ap);
void _bfd_error_handler (const char *fmt, ...) ATTRIBUTE_PRINTF_1;
bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);

View File

@@ -1000,10 +1000,13 @@ union _bfd_doprnt_args
result = print (stream, specifier, value); \
} while (0)
typedef int (*print_func) (void *, const char *, ...);
/*
CODE_FRAGMENT
.typedef int (*bfd_print_callback) (void *, const char *, ...);
*/
static int
_bfd_doprnt (print_func print, void *stream, const char *format,
_bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
union _bfd_doprnt_args *args)
{
const char *ptr = format;
@@ -1446,21 +1449,44 @@ _bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
return arg_count;
}
/*
FUNCTION
bfd_print_error
SYNOPSIS
void bfd_print_error (bfd_print_callback print_func,
void *stream, const char *fmt, va_list ap);
DESCRIPTION
This formats FMT and AP according to BFD "printf" rules,
sending the output to STREAM by repeated calls to PRINT_FUNC.
PRINT_FUNC is a printf-like function; it does not need to
implement the BFD printf format extensions. This can be used
in a callback that is set via bfd_set_error_handler to turn
the error into ordinary output.
*/
void
bfd_print_error (bfd_print_callback print_func, void *stream,
const char *fmt, va_list ap)
{
union _bfd_doprnt_args args[MAX_ARGS];
print_func (stream, "%s: ", _bfd_get_error_program_name ());
_bfd_doprnt_scan (fmt, ap, args);
_bfd_doprnt (print_func, stream, fmt, args);
}
/* The standard error handler that prints to stderr. */
static void
error_handler_fprintf (const char *fmt, va_list ap)
{
union _bfd_doprnt_args args[MAX_ARGS];
_bfd_doprnt_scan (fmt, ap, args);
/* PR 4992: Don't interrupt output being sent to stdout. */
fflush (stdout);
fprintf (stderr, "%s: ", _bfd_get_error_program_name ());
_bfd_doprnt ((print_func) fprintf, stderr, fmt, args);
bfd_print_error ((bfd_print_callback) fprintf, stderr, fmt, ap);
/* On AIX, putc is implemented as a macro that triggers a -Wunused-value
warning, so use the fputc function to avoid it. */
@@ -1512,15 +1538,13 @@ static bfd *error_handler_bfd;
static void
error_handler_sprintf (const char *fmt, va_list ap)
{
union _bfd_doprnt_args args[MAX_ARGS];
char error_buf[1024];
struct buf_stream error_stream;
_bfd_doprnt_scan (fmt, ap, args);
error_stream.ptr = error_buf;
error_stream.left = sizeof (error_buf);
_bfd_doprnt (err_sprintf, &error_stream, fmt, args);
bfd_print_error (err_sprintf, &error_stream, fmt, ap);
size_t len = error_stream.ptr - error_buf;
struct per_xvec_message **warn