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