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 /*****************************************
60 ** EXTERNAL FUNCTION DECLS **
61 ******************************************/
63 /*****************************************
64 ** EXTERNAL DATA DECLS **
65 ******************************************/
66 extern int current_source_line
;
67 extern struct symtab
*current_source_symtab
;
70 /*****************************************
71 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
72 ******************************************/
74 /*****************************************
75 ** STATIC LOCAL DATA **
76 ******************************************/
79 /*****************************************
80 ** PUBLIC FUNCTIONS **
81 ******************************************/
83 /*********************************
84 ** SOURCE/DISASSEM FUNCTIONS **
85 *********************************/
88 ** tuiSrcWinIsDisplayed().
91 tuiSrcWinIsDisplayed (void)
93 return (m_winPtrNotNull (srcWin
) && srcWin
->generic
.isVisible
);
94 } /* tuiSrcWinIsDisplayed */
98 ** tuiAsmWinIsDisplayed().
101 tuiAsmWinIsDisplayed (void)
103 return (m_winPtrNotNull (disassemWin
) && disassemWin
->generic
.isVisible
);
104 } /* tuiAsmWinIsDisplayed */
108 ** tuiDisplayMainFunction().
109 ** Function to display the "main" routine"
112 tuiDisplayMainFunction (void)
114 if ((sourceWindows ())->count
> 0)
118 addr
= parse_and_eval_address ("main");
119 if (addr
== (CORE_ADDR
) 0)
120 addr
= parse_and_eval_address ("MAIN");
121 if (addr
!= (CORE_ADDR
) 0)
123 struct symtab_and_line sal
;
125 tuiUpdateSourceWindowsWithAddr (addr
);
126 sal
= find_pc_line (addr
, 0);
127 tuiSwitchFilename (sal
.symtab
->filename
);
132 } /* tuiDisplayMainFunction */
137 ** tuiUpdateSourceWindow().
138 ** Function to display source in the source window. This function
139 ** initializes the horizontal scroll to 0.
142 tuiUpdateSourceWindow (TuiWinInfoPtr winInfo
, struct symtab
*s
,
143 TuiLineOrAddress lineOrAddr
, int noerror
)
145 winInfo
->detail
.sourceInfo
.horizontalOffset
= 0;
146 tuiUpdateSourceWindowAsIs (winInfo
, s
, lineOrAddr
, noerror
);
149 } /* tuiUpdateSourceWindow */
153 ** tuiUpdateSourceWindowAsIs().
154 ** Function to display source in the source/asm window. This
155 ** function shows the source as specified by the horizontal offset.
158 tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo
, struct symtab
*s
,
159 TuiLineOrAddress lineOrAddr
, int noerror
)
163 if (winInfo
->generic
.type
== SRC_WIN
)
164 ret
= tuiSetSourceContent (s
, lineOrAddr
.lineNo
, noerror
);
166 ret
= tuiSetDisassemContent (s
, lineOrAddr
.addr
);
168 if (ret
== TUI_FAILURE
)
170 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
171 tuiClearExecInfoContent (winInfo
);
175 tuiEraseSourceContent (winInfo
, NO_EMPTY_SOURCE_PROMPT
);
176 tuiShowSourceContent (winInfo
);
177 tuiUpdateExecInfo (winInfo
);
178 if (winInfo
->generic
.type
== SRC_WIN
)
180 current_source_line
= lineOrAddr
.lineNo
+
181 (winInfo
->generic
.contentSize
- 2);
182 current_source_symtab
= s
;
184 ** If the focus was in the asm win, put it in the src
185 ** win if we don't have a split layout
187 if (tuiWinWithFocus () == disassemWin
&&
188 currentLayout () != SRC_DISASSEM_COMMAND
)
189 tuiSetWinFocusTo (srcWin
);
195 } /* tuiUpdateSourceWindowAsIs */
199 ** tuiUpdateSourceWindowsWithAddr().
200 ** Function to ensure that the source and/or disassemly windows
201 ** reflect the input address.
204 tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr
)
208 struct symtab_and_line sal
;
211 switch (currentLayout ())
213 case DISASSEM_COMMAND
:
214 case DISASSEM_DATA_COMMAND
:
215 tuiShowDisassem (addr
);
217 case SRC_DISASSEM_COMMAND
:
218 tuiShowDisassemAndUpdateSource (addr
);
221 sal
= find_pc_line (addr
, 0);
223 tuiShowSource (sal
.symtab
, l
, FALSE
);
231 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
233 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
235 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
236 tuiClearExecInfoContent (winInfo
);
241 } /* tuiUpdateSourceWindowsWithAddr */
244 ** tuiUpdateSourceWindowsWithLine().
245 ** Function to ensure that the source and/or disassemly windows
246 ** reflect the input address.
249 tuiUpdateSourceWindowsWithLine (struct symtab
*s
, int line
)
254 switch (currentLayout ())
256 case DISASSEM_COMMAND
:
257 case DISASSEM_DATA_COMMAND
:
258 find_line_pc (s
, line
, &pc
);
259 tuiUpdateSourceWindowsWithAddr (pc
);
263 tuiShowSource (s
, l
, FALSE
);
264 if (currentLayout () == SRC_DISASSEM_COMMAND
)
266 find_line_pc (s
, line
, &pc
);
267 tuiShowDisassem (pc
);
273 } /* tuiUpdateSourceWindowsWithLine */
276 ** tuiClearSourceContent().
279 tuiClearSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
281 if (m_winPtrNotNull (winInfo
))
285 winInfo
->generic
.contentInUse
= FALSE
;
286 tuiEraseSourceContent (winInfo
, displayPrompt
);
287 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
289 TuiWinElementPtr element
=
290 (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
291 element
->whichElement
.source
.hasBreak
= FALSE
;
292 element
->whichElement
.source
.isExecPoint
= FALSE
;
297 } /* tuiClearSourceContent */
301 ** tuiClearAllSourceWinsContent().
304 tuiClearAllSourceWinsContent (int displayPrompt
)
308 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
309 tuiClearSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
313 } /* tuiClearAllSourceWinsContent */
317 ** tuiEraseSourceContent().
320 tuiEraseSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
323 int halfWidth
= (winInfo
->generic
.width
- 2) / 2;
325 if (winInfo
->generic
.handle
!= (WINDOW
*) NULL
)
327 werase (winInfo
->generic
.handle
);
328 checkAndDisplayHighlightIfNeeded (winInfo
);
329 if (displayPrompt
== EMPTY_SOURCE_PROMPT
)
333 if (winInfo
->generic
.type
== SRC_WIN
)
334 noSrcStr
= NO_SRC_STRING
;
336 noSrcStr
= NO_DISASSEM_STRING
;
337 if (strlen (noSrcStr
) >= halfWidth
)
340 xPos
= halfWidth
- strlen (noSrcStr
);
341 mvwaddstr (winInfo
->generic
.handle
,
342 (winInfo
->generic
.height
/ 2),
346 /* elz: added this function call to set the real contents of
347 the window to what is on the screen, so that later calls
348 to refresh, do display
349 the correct stuff, and not the old image */
351 tuiSetSourceContentNil (winInfo
, noSrcStr
);
353 tuiRefreshWin (&winInfo
->generic
);
356 } /* tuiEraseSourceContent */
360 ** tuiEraseAllSourceContent().
363 tuiEraseAllSourceWinsContent (int displayPrompt
)
367 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
368 tuiEraseSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
372 } /* tuiEraseAllSourceWinsContent */
376 ** tuiShowSourceContent().
379 tuiShowSourceContent (TuiWinInfoPtr winInfo
)
381 int curLine
, i
, curX
;
383 tuiEraseSourceContent (winInfo
, (winInfo
->generic
.contentSize
<= 0));
384 if (winInfo
->generic
.contentSize
> 0)
388 for (curLine
= 1; (curLine
<= winInfo
->generic
.contentSize
); curLine
++)
390 winInfo
->generic
.handle
,
394 winInfo
->generic
.content
[curLine
- 1])->whichElement
.source
.line
);
396 checkAndDisplayHighlightIfNeeded (winInfo
);
397 tuiRefreshWin (&winInfo
->generic
);
398 winInfo
->generic
.contentInUse
= TRUE
;
401 } /* tuiShowSourceContent */
405 ** tuiShowAllSourceWinsContent()
408 tuiShowAllSourceWinsContent (void)
412 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
413 tuiShowSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
416 } /* tuiShowAllSourceWinsContent */
420 ** tuiHorizontalSourceScroll().
421 ** Scroll the source forward or backward horizontally
424 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo
,
425 TuiScrollDirection direction
,
428 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
433 if (current_source_symtab
== (struct symtab
*) NULL
)
434 s
= find_pc_symtab (selected_frame
->pc
);
436 s
= current_source_symtab
;
438 if (direction
== LEFT_SCROLL
)
439 offset
= winInfo
->detail
.sourceInfo
.horizontalOffset
+ numToScroll
;
443 winInfo
->detail
.sourceInfo
.horizontalOffset
- numToScroll
) < 0)
446 winInfo
->detail
.sourceInfo
.horizontalOffset
= offset
;
447 tuiUpdateSourceWindowAsIs (
451 winInfo
->generic
.content
[0])->whichElement
.source
.lineOrAddr
,
456 } /* tuiHorizontalSourceScroll */
460 ** tuiSetHasExecPointAt().
461 ** Set or clear the hasBreak flag in the line whose line is lineNo.
464 tuiSetIsExecPointAt (TuiLineOrAddress l
, TuiWinInfoPtr winInfo
)
467 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
470 while (i
< winInfo
->generic
.contentSize
)
472 if (content
[i
]->whichElement
.source
.lineOrAddr
.addr
== l
.addr
)
473 content
[i
]->whichElement
.source
.isExecPoint
= TRUE
;
475 content
[i
]->whichElement
.source
.isExecPoint
= FALSE
;
480 } /* tuiSetIsExecPointAt */
483 ** tuiSetHasBreakAt().
484 ** Set or clear the hasBreak flag in the line whose line is lineNo.
487 tuiSetHasBreakAt (struct breakpoint
*bp
, TuiWinInfoPtr winInfo
, int hasBreak
)
490 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
493 while (i
< winInfo
->generic
.contentSize
)
496 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
498 if (winInfo
== srcWin
)
500 char *fileNameDisplayed
= (char *) NULL
;
502 if (((TuiWinElementPtr
)
503 locator
->content
[0])->whichElement
.locator
.fileName
!=
505 fileNameDisplayed
= ((TuiWinElementPtr
)
506 locator
->content
[0])->whichElement
.locator
.fileName
;
507 else if (current_source_symtab
!= (struct symtab
*) NULL
)
508 fileNameDisplayed
= current_source_symtab
->filename
;
510 gotIt
= (fileNameDisplayed
!= (char *) NULL
&&
511 bp
->source_file
!= NULL
&&
512 (strcmp (bp
->source_file
, fileNameDisplayed
) == 0) &&
513 content
[i
]->whichElement
.source
.lineOrAddr
.lineNo
==
517 gotIt
= (content
[i
]->whichElement
.source
.lineOrAddr
.addr
521 content
[i
]->whichElement
.source
.hasBreak
= hasBreak
;
528 } /* tuiSetHasBreakAt */
532 ** tuiAllSetHasBreakAt().
533 ** Set or clear the hasBreak flag in all displayed source windows.
536 tuiAllSetHasBreakAt (struct breakpoint
*bp
, int hasBreak
)
540 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
541 tuiSetHasBreakAt (bp
,
542 (TuiWinInfoPtr
) (sourceWindows ())->list
[i
], hasBreak
);
545 } /* tuiAllSetHasBreakAt */
548 /*********************************
549 ** EXECUTION INFO FUNCTIONS **
550 *********************************/
553 ** tuiSetExecInfoContent().
554 ** Function to initialize the content of the execution info window,
555 ** based upon the input window which is either the source or
556 ** disassembly window.
559 tuiSetExecInfoContent (TuiWinInfoPtr winInfo
)
561 TuiStatus ret
= TUI_SUCCESS
;
563 if (winInfo
->detail
.sourceInfo
.executionInfo
!= (TuiGenWinInfoPtr
) NULL
)
565 TuiGenWinInfoPtr execInfoPtr
= winInfo
->detail
.sourceInfo
.executionInfo
;
567 if (execInfoPtr
->content
== (OpaquePtr
) NULL
)
568 execInfoPtr
->content
=
569 (OpaquePtr
) allocContent (winInfo
->generic
.height
,
571 if (execInfoPtr
->content
!= (OpaquePtr
) NULL
)
575 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
577 TuiWinElementPtr element
;
578 TuiWinElementPtr srcElement
;
580 element
= (TuiWinElementPtr
) execInfoPtr
->content
[i
];
581 srcElement
= (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
583 ** First check to see if we have a breakpoint that is
584 ** temporary. If so, and this is our current execution point,
585 ** then clear the break indicator.
587 if (srcElement
->whichElement
.source
.hasBreak
&&
588 srcElement
->whichElement
.source
.isExecPoint
)
590 struct breakpoint
*bp
;
592 extern struct breakpoint
*breakpoint_chain
;
594 for (bp
= breakpoint_chain
;
595 (bp
!= (struct breakpoint
*) NULL
&& !found
);
599 (winInfo
== srcWin
&&
601 srcElement
->whichElement
.source
.lineOrAddr
.lineNo
) ||
602 (winInfo
== disassemWin
&&
603 bp
->address
== (CORE_ADDR
)
604 srcElement
->whichElement
.source
.lineOrAddr
.addr
);
606 srcElement
->whichElement
.source
.hasBreak
=
607 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0);
610 srcElement
->whichElement
.source
.hasBreak
= FALSE
;
613 ** Now update the exec info content based upon the state
614 ** of each line as indicated by the source content.
616 if (srcElement
->whichElement
.source
.hasBreak
&&
617 srcElement
->whichElement
.source
.isExecPoint
)
618 element
->whichElement
.simpleString
= breakLocationStr ();
619 else if (srcElement
->whichElement
.source
.hasBreak
)
620 element
->whichElement
.simpleString
= breakStr ();
621 else if (srcElement
->whichElement
.source
.isExecPoint
)
622 element
->whichElement
.simpleString
= locationStr ();
624 element
->whichElement
.simpleString
= blankStr ();
626 execInfoPtr
->contentSize
= winInfo
->generic
.contentSize
;
633 } /* tuiSetExecInfoContent */
637 ** tuiShowExecInfoContent().
640 tuiShowExecInfoContent (TuiWinInfoPtr winInfo
)
642 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
645 werase (execInfo
->handle
);
646 tuiRefreshWin (execInfo
);
647 for (curLine
= 1; (curLine
<= execInfo
->contentSize
); curLine
++)
648 mvwaddstr (execInfo
->handle
,
652 execInfo
->content
[curLine
- 1])->whichElement
.simpleString
);
653 tuiRefreshWin (execInfo
);
654 execInfo
->contentInUse
= TRUE
;
657 } /* tuiShowExecInfoContent */
661 ** tuiShowAllExecInfosContent()
664 tuiShowAllExecInfosContent (void)
668 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
669 tuiShowExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
672 } /* tuiShowAllExecInfosContent */
676 ** tuiEraseExecInfoContent().
679 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo
)
681 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
683 werase (execInfo
->handle
);
684 tuiRefreshWin (execInfo
);
687 } /* tuiEraseExecInfoContent */
691 ** tuiEraseAllExecInfosContent()
694 tuiEraseAllExecInfosContent (void)
698 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
699 tuiEraseExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
702 } /* tuiEraseAllExecInfosContent */
706 ** tuiClearExecInfoContent().
709 tuiClearExecInfoContent (TuiWinInfoPtr winInfo
)
711 winInfo
->detail
.sourceInfo
.executionInfo
->contentInUse
= FALSE
;
712 tuiEraseExecInfoContent (winInfo
);
715 } /* tuiClearExecInfoContent */
719 ** tuiClearAllExecInfosContent()
722 tuiClearAllExecInfosContent (void)
726 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
727 tuiClearExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
730 } /* tuiClearAllExecInfosContent */
734 ** tuiUpdateExecInfo().
735 ** Function to update the execution info window
738 tuiUpdateExecInfo (TuiWinInfoPtr winInfo
)
740 tuiSetExecInfoContent (winInfo
);
741 tuiShowExecInfoContent (winInfo
);
742 } /* tuiUpdateExecInfo */
746 ** tuiUpdateAllExecInfos()
749 tuiUpdateAllExecInfos (void)
753 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
754 tuiUpdateExecInfo ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
757 } /* tuiUpdateAllExecInfos */
762 ** elz: This function clears the execution info from the source windows
763 ** and resets the locator to display no line info, procedure info, pc
764 ** info. It is called by stack_publish_stopped_with_no_frame, which
765 ** is called then the target terminates execution
768 tuiUpdateOnEnd (void)
771 TuiGenWinInfoPtr locator
;
773 TuiWinInfoPtr winInfo
;
775 locator
= locatorWinInfoPtr ();
777 /* for all the windows (src, asm) */
778 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
782 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
786 tuiSetIsExecPointAt (l
, winInfo
); /* the target is'n running */
787 /* -1 should not match any line number or pc */
788 tuiSetExecInfoContent (winInfo
); /*set winInfo so that > is'n displayed */
789 tuiShowExecInfoContent (winInfo
); /* display the new contents */
792 /*now update the locator */
793 tuiClearLocatorDisplay ();
794 tuiGetLocatorFilename (locator
, &filename
);
800 &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
);
801 tuiShowLocatorContent ();
804 } /* tuiUpdateOnEnd */
809 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo
)
811 register char *srcLine
, *srcLineBuf
;
812 register int i
, lineWidth
, c
, maxLines
;
813 TuiStatus ret
= TUI_FAILURE
;
815 maxLines
= winInfo
->generic
.height
; /* less the highlight box */
816 lineWidth
= winInfo
->generic
.width
- 1;
818 ** Allocate the buffer for the source lines. Do this only once since they
819 ** will be re-used for all source displays. The only other time this will
820 ** be done is when a window's size changes.
822 if (winInfo
->generic
.content
== (OpaquePtr
) NULL
)
824 srcLineBuf
= (char *) xmalloc ((maxLines
* lineWidth
) * sizeof (char));
825 if (srcLineBuf
== (char *) NULL
)
827 "Unable to Allocate Memory for Source or Disassembly Display.\n",
831 /* allocate the content list */
832 if ((winInfo
->generic
.content
=
833 (OpaquePtr
) allocContent (maxLines
, SRC_WIN
)) == (OpaquePtr
) NULL
)
835 tuiFree (srcLineBuf
);
836 srcLineBuf
= (char *) NULL
;
838 "Unable to Allocate Memory for Source or Disassembly Display.\n",
842 for (i
= 0; i
< maxLines
; i
++)
844 winInfo
->generic
.content
[i
])->whichElement
.source
.line
=
845 srcLineBuf
+ (lineWidth
* i
);
852 } /* tuiAllocSourceBuffer */
856 ** tuiLineIsDisplayed().
857 ** Answer whether the a particular line number or address is displayed
858 ** in the current source window.
861 tuiLineIsDisplayed (int line
, TuiWinInfoPtr winInfo
,
864 int isDisplayed
= FALSE
;
868 threshold
= SCROLL_THRESHOLD
;
872 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
874 isDisplayed
= (((TuiWinElementPtr
)
875 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.lineNo
881 } /* tuiLineIsDisplayed */
885 ** tuiLineIsDisplayed().
886 ** Answer whether the a particular line number or address is displayed
887 ** in the current source window.
890 tuiAddrIsDisplayed (CORE_ADDR addr
, TuiWinInfoPtr winInfo
,
893 int isDisplayed
= FALSE
;
897 threshold
= SCROLL_THRESHOLD
;
901 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
903 isDisplayed
= (((TuiWinElementPtr
)
904 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.addr
913 /*****************************************
914 ** STATIC LOCAL FUNCTIONS **
915 ******************************************/