Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / tui / tui-stack.c
CommitLineData
f377b406 1/* TUI display locator.
f33c6cbf 2
88b9d363 3 Copyright (C) 1998-2022 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
5 Contributed by Hewlett-Packard Company.
6
7 This file is part of GDB.
8
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
12 (at your option) any later version.
13
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.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
23#include "symtab.h"
24#include "breakpoint.h"
25#include "frame.h"
75fd9bc1 26#include "command.h"
50265402
SC
27#include "inferior.h"
28#include "target.h"
7563e053 29#include "top.h"
50f182aa 30#include "gdb-demangle.h"
56d397a3 31#include "source.h"
d7b2e967
AC
32#include "tui/tui.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"
f237f998 39#include "tui/tui-location.h"
c906108c 40
6a83354a 41#include "gdb_curses.h"
c906108c 42
973961bd
TT
43#define PROC_PREFIX "In: "
44#define LINE_PREFIX "L"
45#define PC_PREFIX "PC: "
46
e555083f
TT
47/* Strings to display in the TUI status line. */
48#define SINGLE_KEY "(SingleKey)"
49
973961bd
TT
50/* Minimum/Maximum length of some fields displayed in the TUI status
51 line. */
52#define MIN_LINE_WIDTH 4 /* Use at least 4 digits for line
53 numbers. */
54#define MIN_PROC_WIDTH 12
55#define MAX_TARGET_WIDTH 10
56#define MAX_PID_WIDTH 19
57
7d6dd1e9 58\f
c906108c 59
71a25ed2
TT
60std::string
61tui_locator_window::make_status_line () const
50265402 62{
71a25ed2 63 char line_buf[50];
a42a37b7 64 int status_size;
f8532154 65 int proc_width;
5b6fe301 66 const char *pid_name;
50265402
SC
67 int target_width;
68 int pid_width;
69 int line_width;
50265402 70
a068643d 71 std::string pid_name_holder;
d7e15655 72 if (inferior_ptid == null_ptid)
50265402
SC
73 pid_name = "No process";
74 else
a068643d
TT
75 {
76 pid_name_holder = target_pid_to_str (inferior_ptid);
77 pid_name = pid_name_holder.c_str ();
78 }
50265402 79
d777bf0d 80 target_width = strlen (target_shortname ());
50265402
SC
81 if (target_width > MAX_TARGET_WIDTH)
82 target_width = MAX_TARGET_WIDTH;
83
84 pid_width = strlen (pid_name);
85 if (pid_width > MAX_PID_WIDTH)
86 pid_width = MAX_PID_WIDTH;
a42a37b7 87
71a25ed2 88 status_size = width;
50265402
SC
89
90 /* Translate line number and obtain its size. */
f237f998 91 int line_no = tui_location.line_no ();
71a25ed2
TT
92 if (line_no > 0)
93 xsnprintf (line_buf, sizeof (line_buf), "%d", line_no);
50265402
SC
94 else
95 strcpy (line_buf, "??");
96 line_width = strlen (line_buf);
97 if (line_width < MIN_LINE_WIDTH)
98 line_width = MIN_LINE_WIDTH;
99
100 /* Translate PC address. */
f237f998
AB
101 struct gdbarch *gdbarch = tui_location.gdbarch ();
102 CORE_ADDR addr = tui_location.addr ();
71a25ed2
TT
103 std::string pc_out (gdbarch
104 ? paddress (gdbarch, addr)
e2a678a5 105 : "??");
d7e74731
PA
106 const char *pc_buf = pc_out.c_str ();
107 int pc_width = pc_out.size ();
108
50265402
SC
109 /* First determine the amount of proc name width we have available.
110 The +1 are for a space separator between fields.
111 The -1 are to take into account the \0 counted by sizeof. */
112 proc_width = (status_size
dda83cd7
SM
113 - (target_width + 1)
114 - (pid_width + 1)
115 - (sizeof (PROC_PREFIX) - 1 + 1)
116 - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
117 - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
118 - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
119 ? (sizeof (SINGLE_KEY) - 1 + 1)
120 : 0));
50265402
SC
121
122 /* If there is no room to print the function name, try by removing
123 some fields. */
124 if (proc_width < MIN_PROC_WIDTH)
125 {
126 proc_width += target_width + 1;
127 target_width = 0;
128 if (proc_width < MIN_PROC_WIDTH)
dda83cd7
SM
129 {
130 proc_width += pid_width + 1;
131 pid_width = 0;
132 if (proc_width <= MIN_PROC_WIDTH)
133 {
134 proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
135 pc_width = 0;
136 if (proc_width < 0)
137 {
138 proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
139 line_width = 0;
140 if (proc_width < 0)
141 proc_width = 0;
142 }
143 }
144 }
50265402
SC
145 }
146
1cc6d956 147 /* Now create the locator line from the string version of the
f8532154
TT
148 elements. */
149 string_file string;
50265402
SC
150
151 if (target_width > 0)
d777bf0d 152 string.printf ("%*.*s ", -target_width, target_width, target_shortname ());
50265402 153 if (pid_width > 0)
f8532154
TT
154 string.printf ("%*.*s ", -pid_width, pid_width, pid_name);
155
50265402 156 /* Show whether we are in SingleKey mode. */
6d012f14 157 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
50265402 158 {
f8532154
TT
159 string.puts (SINGLE_KEY);
160 string.puts (" ");
50265402
SC
161 }
162
1cc6d956 163 /* Procedure/class name. */
50265402
SC
164 if (proc_width > 0)
165 {
f237f998 166 const std::string &proc_name = tui_location.proc_name ();
9923f347 167 if (proc_name.size () > proc_width)
dda83cd7 168 string.printf ("%s%*.*s* ", PROC_PREFIX,
9923f347 169 1 - proc_width, proc_width - 1, proc_name.c_str ());
50265402 170 else
dda83cd7 171 string.printf ("%s%*.*s ", PROC_PREFIX,
9923f347 172 -proc_width, proc_width, proc_name.c_str ());
50265402
SC
173 }
174
175 if (line_width > 0)
f8532154
TT
176 string.printf ("%s%*.*s ", LINE_PREFIX,
177 -line_width, line_width, line_buf);
50265402
SC
178 if (pc_width > 0)
179 {
f8532154
TT
180 string.puts (PC_PREFIX);
181 string.puts (pc_buf);
50265402 182 }
50265402 183
f8532154
TT
184 if (string.size () < status_size)
185 string.puts (n_spaces (status_size - string.size ()));
186 else if (string.size () > status_size)
187 string.string ().erase (status_size, string.size ());
188
189 return std::move (string.string ());
50265402
SC
190}
191
1cc6d956
MS
192/* Get a printable name for the function at the address. The symbol
193 name is demangled if demangling is turned on. Returns a pointer to
194 a static area holding the result. */
5564c769
SC
195static char*
196tui_get_function_from_frame (struct frame_info *fi)
197{
198 static char name[256];
d7e74731 199 string_file stream;
5564c769 200
22e722e1 201 print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
d7e74731 202 &stream, demangle, "");
5564c769 203
1cc6d956
MS
204 /* Use simple heuristics to isolate the function name. The symbol
205 can be demangled and we can have function parameters. Remove
206 them because the status line is too short to display them. */
d7e74731
PA
207 const char *d = stream.c_str ();
208 if (*d == '<')
209 d++;
210 strncpy (name, d, sizeof (name) - 1);
4e2af517 211 name[sizeof (name) - 1] = 0;
d7e74731
PA
212
213 char *p = strchr (name, '(');
5564c769
SC
214 if (!p)
215 p = strchr (name, '>');
216 if (p)
217 *p = 0;
218 p = strchr (name, '+');
219 if (p)
220 *p = 0;
5564c769
SC
221 return name;
222}
c906108c 223
c906108c 224void
99ab33fb 225tui_locator_window::rerender ()
c906108c 226{
f237f998
AB
227 gdb_assert (handle != NULL);
228
229 std::string string = make_status_line ();
230 scrollok (handle.get (), FALSE);
231 wmove (handle.get (), 0, 0);
232 /* We ignore the return value from wstandout and wstandend, casting them
233 to void in order to avoid a compiler warning. The warning itself was
234 introduced by a patch to ncurses 5.7 dated 2009-08-29, changing these
235 macro to expand to code that causes the compiler to generate an
236 unused-value warning. */
237 (void) wstandout (handle.get ());
238 waddstr (handle.get (), string.c_str ());
239 wclrtoeol (handle.get ());
240 (void) wstandend (handle.get ());
241 refresh_window ();
242 wmove (handle.get (), 0, 0);
2e17b763 243}
c906108c 244
b5fca6d7 245/* Function to print the frame information for the TUI. The windows are
bbcbf914 246 refreshed only if frame information has changed since the last refresh.
b5fca6d7 247
eb390f49
TT
248 Return true if frame information has changed (and windows
249 subsequently refreshed), false otherwise. */
bbcbf914 250
eb390f49 251bool
47d3492a 252tui_show_frame_info (struct frame_info *fi)
c906108c 253{
e594a5d1 254 bool locator_changed_p;
c906108c 255
f237f998 256 if (fi != nullptr)
c906108c 257 {
51abb421 258 symtab_and_line sal = find_frame_sal (fi);
7d6dd1e9 259
0ab92974
TT
260 const char *func_name;
261 /* find_frame_sal does not always set PC, but we want to ensure
262 that it is available in the SAL. */
263 if (get_frame_pc_if_available (fi, &sal.pc))
264 func_name = tui_get_function_from_frame (fi);
e3eebbd7 265 else
0ab92974
TT
266 func_name = _("<unavailable>");
267
f237f998
AB
268 locator_changed_p
269 = tui_location.set_location (get_frame_arch (fi), sal, func_name);
b5fca6d7
PP
270
271 /* If the locator information has not changed, then frame information has
272 not changed. If frame information has not changed, then the windows'
273 contents will not change. So don't bother refreshing the windows. */
274 if (!locator_changed_p)
eb390f49 275 return false;
e3eebbd7 276
ad54d15b 277 for (struct tui_source_window_base *win_info : tui_source_windows ())
c906108c 278 {
1ae58f0c 279 win_info->maybe_update (fi, sal);
7ba913dc 280 win_info->update_exec_info ();
c906108c
SS
281 }
282 }
283 else
284 {
0ab92974
TT
285 symtab_and_line sal {};
286
f237f998 287 locator_changed_p = tui_location.set_location (NULL, sal, "");
b5fca6d7
PP
288
289 if (!locator_changed_p)
eb390f49 290 return false;
b5fca6d7 291
ad54d15b 292 for (struct tui_source_window_base *win_info : tui_source_windows ())
ae4393e2 293 win_info->erase_source_content ();
c906108c 294 }
eb390f49
TT
295
296 return true;
7d6dd1e9 297}
c906108c 298
99ab33fb
TT
299void
300tui_show_locator_content ()
301{
f237f998
AB
302 if (tui_is_window_visible (STATUS_WIN))
303 TUI_STATUS_WIN->rerender ();
99ab33fb
TT
304}
305
12a8555a
TT
306/* Command to update the display with the current execution point. */
307static void
308tui_update_command (const char *arg, int from_tty)
309{
310 execute_command ("frame 0", from_tty);
311}
312
6ba8e26f
AC
313/* Function to initialize gdb commands, for tui window stack
314 manipulation. */
2c0b251b 315
6c265988 316void _initialize_tui_stack ();
c906108c 317void
6c265988 318_initialize_tui_stack ()
c906108c 319{
9a2b4c1b
MS
320 add_com ("update", class_tui, tui_update_command,
321 _("Update the source window and locator to "
283be8bf
TT
322 "display the current execution point.\n\
323Usage: update"));
41783295 324}
This page took 2.935913 seconds and 4 git commands to generate.