Simplify tui_source_window_base::maybe_update method
[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
7d6dd1e9 56\f
c906108c 57
f2dda477
TT
58/* Accessor for the locator win info. Answers a pointer to the static
59 locator win info struct. */
60struct tui_locator_window *
61tui_locator_win_info_ptr (void)
62{
63 return &_locator;
64}
65
71a25ed2
TT
66std::string
67tui_locator_window::make_status_line () const
50265402 68{
71a25ed2 69 char line_buf[50];
a42a37b7 70 int status_size;
f8532154 71 int proc_width;
5b6fe301 72 const char *pid_name;
50265402
SC
73 int target_width;
74 int pid_width;
75 int line_width;
50265402 76
a068643d 77 std::string pid_name_holder;
d7e15655 78 if (inferior_ptid == null_ptid)
50265402
SC
79 pid_name = "No process";
80 else
a068643d
TT
81 {
82 pid_name_holder = target_pid_to_str (inferior_ptid);
83 pid_name = pid_name_holder.c_str ();
84 }
50265402
SC
85
86 target_width = strlen (target_shortname);
87 if (target_width > MAX_TARGET_WIDTH)
88 target_width = MAX_TARGET_WIDTH;
89
90 pid_width = strlen (pid_name);
91 if (pid_width > MAX_PID_WIDTH)
92 pid_width = MAX_PID_WIDTH;
a42a37b7 93
71a25ed2 94 status_size = width;
50265402
SC
95
96 /* Translate line number and obtain its size. */
71a25ed2
TT
97 if (line_no > 0)
98 xsnprintf (line_buf, sizeof (line_buf), "%d", line_no);
50265402
SC
99 else
100 strcpy (line_buf, "??");
101 line_width = strlen (line_buf);
102 if (line_width < MIN_LINE_WIDTH)
103 line_width = MIN_LINE_WIDTH;
104
105 /* Translate PC address. */
71a25ed2
TT
106 std::string pc_out (gdbarch
107 ? paddress (gdbarch, addr)
e2a678a5 108 : "??");
d7e74731
PA
109 const char *pc_buf = pc_out.c_str ();
110 int pc_width = pc_out.size ();
111
50265402
SC
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
116 - (target_width + 1)
117 - (pid_width + 1)
118 - (sizeof (PROC_PREFIX) - 1 + 1)
119 - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
120 - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
6d012f14 121 - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
50265402
SC
122 ? (sizeof (SINGLE_KEY) - 1 + 1)
123 : 0));
124
125 /* If there is no room to print the function name, try by removing
126 some fields. */
127 if (proc_width < MIN_PROC_WIDTH)
128 {
129 proc_width += target_width + 1;
130 target_width = 0;
131 if (proc_width < MIN_PROC_WIDTH)
132 {
133 proc_width += pid_width + 1;
134 pid_width = 0;
135 if (proc_width <= MIN_PROC_WIDTH)
136 {
137 proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
138 pc_width = 0;
139 if (proc_width < 0)
140 {
141 proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
142 line_width = 0;
143 if (proc_width < 0)
144 proc_width = 0;
145 }
146 }
147 }
148 }
149
1cc6d956 150 /* Now create the locator line from the string version of the
f8532154
TT
151 elements. */
152 string_file string;
50265402
SC
153
154 if (target_width > 0)
f8532154 155 string.printf ("%*.*s ", -target_width, target_width, target_shortname);
50265402 156 if (pid_width > 0)
f8532154
TT
157 string.printf ("%*.*s ", -pid_width, pid_width, pid_name);
158
50265402 159 /* Show whether we are in SingleKey mode. */
6d012f14 160 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
50265402 161 {
f8532154
TT
162 string.puts (SINGLE_KEY);
163 string.puts (" ");
50265402
SC
164 }
165
1cc6d956 166 /* Procedure/class name. */
50265402
SC
167 if (proc_width > 0)
168 {
9923f347 169 if (proc_name.size () > proc_width)
f8532154 170 string.printf ("%s%*.*s* ", PROC_PREFIX,
9923f347 171 1 - proc_width, proc_width - 1, proc_name.c_str ());
50265402 172 else
f8532154 173 string.printf ("%s%*.*s ", PROC_PREFIX,
9923f347 174 -proc_width, proc_width, proc_name.c_str ());
50265402
SC
175 }
176
177 if (line_width > 0)
f8532154
TT
178 string.printf ("%s%*.*s ", LINE_PREFIX,
179 -line_width, line_width, line_buf);
50265402
SC
180 if (pc_width > 0)
181 {
f8532154
TT
182 string.puts (PC_PREFIX);
183 string.puts (pc_buf);
50265402 184 }
50265402 185
f8532154
TT
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 ());
190
191 return std::move (string.string ());
50265402
SC
192}
193
1cc6d956
MS
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. */
5564c769
SC
197static char*
198tui_get_function_from_frame (struct frame_info *fi)
199{
200 static char name[256];
d7e74731 201 string_file stream;
5564c769 202
22e722e1 203 print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
d7e74731 204 &stream, demangle, "");
5564c769 205
1cc6d956
MS
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. */
d7e74731
PA
209 const char *d = stream.c_str ();
210 if (*d == '<')
211 d++;
212 strncpy (name, d, sizeof (name) - 1);
4e2af517 213 name[sizeof (name) - 1] = 0;
d7e74731
PA
214
215 char *p = strchr (name, '(');
5564c769
SC
216 if (!p)
217 p = strchr (name, '>');
218 if (p)
219 *p = 0;
220 p = strchr (name, '+');
221 if (p)
222 *p = 0;
5564c769
SC
223 return name;
224}
c906108c 225
c906108c 226void
99ab33fb 227tui_locator_window::rerender ()
c906108c 228{
99ab33fb 229 if (handle != NULL)
c906108c 230 {
71a25ed2 231 std::string string = make_status_line ();
7523da63
TT
232 scrollok (handle.get (), FALSE);
233 wmove (handle.get (), 0, 0);
cae3f17b
JB
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. */
7523da63
TT
239 (void) wstandout (handle.get ());
240 waddstr (handle.get (), string.c_str ());
241 wclrtoeol (handle.get ());
242 (void) wstandend (handle.get ());
99ab33fb 243 refresh_window ();
7523da63 244 wmove (handle.get (), 0, 0);
c906108c 245 }
50265402 246}
c906108c 247
e594a5d1
TT
248/* See tui-stack.h. */
249
250void
251tui_locator_window::set_locator_fullname (const char *fullname)
2e17b763 252{
9923f347 253 full_name = fullname;
900ac242 254 rerender ();
2e17b763 255}
c906108c 256
e594a5d1 257/* See tui-stack.h. */
b5fca6d7 258
e594a5d1
TT
259bool
260tui_locator_window::set_locator_info (struct gdbarch *gdbarch_in,
261 const char *fullname,
262 const char *procname,
263 int lineno,
264 CORE_ADDR addr_in)
c906108c 265{
e594a5d1 266 bool locator_changed_p = false;
7d6dd1e9 267
b5fca6d7
PP
268 if (procname == NULL)
269 procname = "";
270
271 if (fullname == NULL)
272 fullname = "";
273
9923f347 274 locator_changed_p |= proc_name != procname;
e594a5d1
TT
275 locator_changed_p |= lineno != line_no;
276 locator_changed_p |= addr_in != addr;
277 locator_changed_p |= gdbarch_in != gdbarch;
9923f347 278 locator_changed_p |= full_name != fullname;
b5fca6d7 279
9923f347 280 proc_name = procname;
e594a5d1
TT
281 line_no = lineno;
282 addr = addr_in;
283 gdbarch = gdbarch_in;
284 set_locator_fullname (fullname);
b5fca6d7
PP
285
286 return locator_changed_p;
c7c228ed 287}
c906108c 288
56d397a3 289/* Update only the full_name portion of the locator. */
c906108c 290void
c1b167d7 291tui_update_locator_fullname (struct symtab *symtab)
c906108c 292{
e594a5d1
TT
293 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
294
c1b167d7
TT
295 const char *fullname;
296 if (symtab != nullptr)
297 fullname = symtab_to_fullname (symtab);
298 else
299 fullname = "??";
e594a5d1 300 locator->set_locator_fullname (fullname);
2e17b763 301}
c906108c 302
b5fca6d7 303/* Function to print the frame information for the TUI. The windows are
bbcbf914 304 refreshed only if frame information has changed since the last refresh.
b5fca6d7 305
bbcbf914
PP
306 Return 1 if frame information has changed (and windows subsequently
307 refreshed), 0 otherwise. */
308
309int
47d3492a 310tui_show_frame_info (struct frame_info *fi)
c906108c 311{
e594a5d1
TT
312 bool locator_changed_p;
313 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
c906108c
SS
314
315 if (fi)
316 {
e3eebbd7 317 CORE_ADDR pc;
7d6dd1e9 318
51abb421 319 symtab_and_line sal = find_frame_sal (fi);
7d6dd1e9 320
a38da35d
TT
321 const char *fullname = nullptr;
322 if (sal.symtab != nullptr)
323 fullname = symtab_to_fullname (sal.symtab);
324
e3eebbd7 325 if (get_frame_pc_if_available (fi, &pc))
b5fca6d7 326 locator_changed_p
e594a5d1
TT
327 = locator->set_locator_info (get_frame_arch (fi),
328 (sal.symtab == 0
329 ? "??" : fullname),
330 tui_get_function_from_frame (fi),
331 sal.line,
332 pc);
e3eebbd7 333 else
b5fca6d7 334 locator_changed_p
e594a5d1
TT
335 = locator->set_locator_info (get_frame_arch (fi),
336 "??", _("<unavailable>"), sal.line, 0);
b5fca6d7
PP
337
338 /* If the locator information has not changed, then frame information has
339 not changed. If frame information has not changed, then the windows'
340 contents will not change. So don't bother refreshing the windows. */
341 if (!locator_changed_p)
bbcbf914 342 return 0;
e3eebbd7 343
1ae58f0c
TT
344 /* find_frame_sal does not always set PC, but we want to ensure
345 that it is available in the SAL. */
346 sal.pc = pc;
347
ad54d15b 348 for (struct tui_source_window_base *win_info : tui_source_windows ())
c906108c 349 {
1ae58f0c 350 win_info->maybe_update (fi, sal);
7ba913dc 351 win_info->update_exec_info ();
c906108c 352 }
bbcbf914
PP
353
354 return 1;
c906108c
SS
355 }
356 else
357 {
b5fca6d7 358 locator_changed_p
e594a5d1 359 = locator->set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
b5fca6d7
PP
360
361 if (!locator_changed_p)
bbcbf914 362 return 0;
b5fca6d7 363
ad54d15b 364 for (struct tui_source_window_base *win_info : tui_source_windows ())
c906108c 365 {
c398c3d0 366 win_info->erase_source_content ();
7ba913dc 367 win_info->update_exec_info ();
c906108c 368 }
bbcbf914
PP
369
370 return 1;
c906108c 371 }
7d6dd1e9 372}
c906108c 373
99ab33fb
TT
374void
375tui_show_locator_content ()
376{
377 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
378 locator->rerender ();
379}
380
12a8555a
TT
381/* Command to update the display with the current execution point. */
382static void
383tui_update_command (const char *arg, int from_tty)
384{
385 execute_command ("frame 0", from_tty);
386}
387
6ba8e26f
AC
388/* Function to initialize gdb commands, for tui window stack
389 manipulation. */
2c0b251b 390
c906108c 391void
6ba8e26f 392_initialize_tui_stack (void)
c906108c 393{
9a2b4c1b
MS
394 add_com ("update", class_tui, tui_update_command,
395 _("Update the source window and locator to "
89549d7f 396 "display the current execution point."));
41783295 397}
This page took 2.175977 seconds and 4 git commands to generate.