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