X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ftui%2Ftui-stack.c;h=d2443438596a8f46f0e7d48e2dbf10c930bdb079;hb=2dfd3df48dc7edb551718b3944eca6b35a7058a5;hp=3667e4020832336db3ac43d459a60e67fc179334;hpb=e2882c85786571175a0b0bfc3bcd2f14620b1ea3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-stack.c b/gdb/tui/tui-stack.c index 3667e40208..d244343859 100644 --- a/gdb/tui/tui-stack.c +++ b/gdb/tui/tui-stack.c @@ -1,6 +1,6 @@ /* TUI display locator. - Copyright (C) 1998-2018 Free Software Foundation, Inc. + Copyright (C) 1998-2019 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. @@ -39,43 +39,49 @@ #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 (const char *, int); -/* 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) @@ -85,13 +91,11 @@ tui_make_status_line (struct tui_locator_element *loc) 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); @@ -99,11 +103,9 @@ tui_make_status_line (struct tui_locator_element *loc) 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 (); @@ -145,65 +147,48 @@ tui_make_status_line (struct tui_locator_element *loc) } } - /* 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 @@ -239,112 +224,78 @@ tui_get_function_from_frame (struct frame_info *fi) } 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 struct symtab_and_line &sal, + const char *procname) { - struct tui_gen_win_info *locator = tui_locator_win_info_ptr (); - struct tui_locator_element *element; - int locator_changed_p = 0; + bool locator_changed_p = false; - /* 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; - } - - if (procname == NULL) - procname = ""; - - if (fullname == NULL) - fullname = ""; + gdb_assert (procname != NULL); - element = &locator->content[0]->which_element.locator; + const char *fullname = (sal.symtab == nullptr + ? "??" + : symtab_to_fullname (sal.symtab)); - 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; + locator_changed_p |= proc_name != procname; + locator_changed_p |= sal.line != line_no; + locator_changed_p |= sal.pc != addr; + locator_changed_p |= gdbarch_in != gdbarch; + locator_changed_p |= full_name != fullname; - 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 = sal.line; + addr = sal.pc; + gdbarch = gdbarch_in; + set_locator_fullname (fullname); return locator_changed_p; } /* Update only the full_name portion of the locator. */ void -tui_update_locator_fullname (const char *fullname) +tui_update_locator_fullname (struct symtab *symtab) { - tui_set_locator_fullname (fullname); - tui_show_locator_content (); + struct tui_locator_window *locator = tui_locator_win_info_ptr (); + + const char *fullname; + if (symtab != nullptr) + fullname = symtab_to_fullname (symtab); + else + fullname = "??"; + locator->set_locator_fullname (fullname); } /* Function to print the frame information for the TUI. The windows are @@ -356,35 +307,23 @@ tui_update_locator_fullname (const char *fullname) 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)); - - 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); + const char *func_name; + /* find_frame_sal does not always set PC, but we want to ensure + that it is available in the SAL. */ + if (get_frame_pc_if_available (fi, &sal.pc)) + func_name = tui_get_function_from_frame (fi); else - locator_changed_p - = tui_set_locator_info (get_frame_arch (fi), - "??", _(""), sal.line, 0); + func_name = _(""); + + locator_changed_p = locator->set_locator_info (get_frame_arch (fi), + sal, func_name); /* If the locator information has not changed, then frame information has not changed. If frame information has not changed, then the windows' @@ -392,107 +331,35 @@ tui_show_frame_info (struct frame_info *fi) 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); + win_info->update_exec_info (); } return 1; } else { - locator_changed_p - = tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0); + symtab_and_line sal {}; + + locator_changed_p = locator->set_locator_info (NULL, sal, ""); if (!locator_changed_p) return 0; - tui_show_locator_content (); - for (i = 0; i < (tui_source_windows ())->count; i++) - { - win_info = (tui_source_windows ())->list[i]; - tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT); - tui_update_exec_info (win_info); - } + for (struct tui_source_window_base *win_info : tui_source_windows ()) + win_info->erase_source_content (); return 1; } } -/* Function to initialize gdb commands, for tui window stack - manipulation. */ - 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. */ @@ -501,3 +368,14 @@ tui_update_command (const char *arg, int from_tty) { execute_command ("frame 0", from_tty); } + +/* Function to initialize gdb commands, for tui window stack + manipulation. */ + +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.")); +}