#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);
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
}