#include "signals.h"
#include "gdbcmd.h"
#include "serial.h"
-#if 0
-/* No longer needed, I suspect. */
-#include "terminal.h"
-#endif
+#include "terminal.h" /* For job_control */
#include "bfd.h"
#include "target.h"
#include "demangle.h"
{
target_terminal_ours ();
wrap_here(""); /* Force out any buffered output */
- fflush (stdout);
+ gdb_flush (gdb_stdout);
}
/* Print a warning message.
va_start (args);
target_terminal_ours ();
wrap_here(""); /* Force out any buffered output */
- fflush (stdout);
+ gdb_flush (gdb_stdout);
if (warning_pre_print)
- fprintf (stderr, warning_pre_print);
+ fprintf_unfiltered (gdb_stderr, warning_pre_print);
string = va_arg (args, char *);
- vfprintf (stderr, string, args);
- fprintf (stderr, "\n");
+ vfprintf_unfiltered (gdb_stderr, string, args);
+ fprintf_unfiltered (gdb_stderr, "\n");
va_end (args);
}
va_start (args);
target_terminal_ours ();
wrap_here(""); /* Force out any buffered output */
- fflush (stdout);
+ gdb_flush (gdb_stdout);
if (error_pre_print)
- fprintf_filtered (stderr, error_pre_print);
+ fprintf_filtered (gdb_stderr, error_pre_print);
string = va_arg (args, char *);
- vfprintf_filtered (stderr, string, args);
- fprintf_filtered (stderr, "\n");
+ vfprintf_filtered (gdb_stderr, string, args);
+ fprintf_filtered (gdb_stderr, "\n");
va_end (args);
return_to_top_level (RETURN_ERROR);
}
va_start (args);
string = va_arg (args, char *);
- fprintf (stderr, "\ngdb: ");
- vfprintf (stderr, string, args);
- fprintf (stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, "\ngdb: ");
+ vfprintf_unfiltered (gdb_stderr, string, args);
+ fprintf_unfiltered (gdb_stderr, "\n");
va_end (args);
exit (1);
}
string = va_arg (args, char *);
/* "internal error" is always correct, since GDB should never dump
core, no matter what the input. */
- fprintf (stderr, "\ngdb internal error: ");
- vfprintf (stderr, string, args);
- fprintf (stderr, "\n");
+ fprintf_unfiltered (gdb_stderr, "\ngdb internal error: ");
+ vfprintf_unfiltered (gdb_stderr, string, args);
+ fprintf_unfiltered (gdb_stderr, "\n");
va_end (args);
signal (SIGQUIT, SIG_DFL);
strcat (combined, ": ");
strcat (combined, err);
- fprintf (stderr, "%s.\n", combined);
+ /* We want anything which was printed on stdout to come out first, before
+ this message. */
+ gdb_flush (gdb_stdout);
+ fprintf_unfiltered (gdb_stderr, "%s.\n", combined);
}
/* Control C eventually causes this to be called, at a convenient time. */
void
quit ()
{
- serial_t stdout_serial = serial_fdopen (1);
+ serial_t gdb_stdout_serial = serial_fdopen (1);
target_terminal_ours ();
- wrap_here ((char *)0); /* Force out any pending output */
- SERIAL_FLUSH_OUTPUT (stdout_serial);
+ /* We want all output to appear now, before we print "Quit". We
+ have 3 levels of buffering we have to flush (it's possible that
+ some of these should be changed to flush the lower-level ones
+ too): */
+
+ /* 1. The _filtered buffer. */
+ wrap_here ((char *)0);
- SERIAL_UN_FDOPEN (stdout_serial);
+ /* 2. The stdio buffer. */
+ gdb_flush (gdb_stdout);
+ gdb_flush (gdb_stderr);
+
+ /* 3. The system-level buffer. */
+ SERIAL_FLUSH_OUTPUT (gdb_stdout_serial);
+ SERIAL_UN_FDOPEN (gdb_stdout_serial);
/* Don't use *_filtered; we don't want to prompt the user to continue. */
if (error_pre_print)
- fprintf (stderr, error_pre_print);
+ fprintf_unfiltered (gdb_stderr, error_pre_print);
if (job_control
/* If there is no terminal switching for this target, then we can't
possibly get screwed by the lack of job control. */
|| current_target->to_terminal_ours == NULL)
- fprintf (stderr, "Quit\n");
+ fprintf_unfiltered (gdb_stderr, "Quit\n");
else
- fprintf (stderr,
+ fprintf_unfiltered (gdb_stderr,
"Quit (expect signal SIGINT when the program is resumed)\n");
return_to_top_level (RETURN_QUIT);
}
if (kbhit ())
{
int k = getkey ();
- if (k == 1)
+ if (k == 1) {
quit_flag = 1;
- else if (k == 2)
+ quit();
+ }
+ else if (k == 2) {
immediate_quit = 1;
- quit ();
+ quit ();
+ }
+ else
+ {
+ /* We just ignore it */
+ fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
+ }
}
}
-#endif
+#endif
+#ifdef __GO32__
+void notice_quit()
+{
+ if (kbhit ())
+ {
+ int k = getkey ();
+ if (k == 1) {
+ quit_flag = 1;
+ }
+ else if (k == 2)
+ {
+ immediate_quit = 1;
+ }
+ else
+ {
+ fprintf_unfiltered (gdb_stderr, "CTRL-A to quit, CTRL-B to quit harder\n");
+ }
+ }
+}
+#else
+void notice_quit()
+{
+ /* Done by signals */
+}
+#endif
/* Control C comes here */
void
{
quit_flag = 1;
-#ifdef USG
- /* Restore the signal handler. */
+ /* Restore the signal handler. Harmless with BSD-style signals, needed
+ for System V-style signals. So just always do it, rather than worrying
+ about USG defines and stuff like that. */
signal (signo, request_quit);
-#endif
if (immediate_quit)
quit ();
xmalloc (size)
long size;
{
- return (xmmalloc ((void *) NULL, size));
+ return (xmmalloc ((PTR) NULL, size));
}
/* Like mrealloc but get error if no storage available. */
PTR ptr;
long size;
{
- return (xmrealloc ((void *) NULL, ptr, size));
+ return (xmrealloc ((PTR) NULL, ptr, size));
}
\f
char *
msavestring (md, ptr, size)
- void *md;
+ PTR md;
const char *ptr;
int size;
{
char *
mstrsave (md, ptr)
- void *md;
+ PTR md;
const char *ptr;
{
return (msavestring (md, ptr, strlen (ptr)));
while (1)
{
wrap_here (""); /* Flush any buffered output */
- fflush (stdout);
+ gdb_flush (gdb_stdout);
va_start (args);
ctlstr = va_arg (args, char *);
- vfprintf_filtered (stdout, ctlstr, args);
+ vfprintf_filtered (gdb_stdout, ctlstr, args);
va_end (args);
printf_filtered ("(y or n) ");
- fflush (stdout);
+ gdb_flush (gdb_stdout);
answer = fgetc (stdin);
clearerr (stdin); /* in case of C-d */
if (answer == EOF) /* C-d */
if (wrap_buffer[0])
{
*wrap_pointer = '\0';
- fputs (wrap_buffer, stdout);
+ fputs (wrap_buffer, gdb_stdout);
}
wrap_pointer = wrap_buffer;
wrap_buffer[0] = '\0';
}
}
-/* Like fputs but pause after every screenful, and can wrap at points
- other than the final character of a line.
- Unlike fputs, fputs_filtered does not return a value.
+
+GDB_FILE *
+gdb_fopen (name, mode)
+ char * name;
+ char * mode;
+{
+ return fopen (name, mode);
+}
+
+void
+gdb_flush (stream)
+ FILE *stream;
+{
+ fflush (stream);
+}
+
+/* Like fputs but if FILTER is true, pause after every screenful.
+
+ Regardless of FILTER can wrap at points other than the final
+ character of a line.
+
+ Unlike fputs, fputs_maybe_filtered does not return a value.
It is OK for LINEBUFFER to be NULL, in which case just don't print
anything.
- Note that a longjmp to top level may occur in this routine
- (since prompt_for_continue may do so) so this routine should not be
- called when cleanups are not in place. */
+ Note that a longjmp to top level may occur in this routine (only if
+ FILTER is true) (since prompt_for_continue may do so) so this
+ routine should not be called when cleanups are not in place. */
-void
-fputs_filtered (linebuffer, stream)
+static void
+fputs_maybe_filtered (linebuffer, stream, filter)
const char *linebuffer;
FILE *stream;
+ int filter;
{
const char *lineptr;
return;
/* Don't do any filtering if it is disabled. */
- if (stream != stdout
+ if (stream != gdb_stdout
|| (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
{
fputs (linebuffer, stream);
while (*lineptr)
{
/* Possible new page. */
- if (lines_printed >= lines_per_page - 1)
+ if (filter &&
+ (lines_printed >= lines_per_page - 1))
prompt_for_continue ();
while (*lineptr && *lineptr != '\n')
}
}
+void
+fputs_filtered (linebuffer, stream)
+ const char *linebuffer;
+ FILE *stream;
+{
+ fputs_maybe_filtered (linebuffer, stream, 1);
+}
+
+void
+fputs_unfiltered (linebuffer, stream)
+ const char *linebuffer;
+ FILE *stream;
+{
+#if 0
+
+ /* This gets the wrap_buffer buffering wrong when called from
+ gdb_readline (GDB was sometimes failing to print the prompt
+ before reading input). Even at other times, it seems kind of
+ misguided, especially now that printf_unfiltered doesn't use
+ printf_maybe_filtered. */
+
+ fputs_maybe_filtered (linebuffer, stream, 0);
+#else
+ fputs (linebuffer, stream);
+#endif
+}
+
+void
+putc_unfiltered (c)
+ int c;
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_unfiltered (buf, gdb_stdout);
+}
+
+void
+fputc_unfiltered (c, stream)
+ int c;
+ FILE * stream;
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_unfiltered (buf, stream);
+}
+
+
/* Print a variable number of ARGS using format FORMAT. If this
information is going to put the amount written (since the last call
to REINITIALIZE_MORE_FILTER or the last page break) over the page size,
#define MIN_LINEBUF 255
-void
-vfprintf_filtered (stream, format, args)
+static void
+vfprintf_maybe_filtered (stream, format, args, filter)
FILE *stream;
char *format;
va_list args;
+ int filter;
{
char line_buf[MIN_LINEBUF+10];
char *linebuffer = line_buf;
followed. */
vsprintf (linebuffer, format, args);
- fputs_filtered (linebuffer, stream);
+ fputs_maybe_filtered (linebuffer, stream, filter);
+}
+
+
+void
+vfprintf_filtered (stream, format, args)
+ FILE *stream;
+ char *format;
+ va_list args;
+{
+ vfprintf_maybe_filtered (stream, format, args, 1);
+}
+
+void
+vfprintf_unfiltered (stream, format, args)
+ FILE *stream;
+ char *format;
+ va_list args;
+{
+ vfprintf (stream, format, args);
}
void
char *format;
va_list args;
{
- vfprintf_filtered (stdout, format, args);
+ vfprintf_maybe_filtered (gdb_stdout, format, args, 1);
+}
+
+void
+vprintf_unfiltered (format, args)
+ char *format;
+ va_list args;
+{
+ vfprintf (gdb_stdout, format, args);
}
/* VARARGS */
va_end (args);
}
+/* VARARGS */
+void
+fprintf_unfiltered (va_alist)
+ va_dcl
+{
+ va_list args;
+ FILE *stream;
+ char *format;
+
+ va_start (args);
+ stream = va_arg (args, FILE *);
+ format = va_arg (args, char *);
+
+ /* This won't blow up if the restrictions described above are
+ followed. */
+ vfprintf_unfiltered (stream, format, args);
+ va_end (args);
+}
+
/* Like fprintf_filtered, but prints it's result indent.
- Called as fprintfi_filtered (spaces, format, arg1, arg2, ...); */
+ Called as fprintfi_filtered (spaces, stream, format, ...); */
/* VARARGS */
void
va_end (args);
}
+
/* VARARGS */
void
printf_filtered (va_alist)
va_start (args);
format = va_arg (args, char *);
- vfprintf_filtered (stdout, format, args);
+ vfprintf_filtered (gdb_stdout, format, args);
+ va_end (args);
+}
+
+
+/* VARARGS */
+void
+printf_unfiltered (va_alist)
+ va_dcl
+{
+ va_list args;
+ char *format;
+
+ va_start (args);
+ format = va_arg (args, char *);
+
+ vfprintf_unfiltered (gdb_stdout, format, args);
va_end (args);
}
/* Like printf_filtered, but prints it's result indented.
- Called as printfi_filtered (spaces, format, arg1, arg2, ...); */
+ Called as printfi_filtered (spaces, format, ...); */
/* VARARGS */
void
va_start (args);
spaces = va_arg (args, int);
format = va_arg (args, char *);
- print_spaces_filtered (spaces, stdout);
- vfprintf_filtered (stdout, format, args);
+ print_spaces_filtered (spaces, gdb_stdout);
+ vfprintf_filtered (gdb_stdout, format, args);
va_end (args);
}
puts_filtered (string)
char *string;
{
- fputs_filtered (string, stdout);
+ fputs_filtered (string, gdb_stdout);
+}
+
+void
+puts_unfiltered (string)
+ char *string;
+{
+ fputs_unfiltered (string, gdb_stdout);
}
/* Return a pointer to N spaces and a null. The pointer is good
#endif
#endif
/* If the output is not a terminal, don't paginate it. */
- if (!ISATTY (stdout))
+ if (!ISATTY (gdb_stdout))
lines_per_page = UINT_MAX;
set_width_command ((char *)NULL, 0, c);