/* TUI display locator.
- Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Hewlett-Packard Company.
#include "gdb_curses.h"
-/* Get a printable name for the function at the address.
- The symbol name is demangled if demangling is turned on.
- Returns a pointer to a static area holding the result. */
-static char *tui_get_function_from_frame (struct frame_info *fi);
+#define PROC_PREFIX "In: "
+#define LINE_PREFIX "L"
+#define PC_PREFIX "PC: "
-/* Set the full_name portion of the locator. */
-static void tui_set_locator_fullname (const char *fullname);
+/* Minimum/Maximum length of some fields displayed in the TUI status
+ line. */
+#define MIN_LINE_WIDTH 4 /* Use at least 4 digits for line
+ numbers. */
+#define MIN_PROC_WIDTH 12
+#define MAX_TARGET_WIDTH 10
+#define MAX_PID_WIDTH 19
-/* Update the locator, with the provided arguments. */
-static int tui_set_locator_info (struct gdbarch *gdbarch,
- const char *fullname,
- const char *procname,
- int lineno, CORE_ADDR addr);
+static struct tui_locator_window _locator;
-static void tui_update_command (char *, int);
\f
-/* Create the status line to display as much information as we can on
- this single line: target name, process number, current function,
- current line, current PC, SingleKey mode. */
-static char*
-tui_make_status_line (struct tui_locator_element *loc)
+/* Accessor for the locator win info. Answers a pointer to the static
+ locator win info struct. */
+struct tui_locator_window *
+tui_locator_win_info_ptr (void)
+{
+ return &_locator;
+}
+
+std::string
+tui_locator_window::make_status_line () const
{
- char *string;
- char line_buf[50], *pname;
- char *buf;
+ char line_buf[50];
int status_size;
- int i, proc_width;
+ int proc_width;
const char *pid_name;
int target_width;
int pid_width;
int line_width;
- if (ptid_equal (inferior_ptid, null_ptid))
+ std::string pid_name_holder;
+ if (inferior_ptid == null_ptid)
pid_name = "No process";
else
- pid_name = target_pid_to_str (inferior_ptid);
+ {
+ pid_name_holder = target_pid_to_str (inferior_ptid);
+ pid_name = pid_name_holder.c_str ();
+ }
target_width = strlen (target_shortname);
if (target_width > MAX_TARGET_WIDTH)
if (pid_width > MAX_PID_WIDTH)
pid_width = MAX_PID_WIDTH;
- status_size = tui_term_width ();
- string = (char *) xmalloc (status_size + 1);
- buf = (char*) alloca (status_size + 1);
+ status_size = width;
/* Translate line number and obtain its size. */
- if (loc->line_no > 0)
- xsnprintf (line_buf, sizeof (line_buf), "%d", loc->line_no);
+ if (line_no > 0)
+ xsnprintf (line_buf, sizeof (line_buf), "%d", line_no);
else
strcpy (line_buf, "??");
line_width = strlen (line_buf);
line_width = MIN_LINE_WIDTH;
/* Translate PC address. */
- string_file pc_out;
-
- fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??",
- &pc_out);
-
+ std::string pc_out (gdbarch
+ ? paddress (gdbarch, addr)
+ : "??");
const char *pc_buf = pc_out.c_str ();
int pc_width = pc_out.size ();
}
}
- /* Now convert elements to string form. */
- pname = loc->proc_name;
-
/* Now create the locator line from the string version of the
- elements. We could use sprintf() here but that wouldn't ensure
- that we don't overrun the size of the allocated buffer.
- strcat_to_buf() will. */
- *string = (char) 0;
+ elements. */
+ string_file string;
if (target_width > 0)
- {
- sprintf (buf, "%*.*s ",
- -target_width, target_width, target_shortname);
- strcat_to_buf (string, status_size, buf);
- }
+ string.printf ("%*.*s ", -target_width, target_width, target_shortname);
if (pid_width > 0)
- {
- sprintf (buf, "%*.*s ",
- -pid_width, pid_width, pid_name);
- strcat_to_buf (string, status_size, buf);
- }
-
+ string.printf ("%*.*s ", -pid_width, pid_width, pid_name);
+
/* Show whether we are in SingleKey mode. */
if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
{
- strcat_to_buf (string, status_size, SINGLE_KEY);
- strcat_to_buf (string, status_size, " ");
+ string.puts (SINGLE_KEY);
+ string.puts (" ");
}
/* Procedure/class name. */
if (proc_width > 0)
{
- if (strlen (pname) > proc_width)
- sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
- 1 - proc_width, proc_width - 1, pname);
+ if (proc_name.size () > proc_width)
+ string.printf ("%s%*.*s* ", PROC_PREFIX,
+ 1 - proc_width, proc_width - 1, proc_name.c_str ());
else
- sprintf (buf, "%s%*.*s ", PROC_PREFIX,
- -proc_width, proc_width, pname);
- strcat_to_buf (string, status_size, buf);
+ string.printf ("%s%*.*s ", PROC_PREFIX,
+ -proc_width, proc_width, proc_name.c_str ());
}
if (line_width > 0)
- {
- sprintf (buf, "%s%*.*s ", LINE_PREFIX,
- -line_width, line_width, line_buf);
- strcat_to_buf (string, status_size, buf);
- }
+ string.printf ("%s%*.*s ", LINE_PREFIX,
+ -line_width, line_width, line_buf);
if (pc_width > 0)
{
- strcat_to_buf (string, status_size, PC_PREFIX);
- strcat_to_buf (string, status_size, pc_buf);
+ string.puts (PC_PREFIX);
+ string.puts (pc_buf);
}
-
-
- for (i = strlen (string); i < status_size; i++)
- string[i] = ' ';
- string[status_size] = (char) 0;
- return string;
+ if (string.size () < status_size)
+ string.puts (n_spaces (status_size - string.size ()));
+ else if (string.size () > status_size)
+ string.string ().erase (status_size, string.size ());
+
+ return std::move (string.string ());
}
/* Get a printable name for the function at the address. The symbol
}
void
-tui_show_locator_content (void)
+tui_locator_window::rerender ()
{
- char *string;
- struct tui_gen_win_info *locator;
-
- locator = tui_locator_win_info_ptr ();
-
- if (locator != NULL && locator->handle != (WINDOW *) NULL)
+ if (handle != NULL)
{
- struct tui_win_element *element;
-
- element = locator->content[0];
-
- string = tui_make_status_line (&element->which_element.locator);
- wmove (locator->handle, 0, 0);
+ std::string string = make_status_line ();
+ scrollok (handle.get (), FALSE);
+ wmove (handle.get (), 0, 0);
/* We ignore the return value from wstandout and wstandend, casting
them to void in order to avoid a compiler warning. The warning
itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
changing these macro to expand to code that causes the compiler
to generate an unused-value warning. */
- (void) wstandout (locator->handle);
- waddstr (locator->handle, string);
- wclrtoeol (locator->handle);
- (void) wstandend (locator->handle);
- tui_refresh_win (locator);
- wmove (locator->handle, 0, 0);
- xfree (string);
- locator->content_in_use = TRUE;
+ (void) wstandout (handle.get ());
+ waddstr (handle.get (), string.c_str ());
+ wclrtoeol (handle.get ());
+ (void) wstandend (handle.get ());
+ refresh_window ();
+ wmove (handle.get (), 0, 0);
}
}
+/* See tui-stack.h. */
-/* Set the filename portion of the locator. */
-static void
-tui_set_locator_fullname (const char *fullname)
+void
+tui_locator_window::set_locator_fullname (const char *fullname)
{
- struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
- struct tui_locator_element *element;
-
- if (locator->content[0] == NULL)
- {
- tui_set_locator_info (NULL, fullname, NULL, 0, 0);
- return;
- }
-
- element = &locator->content[0]->which_element.locator;
- element->full_name[0] = 0;
- strcat_to_buf (element->full_name, MAX_LOCATOR_ELEMENT_LEN, fullname);
+ full_name = fullname;
+ rerender ();
}
-/* Update the locator, with the provided arguments.
-
- Returns 1 if any of the locator's fields were actually changed,
- and 0 otherwise. */
+/* See tui-stack.h. */
-static int
-tui_set_locator_info (struct gdbarch *gdbarch,
- const char *fullname,
- const char *procname,
- int lineno,
- CORE_ADDR addr)
+bool
+tui_locator_window::set_locator_info (struct gdbarch *gdbarch_in,
+ const char *fullname,
+ const char *procname,
+ int lineno,
+ CORE_ADDR addr_in)
{
- struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
- struct tui_locator_element *element;
- int locator_changed_p = 0;
-
- /* Allocate the locator content if necessary. */
- if (locator->content_size <= 0)
- {
- locator->content = tui_alloc_content (1, LOCATOR_WIN);
- locator->content_size = 1;
- locator_changed_p = 1;
- }
+ bool locator_changed_p = false;
if (procname == NULL)
procname = "";
if (fullname == NULL)
fullname = "";
- element = &locator->content[0]->which_element.locator;
+ locator_changed_p |= proc_name != procname;
+ locator_changed_p |= lineno != line_no;
+ locator_changed_p |= addr_in != addr;
+ locator_changed_p |= gdbarch_in != gdbarch;
+ locator_changed_p |= full_name != fullname;
- locator_changed_p |= strncmp (element->proc_name, procname,
- MAX_LOCATOR_ELEMENT_LEN) != 0;
- locator_changed_p |= lineno != element->line_no;
- locator_changed_p |= addr != element->addr;
- locator_changed_p |= gdbarch != element->gdbarch;
- locator_changed_p |= strncmp (element->full_name, fullname,
- MAX_LOCATOR_ELEMENT_LEN) != 0;
-
- element->proc_name[0] = (char) 0;
- strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
- element->line_no = lineno;
- element->addr = addr;
- element->gdbarch = gdbarch;
- tui_set_locator_fullname (fullname);
+ proc_name = procname;
+ line_no = lineno;
+ addr = addr_in;
+ gdbarch = gdbarch_in;
+ set_locator_fullname (fullname);
return locator_changed_p;
}
void
tui_update_locator_fullname (const char *fullname)
{
- tui_set_locator_fullname (fullname);
- tui_show_locator_content ();
+ struct tui_locator_window *locator = tui_locator_win_info_ptr ();
+
+ locator->set_locator_fullname (fullname);
}
/* Function to print the frame information for the TUI. The windows are
int
tui_show_frame_info (struct frame_info *fi)
{
- struct tui_win_info *win_info;
- int locator_changed_p;
- int i;
+ bool locator_changed_p;
+ struct tui_locator_window *locator = tui_locator_win_info_ptr ();
if (fi)
{
- int start_line, i;
- CORE_ADDR low;
- struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
- int source_already_displayed;
CORE_ADDR pc;
symtab_and_line sal = find_frame_sal (fi);
- source_already_displayed = sal.symtab != 0
- && tui_source_is_displayed (symtab_to_fullname (sal.symtab));
+ const char *fullname = nullptr;
+ if (sal.symtab != nullptr)
+ fullname = symtab_to_fullname (sal.symtab);
if (get_frame_pc_if_available (fi, &pc))
locator_changed_p
- = tui_set_locator_info (get_frame_arch (fi),
- (sal.symtab == 0
- ? "??" : symtab_to_fullname (sal.symtab)),
- tui_get_function_from_frame (fi),
- sal.line,
- pc);
+ = locator->set_locator_info (get_frame_arch (fi),
+ (sal.symtab == 0
+ ? "??" : fullname),
+ tui_get_function_from_frame (fi),
+ sal.line,
+ pc);
else
locator_changed_p
- = tui_set_locator_info (get_frame_arch (fi),
- "??", _("<unavailable>"), sal.line, 0);
+ = locator->set_locator_info (get_frame_arch (fi),
+ "??", _("<unavailable>"), sal.line, 0);
/* If the locator information has not changed, then frame information has
not changed. If frame information has not changed, then the windows'
if (!locator_changed_p)
return 0;
- tui_show_locator_content ();
- start_line = 0;
- for (i = 0; i < (tui_source_windows ())->count; i++)
+ for (struct tui_source_window_base *win_info : tui_source_windows ())
{
- union tui_which_element *item;
-
- win_info = (tui_source_windows ())->list[i];
-
- item = &locator->content[0]->which_element;
- if (win_info == TUI_SRC_WIN)
- {
- start_line = (item->locator.line_no -
- (win_info->generic.viewport_height / 2)) + 1;
- if (start_line <= 0)
- start_line = 1;
- }
- else
- {
- if (find_pc_partial_function (get_frame_pc (fi),
- (const char **) NULL,
- &low, NULL) == 0)
- {
- /* There is no symbol available for current PC. There is no
- safe way how to "disassemble backwards". */
- low = get_frame_pc (fi);
- }
- else
- low = tui_get_low_disassembly_address (get_frame_arch (fi),
- low, get_frame_pc (fi));
- }
-
- if (win_info == TUI_SRC_WIN)
- {
- struct tui_line_or_address l;
-
- l.loa = LOA_LINE;
- l.u.line_no = start_line;
- if (!(source_already_displayed
- && tui_line_is_displayed (item->locator.line_no,
- win_info, TRUE)))
- tui_update_source_window (win_info, get_frame_arch (fi),
- sal.symtab, l, TRUE);
- else
- {
- l.u.line_no = item->locator.line_no;
- tui_set_is_exec_point_at (l, win_info);
- }
- }
- else
- {
- if (win_info == TUI_DISASM_WIN)
- {
- struct tui_line_or_address a;
-
- a.loa = LOA_ADDRESS;
- a.u.addr = low;
- if (!tui_addr_is_displayed (item->locator.addr,
- win_info, TRUE))
- tui_update_source_window (win_info, get_frame_arch (fi),
- sal.symtab, a, TRUE);
- else
- {
- a.u.addr = item->locator.addr;
- tui_set_is_exec_point_at (a, win_info);
- }
- }
- }
- tui_update_exec_info (win_info);
+ win_info->maybe_update (fi, sal, locator->line_no, locator->addr);
+ win_info->update_exec_info ();
}
return 1;
else
{
locator_changed_p
- = tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
+ = locator->set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
if (!locator_changed_p)
return 0;
- tui_show_locator_content ();
- for (i = 0; i < (tui_source_windows ())->count; i++)
+ for (struct tui_source_window_base *win_info : tui_source_windows ())
{
- win_info = (tui_source_windows ())->list[i];
- tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
- tui_update_exec_info (win_info);
+ win_info->erase_source_content ();
+ win_info->update_exec_info ();
}
return 1;
}
}
-/* Function to initialize gdb commands, for tui window stack
- manipulation. */
-
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_tui_stack;
-
void
-_initialize_tui_stack (void)
+tui_show_locator_content ()
{
- add_com ("update", class_tui, tui_update_command,
- _("Update the source window and locator to "
- "display the current execution point.\n"));
+ struct tui_locator_window *locator = tui_locator_win_info_ptr ();
+ locator->rerender ();
}
/* Command to update the display with the current execution point. */
static void
-tui_update_command (char *arg, int from_tty)
+tui_update_command (const char *arg, int from_tty)
{
- char cmd[sizeof("frame 0")];
+ execute_command ("frame 0", from_tty);
+}
+
+/* Function to initialize gdb commands, for tui window stack
+ manipulation. */
- strcpy (cmd, "frame 0");
- execute_command (cmd, from_tty);
+void
+_initialize_tui_stack (void)
+{
+ add_com ("update", class_tui, tui_update_command,
+ _("Update the source window and locator to "
+ "display the current execution point."));
}