1 /* TUI display locator.
3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
5 Contributed by Hewlett-Packard Company.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "breakpoint.h"
30 #include "gdb-demangle.h"
33 #include "tui/tui-data.h"
34 #include "tui/tui-stack.h"
35 #include "tui/tui-wingeneral.h"
36 #include "tui/tui-source.h"
37 #include "tui/tui-winsource.h"
38 #include "tui/tui-file.h"
40 #include "gdb_curses.h"
42 #define PROC_PREFIX "In: "
43 #define LINE_PREFIX "L"
44 #define PC_PREFIX "PC: "
46 /* Minimum/Maximum length of some fields displayed in the TUI status
48 #define MIN_LINE_WIDTH 4 /* Use at least 4 digits for line
50 #define MIN_PROC_WIDTH 12
51 #define MAX_TARGET_WIDTH 10
52 #define MAX_PID_WIDTH 19
54 static struct tui_locator_window _locator
;
58 /* Accessor for the locator win info. Answers a pointer to the static
59 locator win info struct. */
60 struct tui_locator_window
*
61 tui_locator_win_info_ptr (void)
66 /* Create the status line to display as much information as we can on
67 this single line: target name, process number, current function,
68 current line, current PC, SingleKey mode. */
70 tui_make_status_line (struct tui_locator_window
*loc
)
72 char line_buf
[50], *pname
;
80 std::string pid_name_holder
;
81 if (inferior_ptid
== null_ptid
)
82 pid_name
= "No process";
85 pid_name_holder
= target_pid_to_str (inferior_ptid
);
86 pid_name
= pid_name_holder
.c_str ();
89 target_width
= strlen (target_shortname
);
90 if (target_width
> MAX_TARGET_WIDTH
)
91 target_width
= MAX_TARGET_WIDTH
;
93 pid_width
= strlen (pid_name
);
94 if (pid_width
> MAX_PID_WIDTH
)
95 pid_width
= MAX_PID_WIDTH
;
97 status_size
= tui_term_width ();
99 /* Translate line number and obtain its size. */
100 if (loc
->line_no
> 0)
101 xsnprintf (line_buf
, sizeof (line_buf
), "%d", loc
->line_no
);
103 strcpy (line_buf
, "??");
104 line_width
= strlen (line_buf
);
105 if (line_width
< MIN_LINE_WIDTH
)
106 line_width
= MIN_LINE_WIDTH
;
108 /* Translate PC address. */
109 std::string
pc_out (loc
->gdbarch
110 ? paddress (loc
->gdbarch
, loc
->addr
)
112 const char *pc_buf
= pc_out
.c_str ();
113 int pc_width
= pc_out
.size ();
115 /* First determine the amount of proc name width we have available.
116 The +1 are for a space separator between fields.
117 The -1 are to take into account the \0 counted by sizeof. */
118 proc_width
= (status_size
121 - (sizeof (PROC_PREFIX
) - 1 + 1)
122 - (sizeof (LINE_PREFIX
) - 1 + line_width
+ 1)
123 - (sizeof (PC_PREFIX
) - 1 + pc_width
+ 1)
124 - (tui_current_key_mode
== TUI_SINGLE_KEY_MODE
125 ? (sizeof (SINGLE_KEY
) - 1 + 1)
128 /* If there is no room to print the function name, try by removing
130 if (proc_width
< MIN_PROC_WIDTH
)
132 proc_width
+= target_width
+ 1;
134 if (proc_width
< MIN_PROC_WIDTH
)
136 proc_width
+= pid_width
+ 1;
138 if (proc_width
<= MIN_PROC_WIDTH
)
140 proc_width
+= pc_width
+ sizeof (PC_PREFIX
) - 1 + 1;
144 proc_width
+= line_width
+ sizeof (LINE_PREFIX
) - 1 + 1;
153 /* Now convert elements to string form. */
154 pname
= loc
->proc_name
;
156 /* Now create the locator line from the string version of the
160 if (target_width
> 0)
161 string
.printf ("%*.*s ", -target_width
, target_width
, target_shortname
);
163 string
.printf ("%*.*s ", -pid_width
, pid_width
, pid_name
);
165 /* Show whether we are in SingleKey mode. */
166 if (tui_current_key_mode
== TUI_SINGLE_KEY_MODE
)
168 string
.puts (SINGLE_KEY
);
172 /* Procedure/class name. */
175 if (strlen (pname
) > proc_width
)
176 string
.printf ("%s%*.*s* ", PROC_PREFIX
,
177 1 - proc_width
, proc_width
- 1, pname
);
179 string
.printf ("%s%*.*s ", PROC_PREFIX
,
180 -proc_width
, proc_width
, pname
);
184 string
.printf ("%s%*.*s ", LINE_PREFIX
,
185 -line_width
, line_width
, line_buf
);
188 string
.puts (PC_PREFIX
);
189 string
.puts (pc_buf
);
192 if (string
.size () < status_size
)
193 string
.puts (n_spaces (status_size
- string
.size ()));
194 else if (string
.size () > status_size
)
195 string
.string ().erase (status_size
, string
.size ());
197 return std::move (string
.string ());
200 /* Get a printable name for the function at the address. The symbol
201 name is demangled if demangling is turned on. Returns a pointer to
202 a static area holding the result. */
204 tui_get_function_from_frame (struct frame_info
*fi
)
206 static char name
[256];
209 print_address_symbolic (get_frame_arch (fi
), get_frame_pc (fi
),
210 &stream
, demangle
, "");
212 /* Use simple heuristics to isolate the function name. The symbol
213 can be demangled and we can have function parameters. Remove
214 them because the status line is too short to display them. */
215 const char *d
= stream
.c_str ();
218 strncpy (name
, d
, sizeof (name
) - 1);
219 name
[sizeof (name
) - 1] = 0;
221 char *p
= strchr (name
, '(');
223 p
= strchr (name
, '>');
226 p
= strchr (name
, '+');
233 tui_locator_window::rerender ()
237 std::string string
= tui_make_status_line (this);
238 wmove (handle
, 0, 0);
239 /* We ignore the return value from wstandout and wstandend, casting
240 them to void in order to avoid a compiler warning. The warning
241 itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
242 changing these macro to expand to code that causes the compiler
243 to generate an unused-value warning. */
244 (void) wstandout (handle
);
245 waddstr (handle
, string
.c_str ());
247 (void) wstandend (handle
);
249 wmove (handle
, 0, 0);
253 /* See tui-stack.h. */
256 tui_locator_window::set_locator_fullname (const char *fullname
)
258 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
260 locator
->full_name
[0] = 0;
261 strcat_to_buf (locator
->full_name
, MAX_LOCATOR_ELEMENT_LEN
, fullname
);
265 /* See tui-stack.h. */
268 tui_locator_window::set_locator_info (struct gdbarch
*gdbarch_in
,
269 const char *fullname
,
270 const char *procname
,
274 bool locator_changed_p
= false;
276 if (procname
== NULL
)
279 if (fullname
== NULL
)
282 locator_changed_p
|= strncmp (proc_name
, procname
,
283 MAX_LOCATOR_ELEMENT_LEN
) != 0;
284 locator_changed_p
|= lineno
!= line_no
;
285 locator_changed_p
|= addr_in
!= addr
;
286 locator_changed_p
|= gdbarch_in
!= gdbarch
;
287 locator_changed_p
|= strncmp (full_name
, fullname
,
288 MAX_LOCATOR_ELEMENT_LEN
) != 0;
290 proc_name
[0] = (char) 0;
291 strcat_to_buf (proc_name
, MAX_LOCATOR_ELEMENT_LEN
, procname
);
294 gdbarch
= gdbarch_in
;
295 set_locator_fullname (fullname
);
297 return locator_changed_p
;
300 /* Update only the full_name portion of the locator. */
302 tui_update_locator_fullname (const char *fullname
)
304 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
306 locator
->set_locator_fullname (fullname
);
309 /* Function to print the frame information for the TUI. The windows are
310 refreshed only if frame information has changed since the last refresh.
312 Return 1 if frame information has changed (and windows subsequently
313 refreshed), 0 otherwise. */
316 tui_show_frame_info (struct frame_info
*fi
)
318 bool locator_changed_p
;
319 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
325 symtab_and_line sal
= find_frame_sal (fi
);
327 const char *fullname
= nullptr;
328 if (sal
.symtab
!= nullptr)
329 fullname
= symtab_to_fullname (sal
.symtab
);
331 if (get_frame_pc_if_available (fi
, &pc
))
333 = locator
->set_locator_info (get_frame_arch (fi
),
336 tui_get_function_from_frame (fi
),
341 = locator
->set_locator_info (get_frame_arch (fi
),
342 "??", _("<unavailable>"), sal
.line
, 0);
344 /* If the locator information has not changed, then frame information has
345 not changed. If frame information has not changed, then the windows'
346 contents will not change. So don't bother refreshing the windows. */
347 if (!locator_changed_p
)
350 for (struct tui_source_window_base
*win_info
: tui_source_windows ())
352 win_info
->maybe_update (fi
, sal
, locator
->line_no
, locator
->addr
);
353 win_info
->update_exec_info ();
361 = locator
->set_locator_info (NULL
, NULL
, NULL
, 0, (CORE_ADDR
) 0);
363 if (!locator_changed_p
)
366 for (struct tui_source_window_base
*win_info
: tui_source_windows ())
368 win_info
->erase_source_content ();
369 win_info
->update_exec_info ();
377 tui_show_locator_content ()
379 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
380 locator
->rerender ();
383 /* Command to update the display with the current execution point. */
385 tui_update_command (const char *arg
, int from_tty
)
387 execute_command ("frame 0", from_tty
);
390 /* Function to initialize gdb commands, for tui window stack
394 _initialize_tui_stack (void)
396 add_com ("update", class_tui
, tui_update_command
,
397 _("Update the source window and locator to "
398 "display the current execution point."));