Make '{putchar,fputc}_unfiltered' use 'fputs_unfiltered'

There is currently a regression when using
'{putchar,fputc}_unfiltered' with 'puts_unfiltered' which was
introduced by one of the commits that reworked the unfiltered print
code.

The regression makes it impossible to use '{putchar,fputc}_unfiltered'
with 'puts_unfiltered', because the former writes directly to the
ui_file stream using 'stream->write', while the latter uses a buffered
mechanism (see 'wrap_buffer') and delays the printing.

If you do a quick & dirty hack on e.g. top.c:show_gdb_datadir:

  @@ -2088,6 +2088,13 @@ static void
   show_gdb_datadir (struct ui_file *file, int from_tty,
		    struct cmd_list_element *c, const char *value)
   {
  +  putchar_unfiltered ('\n');
  +  puts_unfiltered ("TEST");
  +  putchar_unfiltered ('>');
  +  puts_unfiltered ("PUTS");
  +  putchar_unfiltered ('\n');

rebuild GDB and invoke the "show data-directory" command, you will
see:

  (gdb) show data-directory

  >
  TESTPUTSGDB's data directory is "/usr/local/share/gdb".

Note how the '>' was printed before the output, and "TEST" and "PUTS"
were printed together.

My first attempt to fix this was to always call 'flush_wrap_buffer' at
the end of 'fputs_maybe_filtered', since it seemed to me that the
function should always print what was requested.  But I wasn't sure
this was the right thing to do, so I talked to Tom on IRC and he gave
me another, simpler idea: make '{putchar,fputc}_unfiltered' call into
the already existing 'fputs_unfiltered' function.

This patch implements the idea.  I regtested it on the Buildbot, and
no regressions were detected.

gdb/ChangeLog:
2020-02-20  Sergio Durigan Junior  <sergiodj@redhat.com>
	    Tom Tromey  <tom@tromey.com>

	* utils.c (fputs_maybe_filtered): Call 'stream->puts' instead
	of 'fputc_unfiltered'.
	(putchar_unfiltered): Call 'fputc_unfiltered'.
	(fputc_unfiltered): Call 'fputs_unfiltered'.
This commit is contained in:
Sergio Durigan Junior 2020-02-19 16:40:48 -05:00
parent a9c798035d
commit 3f702acd7d
2 changed files with 25 additions and 8 deletions

View File

@ -1,3 +1,11 @@
2020-02-20 Sergio Durigan Junior <sergiodj@redhat.com>
Tom Tromey <tom@tromey.com>
* utils.c (fputs_maybe_filtered): Call 'stream->puts' instead
of 'fputc_unfiltered'.
(putchar_unfiltered): Call 'fputc_unfiltered'.
(fputc_unfiltered): Call 'fputs_unfiltered'.
2020-02-20 Andrew Burgess <andrew.burgess@embecosm.com>
* config.in: Regenerate.

View File

@ -1776,7 +1776,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
newline -- if chars_per_line is right, we
probably just overflowed anyway; if it's wrong,
let us keep going. */
fputc_unfiltered ('\n', stream);
/* XXX: The ideal thing would be to call
'stream->putc' here, but we can't because it
currently calls 'fputc_unfiltered', which ends up
calling us, which generates an infinite
recursion. */
stream->puts ("\n");
}
else
{
@ -1821,7 +1826,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
wrap_here ((char *) 0); /* Spit out chars, cancel
further wraps. */
lines_printed++;
fputc_unfiltered ('\n', stream);
/* XXX: The ideal thing would be to call
'stream->putc' here, but we can't because it
currently calls 'fputc_unfiltered', which ends up
calling us, which generates an infinite
recursion. */
stream->puts ("\n");
lineptr++;
}
}
@ -1916,10 +1926,7 @@ fputs_highlighted (const char *str, const compiled_regex &highlight,
int
putchar_unfiltered (int c)
{
char buf = c;
gdb_stdout->write (&buf, 1);
return c;
return fputc_unfiltered (c, gdb_stdout);
}
/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
@ -1934,9 +1941,11 @@ putchar_filtered (int c)
int
fputc_unfiltered (int c, struct ui_file *stream)
{
char buf = c;
char buf[2];
stream->write (&buf, 1);
buf[0] = c;
buf[1] = 0;
fputs_unfiltered (buf, stream);
return c;
}