]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-stack.c
Move contents of tui_show_frame_info to new method
[thirdparty/binutils-gdb.git] / gdb / tui / tui-stack.c
CommitLineData
f377b406 1/* TUI display locator.
f33c6cbf 2
42a4f53d 3 Copyright (C) 1998-2019 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"
c906108c 39
6a83354a 40#include "gdb_curses.h"
c906108c 41
f2dda477
TT
42static struct tui_locator_window _locator;
43
5564c769
SC
44/* Get a printable name for the function at the address.
45 The symbol name is demangled if demangling is turned on.
46 Returns a pointer to a static area holding the result. */
5b6fe301 47static char *tui_get_function_from_frame (struct frame_info *fi);
c906108c 48
56d397a3
JK
49/* Set the full_name portion of the locator. */
50static void tui_set_locator_fullname (const char *fullname);
2e17b763
SC
51
52/* Update the locator, with the provided arguments. */
b5fca6d7
PP
53static int tui_set_locator_info (struct gdbarch *gdbarch,
54 const char *fullname,
55 const char *procname,
56 int lineno, CORE_ADDR addr);
2e17b763 57
0b39b52e 58static void tui_update_command (const char *, int);
7d6dd1e9 59\f
c906108c 60
f2dda477
TT
61/* Accessor for the locator win info. Answers a pointer to the static
62 locator win info struct. */
63struct tui_locator_window *
64tui_locator_win_info_ptr (void)
65{
66 return &_locator;
67}
68
69void
70tui_initialize_static_data ()
71{
72 tui_gen_win_info *win = tui_locator_win_info_ptr ();
73 win->width =
74 win->height =
75 win->origin.x =
76 win->origin.y =
77 win->viewport_height = 0;
78 win->handle = NULL;
79 win->is_visible = false;
80 win->title = 0;
81}
82
83
1cc6d956
MS
84/* Create the status line to display as much information as we can on
85 this single line: target name, process number, current function,
86 current line, current PC, SingleKey mode. */
3add462f
TT
87static char *
88tui_make_status_line (struct tui_locator_window *loc)
50265402 89{
5b6fe301 90 char *string;
a42a37b7 91 char line_buf[50], *pname;
5b6fe301 92 char *buf;
a42a37b7 93 int status_size;
50265402 94 int i, proc_width;
5b6fe301 95 const char *pid_name;
50265402
SC
96 int target_width;
97 int pid_width;
98 int line_width;
50265402 99
a068643d 100 std::string pid_name_holder;
d7e15655 101 if (inferior_ptid == null_ptid)
50265402
SC
102 pid_name = "No process";
103 else
a068643d
TT
104 {
105 pid_name_holder = target_pid_to_str (inferior_ptid);
106 pid_name = pid_name_holder.c_str ();
107 }
50265402
SC
108
109 target_width = strlen (target_shortname);
110 if (target_width > MAX_TARGET_WIDTH)
111 target_width = MAX_TARGET_WIDTH;
112
113 pid_width = strlen (pid_name);
114 if (pid_width > MAX_PID_WIDTH)
115 pid_width = MAX_PID_WIDTH;
a42a37b7 116
dd1abb8c 117 status_size = tui_term_width ();
50265402 118 string = (char *) xmalloc (status_size + 1);
a42a37b7 119 buf = (char*) alloca (status_size + 1);
50265402
SC
120
121 /* Translate line number and obtain its size. */
6d012f14 122 if (loc->line_no > 0)
8c042590 123 xsnprintf (line_buf, sizeof (line_buf), "%d", loc->line_no);
50265402
SC
124 else
125 strcpy (line_buf, "??");
126 line_width = strlen (line_buf);
127 if (line_width < MIN_LINE_WIDTH)
128 line_width = MIN_LINE_WIDTH;
129
130 /* Translate PC address. */
e2a678a5
TT
131 std::string pc_out (loc->gdbarch
132 ? paddress (loc->gdbarch, loc->addr)
133 : "??");
d7e74731
PA
134 const char *pc_buf = pc_out.c_str ();
135 int pc_width = pc_out.size ();
136
50265402
SC
137 /* First determine the amount of proc name width we have available.
138 The +1 are for a space separator between fields.
139 The -1 are to take into account the \0 counted by sizeof. */
140 proc_width = (status_size
141 - (target_width + 1)
142 - (pid_width + 1)
143 - (sizeof (PROC_PREFIX) - 1 + 1)
144 - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
145 - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
6d012f14 146 - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
50265402
SC
147 ? (sizeof (SINGLE_KEY) - 1 + 1)
148 : 0));
149
150 /* If there is no room to print the function name, try by removing
151 some fields. */
152 if (proc_width < MIN_PROC_WIDTH)
153 {
154 proc_width += target_width + 1;
155 target_width = 0;
156 if (proc_width < MIN_PROC_WIDTH)
157 {
158 proc_width += pid_width + 1;
159 pid_width = 0;
160 if (proc_width <= MIN_PROC_WIDTH)
161 {
162 proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
163 pc_width = 0;
164 if (proc_width < 0)
165 {
166 proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
167 line_width = 0;
168 if (proc_width < 0)
169 proc_width = 0;
170 }
171 }
172 }
173 }
174
1cc6d956 175 /* Now convert elements to string form. */
6d012f14 176 pname = loc->proc_name;
50265402 177
1cc6d956
MS
178 /* Now create the locator line from the string version of the
179 elements. We could use sprintf() here but that wouldn't ensure
180 that we don't overrun the size of the allocated buffer.
181 strcat_to_buf() will. */
50265402
SC
182 *string = (char) 0;
183
184 if (target_width > 0)
185 {
186 sprintf (buf, "%*.*s ",
187 -target_width, target_width, target_shortname);
188 strcat_to_buf (string, status_size, buf);
189 }
190 if (pid_width > 0)
191 {
192 sprintf (buf, "%*.*s ",
193 -pid_width, pid_width, pid_name);
194 strcat_to_buf (string, status_size, buf);
195 }
196
197 /* Show whether we are in SingleKey mode. */
6d012f14 198 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
50265402
SC
199 {
200 strcat_to_buf (string, status_size, SINGLE_KEY);
201 strcat_to_buf (string, status_size, " ");
202 }
203
1cc6d956 204 /* Procedure/class name. */
50265402
SC
205 if (proc_width > 0)
206 {
207 if (strlen (pname) > proc_width)
208 sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
209 1 - proc_width, proc_width - 1, pname);
210 else
211 sprintf (buf, "%s%*.*s ", PROC_PREFIX,
212 -proc_width, proc_width, pname);
213 strcat_to_buf (string, status_size, buf);
214 }
215
216 if (line_width > 0)
217 {
218 sprintf (buf, "%s%*.*s ", LINE_PREFIX,
219 -line_width, line_width, line_buf);
220 strcat_to_buf (string, status_size, buf);
221 }
222 if (pc_width > 0)
223 {
224 strcat_to_buf (string, status_size, PC_PREFIX);
225 strcat_to_buf (string, status_size, pc_buf);
226 }
227
228
229 for (i = strlen (string); i < status_size; i++)
230 string[i] = ' ';
231 string[status_size] = (char) 0;
232
50265402
SC
233 return string;
234}
235
1cc6d956
MS
236/* Get a printable name for the function at the address. The symbol
237 name is demangled if demangling is turned on. Returns a pointer to
238 a static area holding the result. */
5564c769
SC
239static char*
240tui_get_function_from_frame (struct frame_info *fi)
241{
242 static char name[256];
d7e74731 243 string_file stream;
5564c769 244
22e722e1 245 print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
d7e74731 246 &stream, demangle, "");
5564c769 247
1cc6d956
MS
248 /* Use simple heuristics to isolate the function name. The symbol
249 can be demangled and we can have function parameters. Remove
250 them because the status line is too short to display them. */
d7e74731
PA
251 const char *d = stream.c_str ();
252 if (*d == '<')
253 d++;
254 strncpy (name, d, sizeof (name) - 1);
4e2af517 255 name[sizeof (name) - 1] = 0;
d7e74731
PA
256
257 char *p = strchr (name, '(');
5564c769
SC
258 if (!p)
259 p = strchr (name, '>');
260 if (p)
261 *p = 0;
262 p = strchr (name, '+');
263 if (p)
264 *p = 0;
5564c769
SC
265 return name;
266}
c906108c 267
c906108c 268void
47d3492a 269tui_show_locator_content (void)
c906108c
SS
270{
271 char *string;
3add462f 272 struct tui_locator_window *locator;
c906108c 273
dd1abb8c 274 locator = tui_locator_win_info_ptr ();
c906108c 275
cafb3438 276 if (locator != NULL && locator->handle != NULL)
c906108c 277 {
3add462f 278 string = tui_make_status_line (locator);
50265402 279 wmove (locator->handle, 0, 0);
cae3f17b
JB
280 /* We ignore the return value from wstandout and wstandend, casting
281 them to void in order to avoid a compiler warning. The warning
282 itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
283 changing these macro to expand to code that causes the compiler
284 to generate an unused-value warning. */
ae3bccd4 285 (void) wstandout (locator->handle);
50265402
SC
286 waddstr (locator->handle, string);
287 wclrtoeol (locator->handle);
ae3bccd4 288 (void) wstandend (locator->handle);
5b81daba 289 locator->refresh_window ();
50265402
SC
290 wmove (locator->handle, 0, 0);
291 xfree (string);
c906108c 292 }
50265402 293}
c906108c 294
c906108c 295
2e17b763
SC
296/* Set the filename portion of the locator. */
297static void
56d397a3 298tui_set_locator_fullname (const char *fullname)
2e17b763 299{
3add462f 300 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
2e17b763 301
3add462f
TT
302 locator->full_name[0] = 0;
303 strcat_to_buf (locator->full_name, MAX_LOCATOR_ELEMENT_LEN, fullname);
2e17b763 304}
c906108c 305
b5fca6d7
PP
306/* Update the locator, with the provided arguments.
307
308 Returns 1 if any of the locator's fields were actually changed,
309 and 0 otherwise. */
310
311static int
13274fc3 312tui_set_locator_info (struct gdbarch *gdbarch,
56d397a3 313 const char *fullname,
08ef48c5
MS
314 const char *procname,
315 int lineno,
7d6dd1e9 316 CORE_ADDR addr)
c906108c 317{
3add462f 318 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
b5fca6d7 319 int locator_changed_p = 0;
7d6dd1e9 320
b5fca6d7
PP
321 if (procname == NULL)
322 procname = "";
323
324 if (fullname == NULL)
325 fullname = "";
326
3add462f 327 locator_changed_p |= strncmp (locator->proc_name, procname,
b5fca6d7 328 MAX_LOCATOR_ELEMENT_LEN) != 0;
3add462f
TT
329 locator_changed_p |= lineno != locator->line_no;
330 locator_changed_p |= addr != locator->addr;
331 locator_changed_p |= gdbarch != locator->gdbarch;
332 locator_changed_p |= strncmp (locator->full_name, fullname,
b5fca6d7
PP
333 MAX_LOCATOR_ELEMENT_LEN) != 0;
334
3add462f
TT
335 locator->proc_name[0] = (char) 0;
336 strcat_to_buf (locator->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
337 locator->line_no = lineno;
338 locator->addr = addr;
339 locator->gdbarch = gdbarch;
56d397a3 340 tui_set_locator_fullname (fullname);
b5fca6d7
PP
341
342 return locator_changed_p;
c7c228ed 343}
c906108c 344
56d397a3 345/* Update only the full_name portion of the locator. */
c906108c 346void
56d397a3 347tui_update_locator_fullname (const char *fullname)
c906108c 348{
56d397a3 349 tui_set_locator_fullname (fullname);
47d3492a 350 tui_show_locator_content ();
2e17b763 351}
c906108c 352
b5fca6d7 353/* Function to print the frame information for the TUI. The windows are
bbcbf914 354 refreshed only if frame information has changed since the last refresh.
b5fca6d7 355
bbcbf914
PP
356 Return 1 if frame information has changed (and windows subsequently
357 refreshed), 0 otherwise. */
358
359int
47d3492a 360tui_show_frame_info (struct frame_info *fi)
c906108c 361{
b5fca6d7 362 int locator_changed_p;
c906108c
SS
363
364 if (fi)
365 {
3add462f 366 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
e3eebbd7 367 CORE_ADDR pc;
7d6dd1e9 368
51abb421 369 symtab_and_line sal = find_frame_sal (fi);
7d6dd1e9 370
a38da35d
TT
371 const char *fullname = nullptr;
372 if (sal.symtab != nullptr)
373 fullname = symtab_to_fullname (sal.symtab);
374
e3eebbd7 375 if (get_frame_pc_if_available (fi, &pc))
b5fca6d7
PP
376 locator_changed_p
377 = tui_set_locator_info (get_frame_arch (fi),
378 (sal.symtab == 0
a38da35d 379 ? "??" : fullname),
b5fca6d7
PP
380 tui_get_function_from_frame (fi),
381 sal.line,
382 pc);
e3eebbd7 383 else
b5fca6d7
PP
384 locator_changed_p
385 = tui_set_locator_info (get_frame_arch (fi),
386 "??", _("<unavailable>"), sal.line, 0);
387
388 /* If the locator information has not changed, then frame information has
389 not changed. If frame information has not changed, then the windows'
390 contents will not change. So don't bother refreshing the windows. */
391 if (!locator_changed_p)
bbcbf914 392 return 0;
e3eebbd7 393
47d3492a 394 tui_show_locator_content ();
ad54d15b 395 for (struct tui_source_window_base *win_info : tui_source_windows ())
c906108c 396 {
a54700c6 397 win_info->maybe_update (fi, sal, locator->line_no, locator->addr);
7ba913dc 398 win_info->update_exec_info ();
c906108c 399 }
bbcbf914
PP
400
401 return 1;
c906108c
SS
402 }
403 else
404 {
b5fca6d7
PP
405 locator_changed_p
406 = tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
407
408 if (!locator_changed_p)
bbcbf914 409 return 0;
b5fca6d7 410
47d3492a 411 tui_show_locator_content ();
ad54d15b 412 for (struct tui_source_window_base *win_info : tui_source_windows ())
c906108c 413 {
caf0bc4e 414 tui_clear_source_content (win_info);
7ba913dc 415 win_info->update_exec_info ();
c906108c 416 }
bbcbf914
PP
417
418 return 1;
c906108c 419 }
7d6dd1e9 420}
c906108c 421
6ba8e26f
AC
422/* Function to initialize gdb commands, for tui window stack
423 manipulation. */
2c0b251b 424
c906108c 425void
6ba8e26f 426_initialize_tui_stack (void)
c906108c 427{
9a2b4c1b
MS
428 add_com ("update", class_tui, tui_update_command,
429 _("Update the source window and locator to "
89549d7f 430 "display the current execution point."));
41783295 431}
c906108c 432
7563e053 433/* Command to update the display with the current execution point. */
c906108c 434static void
0b39b52e 435tui_update_command (const char *arg, int from_tty)
c906108c 436{
95a6b0a1 437 execute_command ("frame 0", from_tty);
7563e053 438}