1 /* TUI display locator.
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
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.
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.
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
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
25 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26 "defs.h" should be included first. Unfortunatly some systems
27 (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28 and they clash with "bfd.h"'s definiton of true/false. The correct
29 fix is to remove true/false from "bfd.h", however, until that
30 happens, hack around it by including "config.h" and <curses.h>
44 #include "breakpoint.h"
54 #include "tuiGeneralWin.h"
55 #include "tuiSource.h"
56 #include "tuiSourceWin.h"
60 /* Get a printable name for the function at the address.
61 The symbol name is demangled if demangling is turned on.
62 Returns a pointer to a static area holding the result. */
63 static char* tui_get_function_from_frame (struct frame_info
*fi
);
65 /* Set the filename portion of the locator. */
66 static void tui_set_locator_filename (const char *filename
);
68 /* Update the locator, with the provided arguments. */
69 static void tui_set_locator_info (const char *filename
, const char *procname
,
70 int lineno
, CORE_ADDR addr
);
72 static void tui_update_command (char *, int);
75 /* Create the status line to display as much information as we
76 can on this single line: target name, process number, current
77 function, current line, current PC, SingleKey mode. */
79 tui_make_status_line (TuiLocatorElement
* loc
)
82 char line_buf
[50], *pname
;
92 struct ui_file
*pc_out
;
94 if (ptid_equal (inferior_ptid
, null_ptid
))
95 pid_name
= "No process";
97 pid_name
= target_pid_to_str (inferior_ptid
);
99 target_width
= strlen (target_shortname
);
100 if (target_width
> MAX_TARGET_WIDTH
)
101 target_width
= MAX_TARGET_WIDTH
;
103 pid_width
= strlen (pid_name
);
104 if (pid_width
> MAX_PID_WIDTH
)
105 pid_width
= MAX_PID_WIDTH
;
107 status_size
= termWidth ();
108 string
= (char *) xmalloc (status_size
+ 1);
109 buf
= (char*) alloca (status_size
+ 1);
111 /* Translate line number and obtain its size. */
113 sprintf (line_buf
, "%d", loc
->lineNo
);
115 strcpy (line_buf
, "??");
116 line_width
= strlen (line_buf
);
117 if (line_width
< MIN_LINE_WIDTH
)
118 line_width
= MIN_LINE_WIDTH
;
120 /* Translate PC address. */
121 pc_out
= tui_sfileopen (128);
122 print_address_numeric (loc
->addr
, 1, pc_out
);
123 pc_buf
= tui_file_get_strbuf (pc_out
);
124 pc_width
= strlen (pc_buf
);
126 /* First determine the amount of proc name width we have available.
127 The +1 are for a space separator between fields.
128 The -1 are to take into account the \0 counted by sizeof. */
129 proc_width
= (status_size
132 - (sizeof (PROC_PREFIX
) - 1 + 1)
133 - (sizeof (LINE_PREFIX
) - 1 + line_width
+ 1)
134 - (sizeof (PC_PREFIX
) - 1 + pc_width
+ 1)
135 - (tui_current_key_mode
== tui_single_key_mode
136 ? (sizeof (SINGLE_KEY
) - 1 + 1)
139 /* If there is no room to print the function name, try by removing
141 if (proc_width
< MIN_PROC_WIDTH
)
143 proc_width
+= target_width
+ 1;
145 if (proc_width
< MIN_PROC_WIDTH
)
147 proc_width
+= pid_width
+ 1;
149 if (proc_width
<= MIN_PROC_WIDTH
)
151 proc_width
+= pc_width
+ sizeof (PC_PREFIX
) - 1 + 1;
155 proc_width
+= line_width
+ sizeof (LINE_PREFIX
) - 1 + 1;
164 /* Now convert elements to string form */
165 pname
= loc
->procName
;
167 /* Now create the locator line from the string version
168 of the elements. We could use sprintf() here but
169 that wouldn't ensure that we don't overrun the size
170 of the allocated buffer. strcat_to_buf() will. */
173 if (target_width
> 0)
175 sprintf (buf
, "%*.*s ",
176 -target_width
, target_width
, target_shortname
);
177 strcat_to_buf (string
, status_size
, buf
);
181 sprintf (buf
, "%*.*s ",
182 -pid_width
, pid_width
, pid_name
);
183 strcat_to_buf (string
, status_size
, buf
);
186 /* Show whether we are in SingleKey mode. */
187 if (tui_current_key_mode
== tui_single_key_mode
)
189 strcat_to_buf (string
, status_size
, SINGLE_KEY
);
190 strcat_to_buf (string
, status_size
, " ");
193 /* procedure/class name */
196 if (strlen (pname
) > proc_width
)
197 sprintf (buf
, "%s%*.*s* ", PROC_PREFIX
,
198 1 - proc_width
, proc_width
- 1, pname
);
200 sprintf (buf
, "%s%*.*s ", PROC_PREFIX
,
201 -proc_width
, proc_width
, pname
);
202 strcat_to_buf (string
, status_size
, buf
);
207 sprintf (buf
, "%s%*.*s ", LINE_PREFIX
,
208 -line_width
, line_width
, line_buf
);
209 strcat_to_buf (string
, status_size
, buf
);
213 strcat_to_buf (string
, status_size
, PC_PREFIX
);
214 strcat_to_buf (string
, status_size
, pc_buf
);
218 for (i
= strlen (string
); i
< status_size
; i
++)
220 string
[status_size
] = (char) 0;
222 ui_file_delete (pc_out
);
226 /* Get a printable name for the function at the address.
227 The symbol name is demangled if demangling is turned on.
228 Returns a pointer to a static area holding the result. */
230 tui_get_function_from_frame (struct frame_info
*fi
)
232 static char name
[256];
233 struct ui_file
*stream
= tui_sfileopen (256);
236 print_address_symbolic (fi
->pc
, stream
, demangle
, "");
237 p
= tui_file_get_strbuf (stream
);
239 /* Use simple heuristics to isolate the function name. The symbol can
240 be demangled and we can have function parameters. Remove them because
241 the status line is too short to display them. */
244 strncpy (name
, p
, sizeof (name
));
245 p
= strchr (name
, '(');
247 p
= strchr (name
, '>');
250 p
= strchr (name
, '+');
253 ui_file_delete (stream
);
258 ** tuiShowLocatorContent()
261 tuiShowLocatorContent (void)
264 TuiGenWinInfoPtr locator
;
266 locator
= locatorWinInfoPtr ();
268 if (m_genWinPtrNotNull (locator
) && locator
->handle
!= (WINDOW
*) NULL
)
270 TuiWinElementPtr element
;
272 element
= (TuiWinElementPtr
) locator
->content
[0];
274 string
= tui_make_status_line (&element
->whichElement
.locator
);
275 wmove (locator
->handle
, 0, 0);
276 wstandout (locator
->handle
);
277 waddstr (locator
->handle
, string
);
278 wclrtoeol (locator
->handle
);
279 wstandend (locator
->handle
);
280 tuiRefreshWin (locator
);
281 wmove (locator
->handle
, 0, 0);
283 locator
->contentInUse
= TRUE
;
288 /* Set the filename portion of the locator. */
290 tui_set_locator_filename (const char *filename
)
292 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
293 TuiLocatorElementPtr element
;
295 if (locator
->content
[0] == (Opaque
) NULL
)
297 tui_set_locator_info (filename
, NULL
, 0, 0);
301 element
= &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
;
302 element
->fileName
[0] = 0;
303 strcat_to_buf (element
->fileName
, MAX_LOCATOR_ELEMENT_LEN
, filename
);
306 /* Update the locator, with the provided arguments. */
308 tui_set_locator_info (const char *filename
, const char *procname
, int lineno
,
311 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
312 TuiLocatorElementPtr element
;
314 /* Allocate the locator content if necessary. */
315 if (locator
->contentSize
<= 0)
317 locator
->content
= (OpaquePtr
) allocContent (1, locator
->type
);
318 locator
->contentSize
= 1;
321 element
= &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
;
322 element
->procName
[0] = (char) 0;
323 strcat_to_buf (element
->procName
, MAX_LOCATOR_ELEMENT_LEN
, procname
);
324 element
->lineNo
= lineno
;
325 element
->addr
= addr
;
326 tui_set_locator_filename (filename
);
329 /* Update only the filename portion of the locator. */
331 tuiUpdateLocatorFilename (const char *filename
)
333 tui_set_locator_filename (filename
);
334 tuiShowLocatorContent ();
337 /* Function to print the frame information for the TUI. */
339 tuiShowFrameInfo (struct frame_info
*fi
)
341 TuiWinInfoPtr winInfo
;
346 register int startLine
, i
;
348 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
349 int sourceAlreadyDisplayed
;
350 struct symtab_and_line sal
;
352 sal
= find_pc_line (fi
->pc
,
353 (fi
->next
!= (struct frame_info
*) NULL
&&
354 !fi
->next
->signal_handler_caller
&&
355 !frame_in_dummy (fi
->next
)));
357 sourceAlreadyDisplayed
= sal
.symtab
!= 0
358 && tuiSourceIsDisplayed (sal
.symtab
->filename
);
359 tui_set_locator_info (sal
.symtab
== 0 ? "??" : sal
.symtab
->filename
,
360 tui_get_function_from_frame (fi
),
363 tuiShowLocatorContent ();
365 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
367 TuiWhichElement
*item
;
368 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
370 item
= &((TuiWinElementPtr
) locator
->content
[0])->whichElement
;
371 if (winInfo
== srcWin
)
373 startLine
= (item
->locator
.lineNo
-
374 (winInfo
->generic
.viewportHeight
/ 2)) + 1;
380 if (find_pc_partial_function (fi
->pc
, (char **) NULL
, &low
, (CORE_ADDR
) NULL
) == 0)
381 error ("No function contains program counter for selected frame.\n");
383 low
= tuiGetLowDisassemblyAddress (low
, fi
->pc
);
386 if (winInfo
== srcWin
)
389 l
.lineNo
= startLine
;
390 if (!(sourceAlreadyDisplayed
391 && tuiLineIsDisplayed (item
->locator
.lineNo
, winInfo
, TRUE
)))
392 tuiUpdateSourceWindow (winInfo
, sal
.symtab
, l
, TRUE
);
395 l
.lineNo
= item
->locator
.lineNo
;
396 tuiSetIsExecPointAt (l
, winInfo
);
401 if (winInfo
== disassemWin
)
405 if (!tuiAddrIsDisplayed (item
->locator
.addr
, winInfo
, TRUE
))
406 tuiUpdateSourceWindow (winInfo
, sal
.symtab
, a
, TRUE
);
409 a
.addr
= item
->locator
.addr
;
410 tuiSetIsExecPointAt (a
, winInfo
);
414 tuiUpdateExecInfo (winInfo
);
419 tui_set_locator_info (NULL
, NULL
, 0, (CORE_ADDR
) 0);
420 tuiShowLocatorContent ();
421 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
423 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
424 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
425 tuiUpdateExecInfo (winInfo
);
430 /* Function to initialize gdb commands, for tui window stack manipulation. */
432 _initialize_tuiStack (void)
434 add_com ("update", class_tui
, tui_update_command
,
435 "Update the source window and locator to display the current "
436 "execution point.\n");
439 /* Command to update the display with the current execution point. */
441 tui_update_command (char *arg
, int from_tty
)
443 char cmd
[sizeof("frame 0")];
445 strcpy (cmd
, "frame 0");
446 execute_command (cmd
, from_tty
);