1 /* TUI display source/assembly window.
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>
46 #include "breakpoint.h"
53 #include "tuiGeneralWin.h"
54 #include "tuiSourceWin.h"
55 #include "tuiSource.h"
56 #include "tuiDisassem.h"
59 /* Function to display the "main" routine. */
61 tui_display_main (void)
63 if ((sourceWindows ())->count
> 0)
67 addr
= tuiGetBeginAsmAddress ();
68 if (addr
!= (CORE_ADDR
) 0)
70 struct symtab_and_line sal
;
72 tuiUpdateSourceWindowsWithAddr (addr
);
73 sal
= find_pc_line (addr
, 0);
75 tuiUpdateLocatorFilename (sal
.symtab
->filename
);
77 tuiUpdateLocatorFilename ("??");
85 ** tuiUpdateSourceWindow().
86 ** Function to display source in the source window. This function
87 ** initializes the horizontal scroll to 0.
90 tuiUpdateSourceWindow (TuiWinInfoPtr winInfo
, struct symtab
*s
,
91 TuiLineOrAddress lineOrAddr
, int noerror
)
93 winInfo
->detail
.sourceInfo
.horizontalOffset
= 0;
94 tuiUpdateSourceWindowAsIs (winInfo
, s
, lineOrAddr
, noerror
);
97 } /* tuiUpdateSourceWindow */
101 ** tuiUpdateSourceWindowAsIs().
102 ** Function to display source in the source/asm window. This
103 ** function shows the source as specified by the horizontal offset.
106 tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo
, struct symtab
*s
,
107 TuiLineOrAddress lineOrAddr
, int noerror
)
111 if (winInfo
->generic
.type
== SRC_WIN
)
112 ret
= tuiSetSourceContent (s
, lineOrAddr
.lineNo
, noerror
);
114 ret
= tuiSetDisassemContent (s
, lineOrAddr
.addr
);
116 if (ret
== TUI_FAILURE
)
118 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
119 tuiClearExecInfoContent (winInfo
);
123 tuiEraseSourceContent (winInfo
, NO_EMPTY_SOURCE_PROMPT
);
124 tuiShowSourceContent (winInfo
);
125 tuiUpdateExecInfo (winInfo
);
126 if (winInfo
->generic
.type
== SRC_WIN
)
128 current_source_line
= lineOrAddr
.lineNo
+
129 (winInfo
->generic
.contentSize
- 2);
130 current_source_symtab
= s
;
132 ** If the focus was in the asm win, put it in the src
133 ** win if we don't have a split layout
135 if (tuiWinWithFocus () == disassemWin
&&
136 currentLayout () != SRC_DISASSEM_COMMAND
)
137 tuiSetWinFocusTo (srcWin
);
143 } /* tuiUpdateSourceWindowAsIs */
147 ** tuiUpdateSourceWindowsWithAddr().
148 ** Function to ensure that the source and/or disassemly windows
149 ** reflect the input address.
152 tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr
)
156 struct symtab_and_line sal
;
159 switch (currentLayout ())
161 case DISASSEM_COMMAND
:
162 case DISASSEM_DATA_COMMAND
:
163 tuiShowDisassem (addr
);
165 case SRC_DISASSEM_COMMAND
:
166 tuiShowDisassemAndUpdateSource (addr
);
169 sal
= find_pc_line (addr
, 0);
171 tuiShowSource (sal
.symtab
, l
, FALSE
);
179 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
181 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
183 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
184 tuiClearExecInfoContent (winInfo
);
189 } /* tuiUpdateSourceWindowsWithAddr */
192 ** tuiUpdateSourceWindowsWithLine().
193 ** Function to ensure that the source and/or disassemly windows
194 ** reflect the input address.
197 tuiUpdateSourceWindowsWithLine (struct symtab
*s
, int line
)
202 switch (currentLayout ())
204 case DISASSEM_COMMAND
:
205 case DISASSEM_DATA_COMMAND
:
206 find_line_pc (s
, line
, &pc
);
207 tuiUpdateSourceWindowsWithAddr (pc
);
211 tuiShowSource (s
, l
, FALSE
);
212 if (currentLayout () == SRC_DISASSEM_COMMAND
)
214 find_line_pc (s
, line
, &pc
);
215 tuiShowDisassem (pc
);
221 } /* tuiUpdateSourceWindowsWithLine */
224 ** tuiClearSourceContent().
227 tuiClearSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
229 if (m_winPtrNotNull (winInfo
))
233 winInfo
->generic
.contentInUse
= FALSE
;
234 tuiEraseSourceContent (winInfo
, displayPrompt
);
235 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
237 TuiWinElementPtr element
=
238 (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
239 element
->whichElement
.source
.hasBreak
= FALSE
;
240 element
->whichElement
.source
.isExecPoint
= FALSE
;
245 } /* tuiClearSourceContent */
249 ** tuiEraseSourceContent().
252 tuiEraseSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
255 int halfWidth
= (winInfo
->generic
.width
- 2) / 2;
257 if (winInfo
->generic
.handle
!= (WINDOW
*) NULL
)
259 werase (winInfo
->generic
.handle
);
260 checkAndDisplayHighlightIfNeeded (winInfo
);
261 if (displayPrompt
== EMPTY_SOURCE_PROMPT
)
265 if (winInfo
->generic
.type
== SRC_WIN
)
266 noSrcStr
= NO_SRC_STRING
;
268 noSrcStr
= NO_DISASSEM_STRING
;
269 if (strlen (noSrcStr
) >= halfWidth
)
272 xPos
= halfWidth
- strlen (noSrcStr
);
273 mvwaddstr (winInfo
->generic
.handle
,
274 (winInfo
->generic
.height
/ 2),
278 /* elz: added this function call to set the real contents of
279 the window to what is on the screen, so that later calls
280 to refresh, do display
281 the correct stuff, and not the old image */
283 tuiSetSourceContentNil (winInfo
, noSrcStr
);
285 tuiRefreshWin (&winInfo
->generic
);
288 } /* tuiEraseSourceContent */
291 /* Redraw the complete line of a source or disassembly window. */
293 tui_show_source_line (TuiWinInfoPtr winInfo
, int lineno
)
295 TuiWinElementPtr line
;
298 line
= (TuiWinElementPtr
) winInfo
->generic
.content
[lineno
- 1];
299 if (line
->whichElement
.source
.isExecPoint
)
300 wattron (winInfo
->generic
.handle
, A_STANDOUT
);
302 mvwaddstr (winInfo
->generic
.handle
, lineno
, 1,
303 line
->whichElement
.source
.line
);
304 if (line
->whichElement
.source
.isExecPoint
)
305 wattroff (winInfo
->generic
.handle
, A_STANDOUT
);
307 /* Clear to end of line but stop before the border. */
308 getyx (winInfo
->generic
.handle
, y
, x
);
309 while (x
+ 1 < winInfo
->generic
.width
)
311 waddch (winInfo
->generic
.handle
, ' ');
312 getyx (winInfo
->generic
.handle
, y
, x
);
317 ** tuiShowSourceContent().
320 tuiShowSourceContent (TuiWinInfoPtr winInfo
)
322 if (winInfo
->generic
.contentSize
> 0)
326 for (lineno
= 1; lineno
<= winInfo
->generic
.contentSize
; lineno
++)
327 tui_show_source_line (winInfo
, lineno
);
330 tuiEraseSourceContent (winInfo
, TRUE
);
332 checkAndDisplayHighlightIfNeeded (winInfo
);
333 tuiRefreshWin (&winInfo
->generic
);
334 winInfo
->generic
.contentInUse
= TRUE
;
339 ** tuiHorizontalSourceScroll().
340 ** Scroll the source forward or backward horizontally
343 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo
,
344 TuiScrollDirection direction
,
347 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
352 if (current_source_symtab
== (struct symtab
*) NULL
)
353 s
= find_pc_symtab (selected_frame
->pc
);
355 s
= current_source_symtab
;
357 if (direction
== LEFT_SCROLL
)
358 offset
= winInfo
->detail
.sourceInfo
.horizontalOffset
+ numToScroll
;
362 winInfo
->detail
.sourceInfo
.horizontalOffset
- numToScroll
) < 0)
365 winInfo
->detail
.sourceInfo
.horizontalOffset
= offset
;
366 tuiUpdateSourceWindowAsIs (
370 winInfo
->generic
.content
[0])->whichElement
.source
.lineOrAddr
,
375 } /* tuiHorizontalSourceScroll */
379 ** tuiSetHasExecPointAt().
380 ** Set or clear the hasBreak flag in the line whose line is lineNo.
383 tuiSetIsExecPointAt (TuiLineOrAddress l
, TuiWinInfoPtr winInfo
)
386 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
389 while (i
< winInfo
->generic
.contentSize
)
391 if (content
[i
]->whichElement
.source
.lineOrAddr
.addr
== l
.addr
)
392 content
[i
]->whichElement
.source
.isExecPoint
= TRUE
;
394 content
[i
]->whichElement
.source
.isExecPoint
= FALSE
;
399 } /* tuiSetIsExecPointAt */
402 ** tuiSetHasBreakAt().
403 ** Set or clear the hasBreak flag in the line whose line is lineNo.
406 tuiSetHasBreakAt (struct breakpoint
*bp
, TuiWinInfoPtr winInfo
, int hasBreak
)
409 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
412 while (i
< winInfo
->generic
.contentSize
)
415 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
417 if (winInfo
== srcWin
)
419 TuiSourceInfoPtr src
= &winInfo
->detail
.sourceInfo
;
421 gotIt
= (src
->filename
!= (char *) NULL
&&
422 bp
->source_file
!= NULL
&&
423 (strcmp (bp
->source_file
, src
->filename
) == 0) &&
424 content
[i
]->whichElement
.source
.lineOrAddr
.lineNo
==
428 gotIt
= (content
[i
]->whichElement
.source
.lineOrAddr
.addr
432 content
[i
]->whichElement
.source
.hasBreak
= hasBreak
;
439 } /* tuiSetHasBreakAt */
443 ** tuiAllSetHasBreakAt().
444 ** Set or clear the hasBreak flag in all displayed source windows.
447 tuiAllSetHasBreakAt (struct breakpoint
*bp
, int hasBreak
)
451 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
452 tuiSetHasBreakAt (bp
,
453 (TuiWinInfoPtr
) (sourceWindows ())->list
[i
], hasBreak
);
456 } /* tuiAllSetHasBreakAt */
459 /*********************************
460 ** EXECUTION INFO FUNCTIONS **
461 *********************************/
464 ** tuiSetExecInfoContent().
465 ** Function to initialize the content of the execution info window,
466 ** based upon the input window which is either the source or
467 ** disassembly window.
470 tuiSetExecInfoContent (TuiWinInfoPtr winInfo
)
472 TuiStatus ret
= TUI_SUCCESS
;
474 if (winInfo
->detail
.sourceInfo
.executionInfo
!= (TuiGenWinInfoPtr
) NULL
)
476 TuiGenWinInfoPtr execInfoPtr
= winInfo
->detail
.sourceInfo
.executionInfo
;
478 if (execInfoPtr
->content
== (OpaquePtr
) NULL
)
479 execInfoPtr
->content
=
480 (OpaquePtr
) allocContent (winInfo
->generic
.height
,
482 if (execInfoPtr
->content
!= (OpaquePtr
) NULL
)
486 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
488 TuiWinElementPtr element
;
489 TuiWinElementPtr srcElement
;
491 element
= (TuiWinElementPtr
) execInfoPtr
->content
[i
];
492 srcElement
= (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
494 ** First check to see if we have a breakpoint that is
495 ** temporary. If so, and this is our current execution point,
496 ** then clear the break indicator.
498 if (srcElement
->whichElement
.source
.hasBreak
&&
499 srcElement
->whichElement
.source
.isExecPoint
)
501 struct breakpoint
*bp
;
503 extern struct breakpoint
*breakpoint_chain
;
505 for (bp
= breakpoint_chain
;
506 (bp
!= (struct breakpoint
*) NULL
&& !found
);
510 (winInfo
== srcWin
&&
512 srcElement
->whichElement
.source
.lineOrAddr
.lineNo
) ||
513 (winInfo
== disassemWin
&&
514 bp
->address
== (CORE_ADDR
)
515 srcElement
->whichElement
.source
.lineOrAddr
.addr
);
517 srcElement
->whichElement
.source
.hasBreak
=
518 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0);
521 srcElement
->whichElement
.source
.hasBreak
= FALSE
;
524 ** Now update the exec info content based upon the state
525 ** of each line as indicated by the source content.
527 if (srcElement
->whichElement
.source
.hasBreak
&&
528 srcElement
->whichElement
.source
.isExecPoint
)
529 element
->whichElement
.simpleString
= breakLocationStr ();
530 else if (srcElement
->whichElement
.source
.hasBreak
)
531 element
->whichElement
.simpleString
= breakStr ();
532 else if (srcElement
->whichElement
.source
.isExecPoint
)
533 element
->whichElement
.simpleString
= locationStr ();
535 element
->whichElement
.simpleString
= blankStr ();
537 execInfoPtr
->contentSize
= winInfo
->generic
.contentSize
;
544 } /* tuiSetExecInfoContent */
548 ** tuiShowExecInfoContent().
551 tuiShowExecInfoContent (TuiWinInfoPtr winInfo
)
553 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
556 werase (execInfo
->handle
);
557 tuiRefreshWin (execInfo
);
558 for (curLine
= 1; (curLine
<= execInfo
->contentSize
); curLine
++)
559 mvwaddstr (execInfo
->handle
,
563 execInfo
->content
[curLine
- 1])->whichElement
.simpleString
);
564 tuiRefreshWin (execInfo
);
565 execInfo
->contentInUse
= TRUE
;
568 } /* tuiShowExecInfoContent */
572 ** tuiEraseExecInfoContent().
575 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo
)
577 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
579 werase (execInfo
->handle
);
580 tuiRefreshWin (execInfo
);
583 } /* tuiEraseExecInfoContent */
586 ** tuiClearExecInfoContent().
589 tuiClearExecInfoContent (TuiWinInfoPtr winInfo
)
591 winInfo
->detail
.sourceInfo
.executionInfo
->contentInUse
= FALSE
;
592 tuiEraseExecInfoContent (winInfo
);
595 } /* tuiClearExecInfoContent */
598 ** tuiUpdateExecInfo().
599 ** Function to update the execution info window
602 tuiUpdateExecInfo (TuiWinInfoPtr winInfo
)
604 tuiSetExecInfoContent (winInfo
);
605 tuiShowExecInfoContent (winInfo
);
606 } /* tuiUpdateExecInfo */
610 ** tuiUpdateAllExecInfos()
613 tuiUpdateAllExecInfos (void)
617 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
618 tuiUpdateExecInfo ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
621 } /* tuiUpdateAllExecInfos */
624 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo
)
626 register char *srcLineBuf
;
627 register int i
, lineWidth
, maxLines
;
628 TuiStatus ret
= TUI_FAILURE
;
630 maxLines
= winInfo
->generic
.height
; /* less the highlight box */
631 lineWidth
= winInfo
->generic
.width
- 1;
633 ** Allocate the buffer for the source lines. Do this only once since they
634 ** will be re-used for all source displays. The only other time this will
635 ** be done is when a window's size changes.
637 if (winInfo
->generic
.content
== (OpaquePtr
) NULL
)
639 srcLineBuf
= (char *) xmalloc ((maxLines
* lineWidth
) * sizeof (char));
640 if (srcLineBuf
== (char *) NULL
)
642 "Unable to Allocate Memory for Source or Disassembly Display.\n",
646 /* allocate the content list */
647 if ((winInfo
->generic
.content
=
648 (OpaquePtr
) allocContent (maxLines
, SRC_WIN
)) == (OpaquePtr
) NULL
)
650 tuiFree (srcLineBuf
);
651 srcLineBuf
= (char *) NULL
;
653 "Unable to Allocate Memory for Source or Disassembly Display.\n",
657 for (i
= 0; i
< maxLines
; i
++)
659 winInfo
->generic
.content
[i
])->whichElement
.source
.line
=
660 srcLineBuf
+ (lineWidth
* i
);
667 } /* tuiAllocSourceBuffer */
671 ** tuiLineIsDisplayed().
672 ** Answer whether the a particular line number or address is displayed
673 ** in the current source window.
676 tuiLineIsDisplayed (int line
, TuiWinInfoPtr winInfo
,
679 int isDisplayed
= FALSE
;
683 threshold
= SCROLL_THRESHOLD
;
687 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
689 isDisplayed
= (((TuiWinElementPtr
)
690 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.lineNo
696 } /* tuiLineIsDisplayed */
700 ** tuiLineIsDisplayed().
701 ** Answer whether the a particular line number or address is displayed
702 ** in the current source window.
705 tuiAddrIsDisplayed (CORE_ADDR addr
, TuiWinInfoPtr winInfo
,
708 int isDisplayed
= FALSE
;
712 threshold
= SCROLL_THRESHOLD
;
716 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
718 isDisplayed
= (((TuiWinElementPtr
)
719 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.addr
728 /*****************************************
729 ** STATIC LOCAL FUNCTIONS **
730 ******************************************/