X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Ftui%2Ftui-stack.c;h=b85b7a5d43771bd4635dbd3755a58a15d2c5bba0;hb=a068643d69ce0f25d5f7cbdaa1d0a3211d72c081;hp=7183bc29545c59668260928d472bd6bb7ef06cc4;hpb=6d012f143df40b0870ee1f64940080c1591801a3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tui/tui-stack.c b/gdb/tui/tui-stack.c index 7183bc2954..b85b7a5d43 100644 --- a/gdb/tui/tui-stack.c +++ b/gdb/tui/tui-stack.c @@ -1,7 +1,6 @@ /* TUI display locator. - Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software - Foundation, Inc. + Copyright (C) 1998-2019 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. @@ -9,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,9 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "symtab.h" @@ -30,7 +27,8 @@ #include "inferior.h" #include "target.h" #include "top.h" -#include "gdb_string.h" +#include "gdb-demangle.h" +#include "source.h" #include "tui/tui.h" #include "tui/tui-data.h" #include "tui/tui-stack.h" @@ -39,52 +37,49 @@ #include "tui/tui-winsource.h" #include "tui/tui-file.h" -#ifdef HAVE_NCURSES_H -#include -#else -#ifdef HAVE_CURSES_H -#include -#endif -#endif +#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); +static char *tui_get_function_from_frame (struct frame_info *fi); -/* Set the filename portion of the locator. */ -static void tui_set_locator_filename (const char *filename); +/* Set the full_name portion of the locator. */ +static void tui_set_locator_fullname (const char *fullname); /* Update the locator, with the provided arguments. */ -static void tui_set_locator_info (const char *filename, const char *procname, - int lineno, CORE_ADDR addr); +static int tui_set_locator_info (struct gdbarch *gdbarch, + const char *fullname, + const char *procname, + int lineno, CORE_ADDR addr); -static void tui_update_command (char *, int); +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. */ +/* 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) +tui_make_status_line (struct tui_locator_element *loc) { - char* string; + char *string; char line_buf[50], *pname; - char* buf; + char *buf; int status_size; int i, proc_width; - const char* pid_name; - const char* pc_buf; + const char *pid_name; int target_width; int pid_width; int line_width; - int pc_width; - struct ui_file *pc_out; - 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) @@ -100,7 +95,7 @@ tui_make_status_line (struct tui_locator_element* loc) /* Translate line number and obtain its size. */ if (loc->line_no > 0) - sprintf (line_buf, "%d", loc->line_no); + xsnprintf (line_buf, sizeof (line_buf), "%d", loc->line_no); else strcpy (line_buf, "??"); line_width = strlen (line_buf); @@ -108,11 +103,14 @@ tui_make_status_line (struct tui_locator_element* loc) line_width = MIN_LINE_WIDTH; /* Translate PC address. */ - pc_out = tui_sfileopen (128); - print_address_numeric (loc->addr, 1, pc_out); - pc_buf = tui_file_get_strbuf (pc_out); - pc_width = strlen (pc_buf); - + string_file pc_out; + + fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??", + &pc_out); + + const char *pc_buf = pc_out.c_str (); + int pc_width = pc_out.size (); + /* First determine the amount of proc name width we have available. The +1 are for a space separator between fields. The -1 are to take into account the \0 counted by sizeof. */ @@ -151,13 +149,13 @@ tui_make_status_line (struct tui_locator_element* loc) } } - /* Now convert elements to string form */ + /* 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. */ + /* 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; if (target_width > 0) @@ -180,7 +178,7 @@ tui_make_status_line (struct tui_locator_element* loc) strcat_to_buf (string, status_size, " "); } - /* procedure/class name */ + /* Procedure/class name. */ if (proc_width > 0) { if (strlen (pname) > proc_width) @@ -209,30 +207,31 @@ tui_make_status_line (struct tui_locator_element* loc) string[i] = ' '; string[status_size] = (char) 0; - ui_file_delete (pc_out); return string; } -/* 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. */ +/* 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) { static char name[256]; - struct ui_file *stream = tui_sfileopen (256); - char *p; - - print_address_symbolic (get_frame_pc (fi), stream, demangle, ""); - p = tui_file_get_strbuf (stream); - - /* Use simple heuristics to isolate the function name. The symbol can - be demangled and we can have function parameters. Remove them because - the status line is too short to display them. */ - if (*p == '<') - p++; - strncpy (name, p, sizeof (name)); - p = strchr (name, '('); + string_file stream; + + print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi), + &stream, demangle, ""); + + /* Use simple heuristics to isolate the function name. The symbol + can be demangled and we can have function parameters. Remove + them because the status line is too short to display them. */ + const char *d = stream.c_str (); + if (*d == '<') + d++; + strncpy (name, d, sizeof (name) - 1); + name[sizeof (name) - 1] = 0; + + char *p = strchr (name, '('); if (!p) p = strchr (name, '>'); if (p) @@ -240,31 +239,34 @@ tui_get_function_from_frame (struct frame_info *fi) p = strchr (name, '+'); if (p) *p = 0; - ui_file_delete (stream); return name; } -/* tuiShowLocatorContent(). */ void tui_show_locator_content (void) { char *string; - struct tui_gen_win_info * locator; + struct tui_gen_win_info *locator; locator = tui_locator_win_info_ptr (); if (locator != NULL && locator->handle != (WINDOW *) NULL) { - struct tui_win_element * element; + struct tui_win_element *element; - element = (struct tui_win_element *) locator->content[0]; + element = locator->content[0]; string = tui_make_status_line (&element->which_element.locator); wmove (locator->handle, 0, 0); - wstandout (locator->handle); + /* 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); - wstandend (locator->handle); + (void) wstandend (locator->handle); tui_refresh_win (locator); wmove (locator->handle, 0, 0); xfree (string); @@ -275,84 +277,133 @@ tui_show_locator_content (void) /* Set the filename portion of the locator. */ static void -tui_set_locator_filename (const char *filename) +tui_set_locator_fullname (const char *fullname) { - struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); - struct tui_locator_element * element; + 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 (filename, NULL, 0, 0); + tui_set_locator_info (NULL, fullname, NULL, 0, 0); return; } - element = &((struct tui_win_element *) locator->content[0])->which_element.locator; - element->file_name[0] = 0; - strcat_to_buf (element->file_name, MAX_LOCATOR_ELEMENT_LEN, filename); + element = &locator->content[0]->which_element.locator; + element->full_name[0] = 0; + strcat_to_buf (element->full_name, MAX_LOCATOR_ELEMENT_LEN, fullname); } -/* Update the locator, with the provided arguments. */ -static void -tui_set_locator_info (const char *filename, const char *procname, int lineno, +/* Update the locator, with the provided arguments. + + Returns 1 if any of the locator's fields were actually changed, + and 0 otherwise. */ + +static int +tui_set_locator_info (struct gdbarch *gdbarch, + const char *fullname, + const char *procname, + int lineno, CORE_ADDR addr) { - struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); - struct tui_locator_element * element; + 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 = (void **) tui_alloc_content (1, locator->type); + locator->content = tui_alloc_content (1, LOCATOR_WIN); locator->content_size = 1; + locator_changed_p = 1; } - element = &((struct tui_win_element *) locator->content[0])->which_element.locator; + if (procname == NULL) + procname = ""; + + if (fullname == NULL) + fullname = ""; + + element = &locator->content[0]->which_element.locator; + + 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; - tui_set_locator_filename (filename); + element->gdbarch = gdbarch; + tui_set_locator_fullname (fullname); + + return locator_changed_p; } -/* Update only the filename portion of the locator. */ +/* Update only the full_name portion of the locator. */ void -tui_update_locator_filename (const char *filename) +tui_update_locator_fullname (const char *fullname) { - tui_set_locator_filename (filename); + tui_set_locator_fullname (fullname); tui_show_locator_content (); } -/* Function to print the frame information for the TUI. */ -void +/* Function to print the frame information for the TUI. The windows are + refreshed only if frame information has changed since the last refresh. + + Return 1 if frame information has changed (and windows subsequently + refreshed), 0 otherwise. */ + +int tui_show_frame_info (struct frame_info *fi) { - struct tui_win_info * win_info; - register int i; + struct tui_win_info *win_info; + int locator_changed_p; if (fi) { - register int start_line, i; + int start_line, i; CORE_ADDR low; - struct tui_gen_win_info * locator = tui_locator_win_info_ptr (); - int sourceAlreadyDisplayed; - struct symtab_and_line sal; - - find_frame_sal (fi, &sal); - - sourceAlreadyDisplayed = sal.symtab != 0 - && tui_source_is_displayed (sal.symtab->filename); - tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename, - tui_get_function_from_frame (fi), - sal.line, - get_frame_pc (fi)); + 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); + else + locator_changed_p + = tui_set_locator_info (get_frame_arch (fi), + "??", _(""), 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' + contents will not change. So don't bother refreshing the windows. */ + if (!locator_changed_p) + return 0; + tui_show_locator_content (); start_line = 0; for (i = 0; i < (tui_source_windows ())->count; i++) { union tui_which_element *item; - win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; - item = &((struct tui_win_element *) locator->content[0])->which_element; + 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 - @@ -362,23 +413,33 @@ tui_show_frame_info (struct frame_info *fi) } else { - if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL, - &low, (CORE_ADDR) NULL) == 0) - error ("No function contains program counter for selected frame.\n"); + 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 (low, get_frame_pc (fi)); + low = tui_get_low_disassembly_address (get_frame_arch (fi), + low, get_frame_pc (fi)); } if (win_info == TUI_SRC_WIN) { - union tui_line_or_address l; - l.line_no = start_line; - if (!(sourceAlreadyDisplayed - && tui_line_is_displayed (item->locator.line_no, win_info, TRUE))) - tui_update_source_window (win_info, sal.symtab, l, TRUE); + 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.line_no = item->locator.line_no; + l.u.line_no = item->locator.line_no; tui_set_is_exec_point_at (l, win_info); } } @@ -386,48 +447,60 @@ tui_show_frame_info (struct frame_info *fi) { if (win_info == TUI_DISASM_WIN) { - union tui_line_or_address a; - a.addr = low; - if (!tui_addr_is_displayed (item->locator.addr, win_info, TRUE)) - tui_update_source_window (win_info, sal.symtab, a, TRUE); + 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.addr = item->locator.addr; + a.u.addr = item->locator.addr; tui_set_is_exec_point_at (a, win_info); } } } tui_update_exec_info (win_info); } + + return 1; } else { - tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0); + locator_changed_p + = tui_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 (int i = 0; i < (tui_source_windows ())->count; i++) { - win_info = (struct tui_win_info *) (tui_source_windows ())->list[i]; + win_info = (tui_source_windows ())->list[i]; tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT); tui_update_exec_info (win_info); } + + return 1; } } -/* Function to initialize gdb commands, for tui window stack manipulation. */ +/* Function to initialize gdb commands, for tui window stack + manipulation. */ + void -_initialize_tuiStack (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.\n"); + _("Update the source window and locator to " + "display the current execution point.\n")); } /* 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")]; - - strcpy (cmd, "frame 0"); - execute_command (cmd, from_tty); + execute_command ("frame 0", from_tty); }