#include "bt-utils.h"
#include "gdbsupport/buildargv.h"
#include "pager.h"
+#include "run-on-main-thread.h"
void (*deprecated_error_begin_hook) (void);
term_state.emplace ();
target_terminal::ours_for_output ();
}
- if (filtered_printing_initialized ())
- gdb_stdout->wrap_here (0); /* Force out any buffered output. */
- gdb_flush (gdb_stdout);
if (warning_pre_print)
gdb_puts (warning_pre_print, gdb_stderr);
gdb_vprintf (gdb_stderr, string, args);
bool should_print_backtrace;
};
+/* Return true if the readline callbacks have been initialized for UI.
+ This is always true once GDB is fully initialized, but during the early
+ startup phase this is initially false. */
+
+static bool
+readline_initialized (struct ui *ui)
+{
+ return ui->call_readline != nullptr;
+}
+
/* Report a problem, internal to GDB, to the user. Once the problem
has been reported, and assuming GDB didn't quit, the caller can
either allow execution to resume or throw an error. */
if (problem->should_quit != internal_problem_ask
|| !confirm
|| !filtered_printing_initialized ()
+ || !readline_initialized (current_ui)
|| problem->should_print_backtrace)
gdb_printf (gdb_stderr, "%s\n", reason.c_str ());
/* Default (yes/batch case) is to quit GDB. When in batch mode
this lessens the likelihood of GDB going into an infinite
loop. */
- if (!confirm || !filtered_printing_initialized ())
+ if (!confirm || !filtered_printing_initialized ()
+ || !readline_initialized (current_ui))
quit_p = 1;
else
quit_p = query (_("%s\nQuit this debugging session? "),
gdb_puts (_("\nThis is a bug, please report it."), gdb_stderr);
if (REPORT_BUGS_TO[0])
- gdb_printf (gdb_stderr, _(" For instructions, see:\n%s."),
- REPORT_BUGS_TO);
+ gdb_printf (gdb_stderr, _(" For instructions, see:\n%ps."),
+ styled_string (file_name_style.style (),
+ REPORT_BUGS_TO));
gdb_puts ("\n\n", gdb_stderr);
if (problem->should_dump_core == internal_problem_ask)
{
if (!can_dump_core_warn (LIMIT_MAX, reason.c_str ()))
dump_core_p = 0;
- else if (!filtered_printing_initialized ())
+ else if (!filtered_printing_initialized ()
+ || !readline_initialized (current_ui))
dump_core_p = 1;
else
{
print_sys_errmsg (const char *string, int errcode)
{
const char *err = safe_strerror (errcode);
- /* We want anything which was printed on stdout to come out first, before
- this message. */
- gdb_flush (gdb_stdout);
gdb_printf (gdb_stderr, "%s: %s.\n", string, err);
}
void
maybe_quit (void)
{
+ if (!is_main_thread ())
+ return;
+
if (sync_quit_force_run)
quit ();
if (linebuffer == 0)
return;
- /* Don't do any filtering if it is disabled. */
- if (!pagination_enabled
- || pagination_disabled_for_command
- || batch_flag
+ /* Don't do any filtering or wrapping if both are disabled. */
+ if (batch_flag
|| (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
|| top_level_interpreter () == NULL
|| top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
m_wrap_indent = 0;
});
+ /* If the user does "set height 1" then the pager will exhibit weird
+ behavior. This is pathological, though, so don't allow it. */
+ const unsigned int lines_allowed = (lines_per_page > 1
+ ? lines_per_page - 1
+ : 1);
+
/* Go through and output each character. Show line extension
when this is necessary; prompt user for new page when this is
necessary. */
/* Possible new page. Note that PAGINATION_DISABLED_FOR_COMMAND
might be set during this loop, so we must continue to check
it here. */
- if ((lines_printed >= lines_per_page - 1)
- && !pagination_disabled_for_command)
+ if (pagination_enabled
+ && !pagination_disabled_for_command
+ && lines_printed >= lines_allowed)
prompt_for_continue ();
while (*lineptr && *lineptr != '\n')
/* Possible new page. Note that
PAGINATION_DISABLED_FOR_COMMAND might be set during
this loop, so we must continue to check it here. */
- if (lines_printed >= lines_per_page - 1
- && !pagination_disabled_for_command)
+ if (pagination_enabled
+ && !pagination_disabled_for_command
+ && lines_printed >= lines_allowed)
{
prompt_for_continue ();
did_paginate = true;
this->puts (str.c_str ());
}
+#if GDB_SELF_TEST
+
+/* Test that disabling the pager does not also disable word
+ wrapping. */
+
+static void
+test_pager ()
+{
+ string_file *strfile = new string_file ();
+ pager_file pager (strfile);
+
+ /* Make sure the pager is disabled. */
+ scoped_restore save_enabled
+ = make_scoped_restore (&pagination_enabled, false);
+ scoped_restore save_disabled
+ = make_scoped_restore (&pagination_disabled_for_command, false);
+ scoped_restore save_batch
+ = make_scoped_restore (&batch_flag, false);
+ scoped_restore save_lines
+ = make_scoped_restore (&lines_per_page, 50);
+ /* Make it easy to word wrap. */
+ scoped_restore save_chars
+ = make_scoped_restore (&chars_per_line, 15);
+ scoped_restore save_printed
+ = make_scoped_restore (&chars_printed, 0);
+
+ pager.puts ("aaaaaaaaaaaa");
+ pager.wrap_here (2);
+ pager.puts ("bbbbbbbbbbbb\n");
+
+ SELF_CHECK (strfile->string () == "aaaaaaaaaaaa\n bbbbbbbbbbbb\n");
+}
+
+#endif /* GDB_SELF_TEST */
+
void
gdb_puts (const char *linebuffer, struct ui_file *stream)
{
gdb_puts (str, stream);
}
-/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
- May return nonlocally. */
-
-int
+void
gdb_putc (int c)
{
return gdb_stdout->putc (c);
}
-int
+void
gdb_putc (int c, struct ui_file *stream)
{
return stream->putc (c);
stream->emit_style_escape (ui_file_style ());
}
-/* See utils.h. */
-
-void
-vfprintf_styled (struct ui_file *stream, const ui_file_style &style,
- const char *format, va_list args)
-{
- stream->emit_style_escape (style);
- gdb_vprintf (stream, format, args);
- stream->emit_style_escape (ui_file_style ());
-}
-
void
gdb_printf (const char *format, ...)
{
\f
/* C++/ObjC demangler stuff. */
-/* fprintf_symbol_filtered attempts to demangle NAME, a symbol in language
+/* fprintf_symbol attempts to demangle NAME, a symbol in language
LANG, using demangling args ARG_MODE, and print it filtered to STREAM.
If the name is not mangled, or the language for the name is unknown, or
demangling is off, the name is printed in its "raw" form. */
void
-fprintf_symbol_filtered (struct ui_file *stream, const char *name,
- enum language lang, int arg_mode)
+fprintf_symbol (struct ui_file *stream, const char *name,
+ enum language lang, int arg_mode)
{
if (name != NULL)
{
selftests::register_test ("gdb_argv_array_view", gdb_argv_as_array_view_test);
selftests::register_test ("strncmp_iw_with_mode",
strncmp_iw_with_mode_tests);
+ selftests::register_test ("pager", test_pager);
#endif
}