]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-stack.c
remove gdb_string.h
[thirdparty/binutils-gdb.git] / gdb / tui / tui-stack.c
CommitLineData
f377b406 1/* TUI display locator.
f33c6cbf 2
8acc9f48 3 Copyright (C) 1998-2013 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"
0e9f083f 31#include <string.h>
56d397a3 32#include "source.h"
d7b2e967
AC
33#include "tui/tui.h"
34#include "tui/tui-data.h"
35#include "tui/tui-stack.h"
36#include "tui/tui-wingeneral.h"
37#include "tui/tui-source.h"
38#include "tui/tui-winsource.h"
39#include "tui/tui-file.h"
c906108c 40
6a83354a 41#include "gdb_curses.h"
c906108c 42
5564c769
SC
43/* Get a printable name for the function at the address.
44 The symbol name is demangled if demangling is turned on.
45 Returns a pointer to a static area holding the result. */
5b6fe301 46static char *tui_get_function_from_frame (struct frame_info *fi);
c906108c 47
56d397a3
JK
48/* Set the full_name portion of the locator. */
49static void tui_set_locator_fullname (const char *fullname);
2e17b763
SC
50
51/* Update the locator, with the provided arguments. */
13274fc3 52static void tui_set_locator_info (struct gdbarch *gdbarch,
56d397a3 53 const char *fullname,
08ef48c5 54 const char *procname,
7d6dd1e9 55 int lineno, CORE_ADDR addr);
2e17b763 56
7563e053 57static void tui_update_command (char *, int);
7d6dd1e9 58\f
c906108c 59
1cc6d956
MS
60/* Create the status line to display as much information as we can on
61 this single line: target name, process number, current function,
62 current line, current PC, SingleKey mode. */
50265402 63static char*
5b6fe301 64tui_make_status_line (struct tui_locator_element *loc)
50265402 65{
5b6fe301 66 char *string;
a42a37b7 67 char line_buf[50], *pname;
5b6fe301 68 char *buf;
a42a37b7 69 int status_size;
50265402 70 int i, proc_width;
5b6fe301
MS
71 const char *pid_name;
72 const char *pc_buf;
50265402
SC
73 int target_width;
74 int pid_width;
75 int line_width;
76 int pc_width;
77 struct ui_file *pc_out;
78
79 if (ptid_equal (inferior_ptid, null_ptid))
80 pid_name = "No process";
81 else
82 pid_name = target_pid_to_str (inferior_ptid);
83
84 target_width = strlen (target_shortname);
85 if (target_width > MAX_TARGET_WIDTH)
86 target_width = MAX_TARGET_WIDTH;
87
88 pid_width = strlen (pid_name);
89 if (pid_width > MAX_PID_WIDTH)
90 pid_width = MAX_PID_WIDTH;
a42a37b7 91
dd1abb8c 92 status_size = tui_term_width ();
50265402 93 string = (char *) xmalloc (status_size + 1);
a42a37b7 94 buf = (char*) alloca (status_size + 1);
50265402
SC
95
96 /* Translate line number and obtain its size. */
6d012f14 97 if (loc->line_no > 0)
8c042590 98 xsnprintf (line_buf, sizeof (line_buf), "%d", loc->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. */
106 pc_out = tui_sfileopen (128);
2d5f09f0
UW
107 fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??",
108 pc_out);
50265402
SC
109 pc_buf = tui_file_get_strbuf (pc_out);
110 pc_width = strlen (pc_buf);
111
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 convert elements to string form. */
6d012f14 151 pname = loc->proc_name;
50265402 152
1cc6d956
MS
153 /* Now create the locator line from the string version of the
154 elements. We could use sprintf() here but that wouldn't ensure
155 that we don't overrun the size of the allocated buffer.
156 strcat_to_buf() will. */
50265402
SC
157 *string = (char) 0;
158
159 if (target_width > 0)
160 {
161 sprintf (buf, "%*.*s ",
162 -target_width, target_width, target_shortname);
163 strcat_to_buf (string, status_size, buf);
164 }
165 if (pid_width > 0)
166 {
167 sprintf (buf, "%*.*s ",
168 -pid_width, pid_width, pid_name);
169 strcat_to_buf (string, status_size, buf);
170 }
171
172 /* Show whether we are in SingleKey mode. */
6d012f14 173 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
50265402
SC
174 {
175 strcat_to_buf (string, status_size, SINGLE_KEY);
176 strcat_to_buf (string, status_size, " ");
177 }
178
1cc6d956 179 /* Procedure/class name. */
50265402
SC
180 if (proc_width > 0)
181 {
182 if (strlen (pname) > proc_width)
183 sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
184 1 - proc_width, proc_width - 1, pname);
185 else
186 sprintf (buf, "%s%*.*s ", PROC_PREFIX,
187 -proc_width, proc_width, pname);
188 strcat_to_buf (string, status_size, buf);
189 }
190
191 if (line_width > 0)
192 {
193 sprintf (buf, "%s%*.*s ", LINE_PREFIX,
194 -line_width, line_width, line_buf);
195 strcat_to_buf (string, status_size, buf);
196 }
197 if (pc_width > 0)
198 {
199 strcat_to_buf (string, status_size, PC_PREFIX);
200 strcat_to_buf (string, status_size, pc_buf);
201 }
202
203
204 for (i = strlen (string); i < status_size; i++)
205 string[i] = ' ';
206 string[status_size] = (char) 0;
207
208 ui_file_delete (pc_out);
209 return string;
210}
211
1cc6d956
MS
212/* Get a printable name for the function at the address. The symbol
213 name is demangled if demangling is turned on. Returns a pointer to
214 a static area holding the result. */
5564c769
SC
215static char*
216tui_get_function_from_frame (struct frame_info *fi)
217{
218 static char name[256];
219 struct ui_file *stream = tui_sfileopen (256);
220 char *p;
221
22e722e1
DJ
222 print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
223 stream, demangle, "");
5564c769
SC
224 p = tui_file_get_strbuf (stream);
225
1cc6d956
MS
226 /* Use simple heuristics to isolate the function name. The symbol
227 can be demangled and we can have function parameters. Remove
228 them because the status line is too short to display them. */
5564c769
SC
229 if (*p == '<')
230 p++;
086dbf66 231 strncpy (name, p, sizeof (name) - 1);
4e2af517 232 name[sizeof (name) - 1] = 0;
5564c769
SC
233 p = strchr (name, '(');
234 if (!p)
235 p = strchr (name, '>');
236 if (p)
237 *p = 0;
238 p = strchr (name, '+');
239 if (p)
240 *p = 0;
241 ui_file_delete (stream);
242 return name;
243}
c906108c 244
c906108c 245void
47d3492a 246tui_show_locator_content (void)
c906108c
SS
247{
248 char *string;
5b6fe301 249 struct tui_gen_win_info *locator;
c906108c 250
dd1abb8c 251 locator = tui_locator_win_info_ptr ();
c906108c 252
6d012f14 253 if (locator != NULL && locator->handle != (WINDOW *) NULL)
c906108c 254 {
5b6fe301 255 struct tui_win_element *element;
50265402 256
2a8854a7 257 element = (struct tui_win_element *) locator->content[0];
50265402 258
6d012f14 259 string = tui_make_status_line (&element->which_element.locator);
50265402 260 wmove (locator->handle, 0, 0);
cae3f17b
JB
261 /* We ignore the return value from wstandout and wstandend, casting
262 them to void in order to avoid a compiler warning. The warning
263 itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
264 changing these macro to expand to code that causes the compiler
265 to generate an unused-value warning. */
ae3bccd4 266 (void) wstandout (locator->handle);
50265402
SC
267 waddstr (locator->handle, string);
268 wclrtoeol (locator->handle);
ae3bccd4 269 (void) wstandend (locator->handle);
ec7d9e56 270 tui_refresh_win (locator);
50265402
SC
271 wmove (locator->handle, 0, 0);
272 xfree (string);
6d012f14 273 locator->content_in_use = TRUE;
c906108c 274 }
50265402 275}
c906108c 276
c906108c 277
2e17b763
SC
278/* Set the filename portion of the locator. */
279static void
56d397a3 280tui_set_locator_fullname (const char *fullname)
2e17b763 281{
5b6fe301
MS
282 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
283 struct tui_locator_element *element;
2e17b763 284
22940a24 285 if (locator->content[0] == NULL)
7d6dd1e9 286 {
56d397a3 287 tui_set_locator_info (NULL, fullname, NULL, 0, 0);
7d6dd1e9
SC
288 return;
289 }
2e17b763 290
9a2b4c1b
MS
291 element = &((struct tui_win_element *)
292 locator->content[0])->which_element.locator;
56d397a3
JK
293 element->full_name[0] = 0;
294 strcat_to_buf (element->full_name, MAX_LOCATOR_ELEMENT_LEN, fullname);
2e17b763 295}
c906108c 296
c7c228ed 297/* Update the locator, with the provided arguments. */
2e17b763 298static void
13274fc3 299tui_set_locator_info (struct gdbarch *gdbarch,
56d397a3 300 const char *fullname,
08ef48c5
MS
301 const char *procname,
302 int lineno,
7d6dd1e9 303 CORE_ADDR addr)
c906108c 304{
5b6fe301
MS
305 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
306 struct tui_locator_element *element;
7d6dd1e9
SC
307
308 /* Allocate the locator content if necessary. */
6d012f14 309 if (locator->content_size <= 0)
7d6dd1e9 310 {
22940a24 311 locator->content = (void **) tui_alloc_content (1, locator->type);
6d012f14 312 locator->content_size = 1;
7d6dd1e9
SC
313 }
314
9a2b4c1b
MS
315 element = &((struct tui_win_element *)
316 locator->content[0])->which_element.locator;
6d012f14
AC
317 element->proc_name[0] = (char) 0;
318 strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
319 element->line_no = lineno;
c774cec6 320 element->addr = addr;
13274fc3 321 element->gdbarch = gdbarch;
56d397a3 322 tui_set_locator_fullname (fullname);
c7c228ed 323}
c906108c 324
56d397a3 325/* Update only the full_name portion of the locator. */
c906108c 326void
56d397a3 327tui_update_locator_fullname (const char *fullname)
c906108c 328{
56d397a3 329 tui_set_locator_fullname (fullname);
47d3492a 330 tui_show_locator_content ();
2e17b763 331}
c906108c 332
7d6dd1e9 333/* Function to print the frame information for the TUI. */
c906108c 334void
47d3492a 335tui_show_frame_info (struct frame_info *fi)
c906108c 336{
5b6fe301 337 struct tui_win_info *win_info;
d02c80cd 338 int i;
c906108c
SS
339
340 if (fi)
341 {
d02c80cd 342 int start_line, i;
c906108c 343 CORE_ADDR low;
5b6fe301 344 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
6ba8e26f 345 int source_already_displayed;
7d6dd1e9 346 struct symtab_and_line sal;
e3eebbd7 347 CORE_ADDR pc;
7d6dd1e9 348
3d7442da 349 find_frame_sal (fi, &sal);
7d6dd1e9 350
6ba8e26f 351 source_already_displayed = sal.symtab != 0
56d397a3 352 && tui_source_is_displayed (symtab_to_fullname (sal.symtab));
e3eebbd7
PA
353
354 if (get_frame_pc_if_available (fi, &pc))
355 tui_set_locator_info (get_frame_arch (fi),
56d397a3
JK
356 (sal.symtab == 0
357 ? "??" : symtab_to_fullname (sal.symtab)),
e3eebbd7
PA
358 tui_get_function_from_frame (fi),
359 sal.line,
360 pc);
361 else
362 tui_set_locator_info (get_frame_arch (fi),
363 "??", _("<unavailable>"), sal.line, 0);
364
47d3492a 365 tui_show_locator_content ();
6d012f14 366 start_line = 0;
dd1abb8c 367 for (i = 0; i < (tui_source_windows ())->count; i++)
c906108c 368 {
2a8854a7 369 union tui_which_element *item;
1c5313c5 370
96c1eda2 371 win_info = (tui_source_windows ())->list[i];
a4b99e53 372
9a2b4c1b
MS
373 item = &((struct tui_win_element *)
374 locator->content[0])->which_element;
6d012f14 375 if (win_info == TUI_SRC_WIN)
c906108c 376 {
6d012f14
AC
377 start_line = (item->locator.line_no -
378 (win_info->generic.viewport_height / 2)) + 1;
379 if (start_line <= 0)
380 start_line = 1;
c906108c
SS
381 }
382 else
383 {
2c02bd72
DE
384 if (find_pc_partial_function (get_frame_pc (fi),
385 (const char **) NULL,
87177905 386 &low, (CORE_ADDR) 0) == 0)
c04b3e8f
JK
387 {
388 /* There is no symbol available for current PC. There is no
389 safe way how to "disassemble backwards". */
390 low = get_frame_pc (fi);
391 }
c906108c 392 else
13274fc3
UW
393 low = tui_get_low_disassembly_address (get_frame_arch (fi),
394 low, get_frame_pc (fi));
c906108c
SS
395 }
396
6d012f14 397 if (win_info == TUI_SRC_WIN)
c906108c 398 {
362c05fe 399 struct tui_line_or_address l;
1c5313c5 400
362c05fe
AS
401 l.loa = LOA_LINE;
402 l.u.line_no = start_line;
6ba8e26f 403 if (!(source_already_displayed
9a2b4c1b
MS
404 && tui_line_is_displayed (item->locator.line_no,
405 win_info, TRUE)))
13274fc3
UW
406 tui_update_source_window (win_info, get_frame_arch (fi),
407 sal.symtab, l, TRUE);
c906108c 408 else
a4b99e53 409 {
362c05fe 410 l.u.line_no = item->locator.line_no;
6d012f14 411 tui_set_is_exec_point_at (l, win_info);
a4b99e53 412 }
c906108c
SS
413 }
414 else
415 {
6d012f14 416 if (win_info == TUI_DISASM_WIN)
c906108c 417 {
362c05fe 418 struct tui_line_or_address a;
1c5313c5 419
362c05fe
AS
420 a.loa = LOA_ADDRESS;
421 a.u.addr = low;
9a2b4c1b
MS
422 if (!tui_addr_is_displayed (item->locator.addr,
423 win_info, TRUE))
13274fc3
UW
424 tui_update_source_window (win_info, get_frame_arch (fi),
425 sal.symtab, a, TRUE);
c906108c 426 else
a4b99e53 427 {
362c05fe 428 a.u.addr = item->locator.addr;
6d012f14 429 tui_set_is_exec_point_at (a, win_info);
a4b99e53 430 }
c906108c
SS
431 }
432 }
6d012f14 433 tui_update_exec_info (win_info);
c906108c
SS
434 }
435 }
436 else
437 {
13274fc3 438 tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
47d3492a 439 tui_show_locator_content ();
dd1abb8c 440 for (i = 0; i < (tui_source_windows ())->count; i++)
c906108c 441 {
96c1eda2 442 win_info = (tui_source_windows ())->list[i];
6d012f14
AC
443 tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
444 tui_update_exec_info (win_info);
c906108c
SS
445 }
446 }
7d6dd1e9 447}
c906108c 448
6ba8e26f
AC
449/* Function to initialize gdb commands, for tui window stack
450 manipulation. */
2c0b251b
PA
451
452/* Provide a prototype to silence -Wmissing-prototypes. */
453extern initialize_file_ftype _initialize_tui_stack;
454
c906108c 455void
6ba8e26f 456_initialize_tui_stack (void)
c906108c 457{
9a2b4c1b
MS
458 add_com ("update", class_tui, tui_update_command,
459 _("Update the source window and locator to "
460 "display the current execution point.\n"));
41783295 461}
c906108c 462
7563e053 463/* Command to update the display with the current execution point. */
c906108c 464static void
7563e053 465tui_update_command (char *arg, int from_tty)
c906108c 466{
7563e053 467 char cmd[sizeof("frame 0")];
c906108c 468
7563e053
SC
469 strcpy (cmd, "frame 0");
470 execute_command (cmd, from_tty);
471}