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)
67 tui_locator_window::make_status_line () const
77 std::string pid_name_holder
;
78 if (inferior_ptid
== null_ptid
)
79 pid_name
= "No process";
82 pid_name_holder
= target_pid_to_str (inferior_ptid
);
83 pid_name
= pid_name_holder
.c_str ();
86 target_width
= strlen (target_shortname
);
87 if (target_width
> MAX_TARGET_WIDTH
)
88 target_width
= MAX_TARGET_WIDTH
;
90 pid_width
= strlen (pid_name
);
91 if (pid_width
> MAX_PID_WIDTH
)
92 pid_width
= MAX_PID_WIDTH
;
96 /* Translate line number and obtain its size. */
98 xsnprintf (line_buf
, sizeof (line_buf
), "%d", line_no
);
100 strcpy (line_buf
, "??");
101 line_width
= strlen (line_buf
);
102 if (line_width
< MIN_LINE_WIDTH
)
103 line_width
= MIN_LINE_WIDTH
;
105 /* Translate PC address. */
106 std::string
pc_out (gdbarch
107 ? paddress (gdbarch
, addr
)
109 const char *pc_buf
= pc_out
.c_str ();
110 int pc_width
= pc_out
.size ();
112 /* First determine the amount of proc name width we have available.
113 The +1 are for a space separator between fields.
114 The -1 are to take into account the \0 counted by sizeof. */
115 proc_width
= (status_size
118 - (sizeof (PROC_PREFIX
) - 1 + 1)
119 - (sizeof (LINE_PREFIX
) - 1 + line_width
+ 1)
120 - (sizeof (PC_PREFIX
) - 1 + pc_width
+ 1)
121 - (tui_current_key_mode
== TUI_SINGLE_KEY_MODE
122 ? (sizeof (SINGLE_KEY
) - 1 + 1)
125 /* If there is no room to print the function name, try by removing
127 if (proc_width
< MIN_PROC_WIDTH
)
129 proc_width
+= target_width
+ 1;
131 if (proc_width
< MIN_PROC_WIDTH
)
133 proc_width
+= pid_width
+ 1;
135 if (proc_width
<= MIN_PROC_WIDTH
)
137 proc_width
+= pc_width
+ sizeof (PC_PREFIX
) - 1 + 1;
141 proc_width
+= line_width
+ sizeof (LINE_PREFIX
) - 1 + 1;
150 /* Now create the locator line from the string version of the
154 if (target_width
> 0)
155 string
.printf ("%*.*s ", -target_width
, target_width
, target_shortname
);
157 string
.printf ("%*.*s ", -pid_width
, pid_width
, pid_name
);
159 /* Show whether we are in SingleKey mode. */
160 if (tui_current_key_mode
== TUI_SINGLE_KEY_MODE
)
162 string
.puts (SINGLE_KEY
);
166 /* Procedure/class name. */
169 if (proc_name
.size () > proc_width
)
170 string
.printf ("%s%*.*s* ", PROC_PREFIX
,
171 1 - proc_width
, proc_width
- 1, proc_name
.c_str ());
173 string
.printf ("%s%*.*s ", PROC_PREFIX
,
174 -proc_width
, proc_width
, proc_name
.c_str ());
178 string
.printf ("%s%*.*s ", LINE_PREFIX
,
179 -line_width
, line_width
, line_buf
);
182 string
.puts (PC_PREFIX
);
183 string
.puts (pc_buf
);
186 if (string
.size () < status_size
)
187 string
.puts (n_spaces (status_size
- string
.size ()));
188 else if (string
.size () > status_size
)
189 string
.string ().erase (status_size
, string
.size ());
191 return std::move (string
.string ());
194 /* Get a printable name for the function at the address. The symbol
195 name is demangled if demangling is turned on. Returns a pointer to
196 a static area holding the result. */
198 tui_get_function_from_frame (struct frame_info
*fi
)
200 static char name
[256];
203 print_address_symbolic (get_frame_arch (fi
), get_frame_pc (fi
),
204 &stream
, demangle
, "");
206 /* Use simple heuristics to isolate the function name. The symbol
207 can be demangled and we can have function parameters. Remove
208 them because the status line is too short to display them. */
209 const char *d
= stream
.c_str ();
212 strncpy (name
, d
, sizeof (name
) - 1);
213 name
[sizeof (name
) - 1] = 0;
215 char *p
= strchr (name
, '(');
217 p
= strchr (name
, '>');
220 p
= strchr (name
, '+');
227 tui_locator_window::rerender ()
231 std::string string
= make_status_line ();
232 scrollok (handle
.get (), FALSE
);
233 wmove (handle
.get (), 0, 0);
234 /* We ignore the return value from wstandout and wstandend, casting
235 them to void in order to avoid a compiler warning. The warning
236 itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
237 changing these macro to expand to code that causes the compiler
238 to generate an unused-value warning. */
239 (void) wstandout (handle
.get ());
240 waddstr (handle
.get (), string
.c_str ());
241 wclrtoeol (handle
.get ());
242 (void) wstandend (handle
.get ());
244 wmove (handle
.get (), 0, 0);
248 /* See tui-stack.h. */
251 tui_locator_window::set_locator_fullname (const char *fullname
)
253 full_name
= fullname
;
257 /* See tui-stack.h. */
260 tui_locator_window::set_locator_info (struct gdbarch
*gdbarch_in
,
261 const char *fullname
,
262 const char *procname
,
266 bool locator_changed_p
= false;
268 if (procname
== NULL
)
271 if (fullname
== NULL
)
274 locator_changed_p
|= proc_name
!= procname
;
275 locator_changed_p
|= lineno
!= line_no
;
276 locator_changed_p
|= addr_in
!= addr
;
277 locator_changed_p
|= gdbarch_in
!= gdbarch
;
278 locator_changed_p
|= full_name
!= fullname
;
280 proc_name
= procname
;
283 gdbarch
= gdbarch_in
;
284 set_locator_fullname (fullname
);
286 return locator_changed_p
;
289 /* Update only the full_name portion of the locator. */
291 tui_update_locator_fullname (const char *fullname
)
293 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
295 locator
->set_locator_fullname (fullname
);
298 /* Function to print the frame information for the TUI. The windows are
299 refreshed only if frame information has changed since the last refresh.
301 Return 1 if frame information has changed (and windows subsequently
302 refreshed), 0 otherwise. */
305 tui_show_frame_info (struct frame_info
*fi
)
307 bool locator_changed_p
;
308 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
314 symtab_and_line sal
= find_frame_sal (fi
);
316 const char *fullname
= nullptr;
317 if (sal
.symtab
!= nullptr)
318 fullname
= symtab_to_fullname (sal
.symtab
);
320 if (get_frame_pc_if_available (fi
, &pc
))
322 = locator
->set_locator_info (get_frame_arch (fi
),
325 tui_get_function_from_frame (fi
),
330 = locator
->set_locator_info (get_frame_arch (fi
),
331 "??", _("<unavailable>"), sal
.line
, 0);
333 /* If the locator information has not changed, then frame information has
334 not changed. If frame information has not changed, then the windows'
335 contents will not change. So don't bother refreshing the windows. */
336 if (!locator_changed_p
)
339 for (struct tui_source_window_base
*win_info
: tui_source_windows ())
341 win_info
->maybe_update (fi
, sal
, locator
->line_no
, locator
->addr
);
342 win_info
->update_exec_info ();
350 = locator
->set_locator_info (NULL
, NULL
, NULL
, 0, (CORE_ADDR
) 0);
352 if (!locator_changed_p
)
355 for (struct tui_source_window_base
*win_info
: tui_source_windows ())
357 win_info
->erase_source_content ();
358 win_info
->update_exec_info ();
366 tui_show_locator_content ()
368 struct tui_locator_window
*locator
= tui_locator_win_info_ptr ();
369 locator
->rerender ();
372 /* Command to update the display with the current execution point. */
374 tui_update_command (const char *arg
, int from_tty
)
376 execute_command ("frame 0", from_tty
);
379 /* Function to initialize gdb commands, for tui window stack
383 _initialize_tui_stack (void)
385 add_com ("update", class_tui
, tui_update_command
,
386 _("Update the source window and locator to "
387 "display the current execution point."));