2008-02-21 Pedro Alves <pedro@codesorcery.com>
[deliverable/binutils-gdb.git] / gdb / tui / tui-stack.c
CommitLineData
f377b406 1/* TUI display locator.
f33c6cbf 2
0fb0cc75
JB
3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008,
4 2009 Free Software Foundation, Inc.
f33c6cbf 5
f377b406
SC
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
22
23#include "defs.h"
24#include "symtab.h"
25#include "breakpoint.h"
26#include "frame.h"
75fd9bc1 27#include "command.h"
50265402
SC
28#include "inferior.h"
29#include "target.h"
7563e053 30#include "top.h"
6d012f14 31#include "gdb_string.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
5564c769
SC
42/* Get a printable name for the function at the address.
43 The symbol name is demangled if demangling is turned on.
44 Returns a pointer to a static area holding the result. */
5b6fe301 45static char *tui_get_function_from_frame (struct frame_info *fi);
c906108c 46
2e17b763
SC
47/* Set the filename portion of the locator. */
48static void tui_set_locator_filename (const char *filename);
49
50/* Update the locator, with the provided arguments. */
08ef48c5
MS
51static void tui_set_locator_info (const char *filename,
52 const char *procname,
7d6dd1e9 53 int lineno, CORE_ADDR addr);
2e17b763 54
7563e053 55static void tui_update_command (char *, int);
7d6dd1e9 56\f
c906108c 57
1cc6d956
MS
58/* Create the status line to display as much information as we can on
59 this single line: target name, process number, current function,
60 current line, current PC, SingleKey mode. */
50265402 61static char*
5b6fe301 62tui_make_status_line (struct tui_locator_element *loc)
50265402 63{
5b6fe301 64 char *string;
a42a37b7 65 char line_buf[50], *pname;
5b6fe301 66 char *buf;
a42a37b7 67 int status_size;
50265402 68 int i, proc_width;
5b6fe301
MS
69 const char *pid_name;
70 const char *pc_buf;
50265402
SC
71 int target_width;
72 int pid_width;
73 int line_width;
74 int pc_width;
75 struct ui_file *pc_out;
76
77 if (ptid_equal (inferior_ptid, null_ptid))
78 pid_name = "No process";
79 else
80 pid_name = target_pid_to_str (inferior_ptid);
81
82 target_width = strlen (target_shortname);
83 if (target_width > MAX_TARGET_WIDTH)
84 target_width = MAX_TARGET_WIDTH;
85
86 pid_width = strlen (pid_name);
87 if (pid_width > MAX_PID_WIDTH)
88 pid_width = MAX_PID_WIDTH;
a42a37b7 89
dd1abb8c 90 status_size = tui_term_width ();
50265402 91 string = (char *) xmalloc (status_size + 1);
a42a37b7 92 buf = (char*) alloca (status_size + 1);
50265402
SC
93
94 /* Translate line number and obtain its size. */
6d012f14
AC
95 if (loc->line_no > 0)
96 sprintf (line_buf, "%d", loc->line_no);
50265402
SC
97 else
98 strcpy (line_buf, "??");
99 line_width = strlen (line_buf);
100 if (line_width < MIN_LINE_WIDTH)
101 line_width = MIN_LINE_WIDTH;
102
103 /* Translate PC address. */
104 pc_out = tui_sfileopen (128);
50ee7535 105 fputs_filtered (paddress (loc->addr), pc_out);
50265402
SC
106 pc_buf = tui_file_get_strbuf (pc_out);
107 pc_width = strlen (pc_buf);
108
109 /* First determine the amount of proc name width we have available.
110 The +1 are for a space separator between fields.
111 The -1 are to take into account the \0 counted by sizeof. */
112 proc_width = (status_size
113 - (target_width + 1)
114 - (pid_width + 1)
115 - (sizeof (PROC_PREFIX) - 1 + 1)
116 - (sizeof (LINE_PREFIX) - 1 + line_width + 1)
117 - (sizeof (PC_PREFIX) - 1 + pc_width + 1)
6d012f14 118 - (tui_current_key_mode == TUI_SINGLE_KEY_MODE
50265402
SC
119 ? (sizeof (SINGLE_KEY) - 1 + 1)
120 : 0));
121
122 /* If there is no room to print the function name, try by removing
123 some fields. */
124 if (proc_width < MIN_PROC_WIDTH)
125 {
126 proc_width += target_width + 1;
127 target_width = 0;
128 if (proc_width < MIN_PROC_WIDTH)
129 {
130 proc_width += pid_width + 1;
131 pid_width = 0;
132 if (proc_width <= MIN_PROC_WIDTH)
133 {
134 proc_width += pc_width + sizeof (PC_PREFIX) - 1 + 1;
135 pc_width = 0;
136 if (proc_width < 0)
137 {
138 proc_width += line_width + sizeof (LINE_PREFIX) - 1 + 1;
139 line_width = 0;
140 if (proc_width < 0)
141 proc_width = 0;
142 }
143 }
144 }
145 }
146
1cc6d956 147 /* Now convert elements to string form. */
6d012f14 148 pname = loc->proc_name;
50265402 149
1cc6d956
MS
150 /* Now create the locator line from the string version of the
151 elements. We could use sprintf() here but that wouldn't ensure
152 that we don't overrun the size of the allocated buffer.
153 strcat_to_buf() will. */
50265402
SC
154 *string = (char) 0;
155
156 if (target_width > 0)
157 {
158 sprintf (buf, "%*.*s ",
159 -target_width, target_width, target_shortname);
160 strcat_to_buf (string, status_size, buf);
161 }
162 if (pid_width > 0)
163 {
164 sprintf (buf, "%*.*s ",
165 -pid_width, pid_width, pid_name);
166 strcat_to_buf (string, status_size, buf);
167 }
168
169 /* Show whether we are in SingleKey mode. */
6d012f14 170 if (tui_current_key_mode == TUI_SINGLE_KEY_MODE)
50265402
SC
171 {
172 strcat_to_buf (string, status_size, SINGLE_KEY);
173 strcat_to_buf (string, status_size, " ");
174 }
175
1cc6d956 176 /* Procedure/class name. */
50265402
SC
177 if (proc_width > 0)
178 {
179 if (strlen (pname) > proc_width)
180 sprintf (buf, "%s%*.*s* ", PROC_PREFIX,
181 1 - proc_width, proc_width - 1, pname);
182 else
183 sprintf (buf, "%s%*.*s ", PROC_PREFIX,
184 -proc_width, proc_width, pname);
185 strcat_to_buf (string, status_size, buf);
186 }
187
188 if (line_width > 0)
189 {
190 sprintf (buf, "%s%*.*s ", LINE_PREFIX,
191 -line_width, line_width, line_buf);
192 strcat_to_buf (string, status_size, buf);
193 }
194 if (pc_width > 0)
195 {
196 strcat_to_buf (string, status_size, PC_PREFIX);
197 strcat_to_buf (string, status_size, pc_buf);
198 }
199
200
201 for (i = strlen (string); i < status_size; i++)
202 string[i] = ' ';
203 string[status_size] = (char) 0;
204
205 ui_file_delete (pc_out);
206 return string;
207}
208
1cc6d956
MS
209/* Get a printable name for the function at the address. The symbol
210 name is demangled if demangling is turned on. Returns a pointer to
211 a static area holding the result. */
5564c769
SC
212static char*
213tui_get_function_from_frame (struct frame_info *fi)
214{
215 static char name[256];
216 struct ui_file *stream = tui_sfileopen (256);
217 char *p;
218
f70a7d61 219 print_address_symbolic (get_frame_pc (fi), stream, demangle, "");
5564c769
SC
220 p = tui_file_get_strbuf (stream);
221
1cc6d956
MS
222 /* Use simple heuristics to isolate the function name. The symbol
223 can be demangled and we can have function parameters. Remove
224 them because the status line is too short to display them. */
5564c769
SC
225 if (*p == '<')
226 p++;
227 strncpy (name, p, sizeof (name));
228 p = strchr (name, '(');
229 if (!p)
230 p = strchr (name, '>');
231 if (p)
232 *p = 0;
233 p = strchr (name, '+');
234 if (p)
235 *p = 0;
236 ui_file_delete (stream);
237 return name;
238}
c906108c 239
c906108c 240void
47d3492a 241tui_show_locator_content (void)
c906108c
SS
242{
243 char *string;
5b6fe301 244 struct tui_gen_win_info *locator;
c906108c 245
dd1abb8c 246 locator = tui_locator_win_info_ptr ();
c906108c 247
6d012f14 248 if (locator != NULL && locator->handle != (WINDOW *) NULL)
c906108c 249 {
5b6fe301 250 struct tui_win_element *element;
50265402 251
2a8854a7 252 element = (struct tui_win_element *) locator->content[0];
50265402 253
6d012f14 254 string = tui_make_status_line (&element->which_element.locator);
50265402
SC
255 wmove (locator->handle, 0, 0);
256 wstandout (locator->handle);
257 waddstr (locator->handle, string);
258 wclrtoeol (locator->handle);
259 wstandend (locator->handle);
ec7d9e56 260 tui_refresh_win (locator);
50265402
SC
261 wmove (locator->handle, 0, 0);
262 xfree (string);
6d012f14 263 locator->content_in_use = TRUE;
c906108c 264 }
50265402 265}
c906108c 266
c906108c 267
2e17b763
SC
268/* Set the filename portion of the locator. */
269static void
270tui_set_locator_filename (const char *filename)
271{
5b6fe301
MS
272 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
273 struct tui_locator_element *element;
2e17b763 274
22940a24 275 if (locator->content[0] == NULL)
7d6dd1e9
SC
276 {
277 tui_set_locator_info (filename, NULL, 0, 0);
278 return;
279 }
2e17b763 280
6d012f14
AC
281 element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
282 element->file_name[0] = 0;
283 strcat_to_buf (element->file_name, MAX_LOCATOR_ELEMENT_LEN, filename);
2e17b763 284}
c906108c 285
c7c228ed 286/* Update the locator, with the provided arguments. */
2e17b763 287static void
08ef48c5
MS
288tui_set_locator_info (const char *filename,
289 const char *procname,
290 int lineno,
7d6dd1e9 291 CORE_ADDR addr)
c906108c 292{
5b6fe301
MS
293 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
294 struct tui_locator_element *element;
7d6dd1e9
SC
295
296 /* Allocate the locator content if necessary. */
6d012f14 297 if (locator->content_size <= 0)
7d6dd1e9 298 {
22940a24 299 locator->content = (void **) tui_alloc_content (1, locator->type);
6d012f14 300 locator->content_size = 1;
7d6dd1e9
SC
301 }
302
6d012f14
AC
303 element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
304 element->proc_name[0] = (char) 0;
305 strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
306 element->line_no = lineno;
c774cec6 307 element->addr = addr;
2e17b763 308 tui_set_locator_filename (filename);
c7c228ed 309}
c906108c 310
2e17b763 311/* Update only the filename portion of the locator. */
c906108c 312void
47d3492a 313tui_update_locator_filename (const char *filename)
c906108c 314{
2e17b763 315 tui_set_locator_filename (filename);
47d3492a 316 tui_show_locator_content ();
2e17b763 317}
c906108c 318
7d6dd1e9 319/* Function to print the frame information for the TUI. */
c906108c 320void
47d3492a 321tui_show_frame_info (struct frame_info *fi)
c906108c 322{
5b6fe301 323 struct tui_win_info *win_info;
d02c80cd 324 int i;
c906108c
SS
325
326 if (fi)
327 {
d02c80cd 328 int start_line, i;
c906108c 329 CORE_ADDR low;
5b6fe301 330 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
6ba8e26f 331 int source_already_displayed;
7d6dd1e9
SC
332 struct symtab_and_line sal;
333
3d7442da 334 find_frame_sal (fi, &sal);
7d6dd1e9 335
6ba8e26f 336 source_already_displayed = sal.symtab != 0
a358af15 337 && tui_source_is_displayed (sal.symtab->filename);
7d6dd1e9
SC
338 tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename,
339 tui_get_function_from_frame (fi),
340 sal.line,
f70a7d61 341 get_frame_pc (fi));
47d3492a 342 tui_show_locator_content ();
6d012f14 343 start_line = 0;
dd1abb8c 344 for (i = 0; i < (tui_source_windows ())->count; i++)
c906108c 345 {
2a8854a7 346 union tui_which_element *item;
96c1eda2 347 win_info = (tui_source_windows ())->list[i];
a4b99e53 348
6d012f14
AC
349 item = &((struct tui_win_element *) locator->content[0])->which_element;
350 if (win_info == TUI_SRC_WIN)
c906108c 351 {
6d012f14
AC
352 start_line = (item->locator.line_no -
353 (win_info->generic.viewport_height / 2)) + 1;
354 if (start_line <= 0)
355 start_line = 1;
c906108c
SS
356 }
357 else
358 {
f70a7d61 359 if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL,
87177905 360 &low, (CORE_ADDR) 0) == 0)
8a3fe4f8 361 error (_("No function contains program counter for selected frame."));
c906108c 362 else
22940a24 363 low = tui_get_low_disassembly_address (low, get_frame_pc (fi));
c906108c
SS
364 }
365
6d012f14 366 if (win_info == TUI_SRC_WIN)
c906108c 367 {
362c05fe
AS
368 struct tui_line_or_address l;
369 l.loa = LOA_LINE;
370 l.u.line_no = start_line;
6ba8e26f 371 if (!(source_already_displayed
6d012f14
AC
372 && tui_line_is_displayed (item->locator.line_no, win_info, TRUE)))
373 tui_update_source_window (win_info, sal.symtab, l, TRUE);
c906108c 374 else
a4b99e53 375 {
362c05fe 376 l.u.line_no = item->locator.line_no;
6d012f14 377 tui_set_is_exec_point_at (l, win_info);
a4b99e53 378 }
c906108c
SS
379 }
380 else
381 {
6d012f14 382 if (win_info == TUI_DISASM_WIN)
c906108c 383 {
362c05fe
AS
384 struct tui_line_or_address a;
385 a.loa = LOA_ADDRESS;
386 a.u.addr = low;
6d012f14
AC
387 if (!tui_addr_is_displayed (item->locator.addr, win_info, TRUE))
388 tui_update_source_window (win_info, sal.symtab, a, TRUE);
c906108c 389 else
a4b99e53 390 {
362c05fe 391 a.u.addr = item->locator.addr;
6d012f14 392 tui_set_is_exec_point_at (a, win_info);
a4b99e53 393 }
c906108c
SS
394 }
395 }
6d012f14 396 tui_update_exec_info (win_info);
c906108c
SS
397 }
398 }
399 else
400 {
7d6dd1e9 401 tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0);
47d3492a 402 tui_show_locator_content ();
dd1abb8c 403 for (i = 0; i < (tui_source_windows ())->count; i++)
c906108c 404 {
96c1eda2 405 win_info = (tui_source_windows ())->list[i];
6d012f14
AC
406 tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
407 tui_update_exec_info (win_info);
c906108c
SS
408 }
409 }
7d6dd1e9 410}
c906108c 411
6ba8e26f
AC
412/* Function to initialize gdb commands, for tui window stack
413 manipulation. */
2c0b251b
PA
414
415/* Provide a prototype to silence -Wmissing-prototypes. */
416extern initialize_file_ftype _initialize_tui_stack;
417
c906108c 418void
6ba8e26f 419_initialize_tui_stack (void)
c906108c 420{
1bedd215
AC
421 add_com ("update", class_tui, tui_update_command, _("\
422Update the source window and locator to display the current execution point.\n"));
41783295 423}
c906108c 424
7563e053 425/* Command to update the display with the current execution point. */
c906108c 426static void
7563e053 427tui_update_command (char *arg, int from_tty)
c906108c 428{
7563e053 429 char cmd[sizeof("frame 0")];
c906108c 430
7563e053
SC
431 strcpy (cmd, "frame 0");
432 execute_command (cmd, from_tty);
433}
This page took 1.090788 seconds and 4 git commands to generate.