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