1 /* TUI display source/assembly window.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "breakpoint.h"
33 #include "tuiGeneralWin.h"
34 #include "tuiSourceWin.h"
35 #include "tuiSource.h"
36 #include "tuiDisassem.h"
39 /*****************************************
40 ** EXTERNAL FUNCTION DECLS **
41 ******************************************/
43 /*****************************************
44 ** EXTERNAL DATA DECLS **
45 ******************************************/
46 extern int current_source_line
;
47 extern struct symtab
*current_source_symtab
;
50 /*****************************************
51 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
52 ******************************************/
54 /*****************************************
55 ** STATIC LOCAL DATA **
56 ******************************************/
59 /*****************************************
60 ** PUBLIC FUNCTIONS **
61 ******************************************/
63 /*********************************
64 ** SOURCE/DISASSEM FUNCTIONS **
65 *********************************/
68 ** tuiSrcWinIsDisplayed().
71 tuiSrcWinIsDisplayed (void)
73 return (m_winPtrNotNull (srcWin
) && srcWin
->generic
.isVisible
);
74 } /* tuiSrcWinIsDisplayed */
78 ** tuiAsmWinIsDisplayed().
81 tuiAsmWinIsDisplayed (void)
83 return (m_winPtrNotNull (disassemWin
) && disassemWin
->generic
.isVisible
);
84 } /* tuiAsmWinIsDisplayed */
88 ** tuiDisplayMainFunction().
89 ** Function to display the "main" routine"
92 tuiDisplayMainFunction (void)
94 if ((sourceWindows ())->count
> 0)
98 addr
= parse_and_eval_address ("main");
99 if (addr
== (CORE_ADDR
) 0)
100 addr
= parse_and_eval_address ("MAIN");
101 if (addr
!= (CORE_ADDR
) 0)
103 struct symtab_and_line sal
;
105 tuiUpdateSourceWindowsWithAddr (addr
);
106 sal
= find_pc_line (addr
, 0);
107 tuiSwitchFilename (sal
.symtab
->filename
);
112 } /* tuiDisplayMainFunction */
117 ** tuiUpdateSourceWindow().
118 ** Function to display source in the source window. This function
119 ** initializes the horizontal scroll to 0.
122 tuiUpdateSourceWindow (TuiWinInfoPtr winInfo
, struct symtab
*s
,
123 TuiLineOrAddress lineOrAddr
, int noerror
)
125 winInfo
->detail
.sourceInfo
.horizontalOffset
= 0;
126 tuiUpdateSourceWindowAsIs (winInfo
, s
, lineOrAddr
, noerror
);
129 } /* tuiUpdateSourceWindow */
133 ** tuiUpdateSourceWindowAsIs().
134 ** Function to display source in the source/asm window. This
135 ** function shows the source as specified by the horizontal offset.
138 tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo
, struct symtab
*s
,
139 TuiLineOrAddress lineOrAddr
, int noerror
)
143 if (winInfo
->generic
.type
== SRC_WIN
)
144 ret
= tuiSetSourceContent (s
, lineOrAddr
.lineNo
, noerror
);
146 ret
= tuiSetDisassemContent (s
, lineOrAddr
.addr
);
148 if (ret
== TUI_FAILURE
)
150 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
151 tuiClearExecInfoContent (winInfo
);
155 tuiEraseSourceContent (winInfo
, NO_EMPTY_SOURCE_PROMPT
);
156 tuiShowSourceContent (winInfo
);
157 tuiUpdateExecInfo (winInfo
);
158 if (winInfo
->generic
.type
== SRC_WIN
)
160 current_source_line
= lineOrAddr
.lineNo
+
161 (winInfo
->generic
.contentSize
- 2);
162 current_source_symtab
= s
;
164 ** If the focus was in the asm win, put it in the src
165 ** win if we don't have a split layout
167 if (tuiWinWithFocus () == disassemWin
&&
168 currentLayout () != SRC_DISASSEM_COMMAND
)
169 tuiSetWinFocusTo (srcWin
);
175 } /* tuiUpdateSourceWindowAsIs */
179 ** tuiUpdateSourceWindowsWithAddr().
180 ** Function to ensure that the source and/or disassemly windows
181 ** reflect the input address.
184 tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr
)
188 struct symtab_and_line sal
;
191 switch (currentLayout ())
193 case DISASSEM_COMMAND
:
194 case DISASSEM_DATA_COMMAND
:
195 tuiShowDisassem (addr
);
197 case SRC_DISASSEM_COMMAND
:
198 tuiShowDisassemAndUpdateSource (addr
);
201 sal
= find_pc_line (addr
, 0);
203 tuiShowSource (sal
.symtab
, l
, FALSE
);
211 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
213 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
215 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
216 tuiClearExecInfoContent (winInfo
);
221 } /* tuiUpdateSourceWindowsWithAddr */
224 ** tuiUpdateSourceWindowsWithLine().
225 ** Function to ensure that the source and/or disassemly windows
226 ** reflect the input address.
229 tuiUpdateSourceWindowsWithLine (struct symtab
*s
, int line
)
234 switch (currentLayout ())
236 case DISASSEM_COMMAND
:
237 case DISASSEM_DATA_COMMAND
:
238 find_line_pc (s
, line
, &pc
);
239 tuiUpdateSourceWindowsWithAddr (pc
);
243 tuiShowSource (s
, l
, FALSE
);
244 if (currentLayout () == SRC_DISASSEM_COMMAND
)
246 find_line_pc (s
, line
, &pc
);
247 tuiShowDisassem (pc
);
253 } /* tuiUpdateSourceWindowsWithLine */
256 ** tuiClearSourceContent().
259 tuiClearSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
261 if (m_winPtrNotNull (winInfo
))
265 winInfo
->generic
.contentInUse
= FALSE
;
266 tuiEraseSourceContent (winInfo
, displayPrompt
);
267 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
269 TuiWinElementPtr element
=
270 (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
271 element
->whichElement
.source
.hasBreak
= FALSE
;
272 element
->whichElement
.source
.isExecPoint
= FALSE
;
277 } /* tuiClearSourceContent */
281 ** tuiClearAllSourceWinsContent().
284 tuiClearAllSourceWinsContent (int displayPrompt
)
288 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
289 tuiClearSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
293 } /* tuiClearAllSourceWinsContent */
297 ** tuiEraseSourceContent().
300 tuiEraseSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
303 int halfWidth
= (winInfo
->generic
.width
- 2) / 2;
305 if (winInfo
->generic
.handle
!= (WINDOW
*) NULL
)
307 werase (winInfo
->generic
.handle
);
308 checkAndDisplayHighlightIfNeeded (winInfo
);
309 if (displayPrompt
== EMPTY_SOURCE_PROMPT
)
313 if (winInfo
->generic
.type
== SRC_WIN
)
314 noSrcStr
= NO_SRC_STRING
;
316 noSrcStr
= NO_DISASSEM_STRING
;
317 if (strlen (noSrcStr
) >= halfWidth
)
320 xPos
= halfWidth
- strlen (noSrcStr
);
321 mvwaddstr (winInfo
->generic
.handle
,
322 (winInfo
->generic
.height
/ 2),
326 /* elz: added this function call to set the real contents of
327 the window to what is on the screen, so that later calls
328 to refresh, do display
329 the correct stuff, and not the old image */
331 tuiSetSourceContentNil (winInfo
, noSrcStr
);
333 tuiRefreshWin (&winInfo
->generic
);
336 } /* tuiEraseSourceContent */
340 ** tuiEraseAllSourceContent().
343 tuiEraseAllSourceWinsContent (int displayPrompt
)
347 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
348 tuiEraseSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
352 } /* tuiEraseAllSourceWinsContent */
356 ** tuiShowSourceContent().
359 tuiShowSourceContent (TuiWinInfoPtr winInfo
)
361 int curLine
, i
, curX
;
363 tuiEraseSourceContent (winInfo
, (winInfo
->generic
.contentSize
<= 0));
364 if (winInfo
->generic
.contentSize
> 0)
368 for (curLine
= 1; (curLine
<= winInfo
->generic
.contentSize
); curLine
++)
370 winInfo
->generic
.handle
,
374 winInfo
->generic
.content
[curLine
- 1])->whichElement
.source
.line
);
376 checkAndDisplayHighlightIfNeeded (winInfo
);
377 tuiRefreshWin (&winInfo
->generic
);
378 winInfo
->generic
.contentInUse
= TRUE
;
381 } /* tuiShowSourceContent */
385 ** tuiShowAllSourceWinsContent()
388 tuiShowAllSourceWinsContent (void)
392 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
393 tuiShowSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
396 } /* tuiShowAllSourceWinsContent */
400 ** tuiHorizontalSourceScroll().
401 ** Scroll the source forward or backward horizontally
404 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo
,
405 TuiScrollDirection direction
,
408 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
413 if (current_source_symtab
== (struct symtab
*) NULL
)
414 s
= find_pc_symtab (selected_frame
->pc
);
416 s
= current_source_symtab
;
418 if (direction
== LEFT_SCROLL
)
419 offset
= winInfo
->detail
.sourceInfo
.horizontalOffset
+ numToScroll
;
423 winInfo
->detail
.sourceInfo
.horizontalOffset
- numToScroll
) < 0)
426 winInfo
->detail
.sourceInfo
.horizontalOffset
= offset
;
427 tuiUpdateSourceWindowAsIs (
431 winInfo
->generic
.content
[0])->whichElement
.source
.lineOrAddr
,
436 } /* tuiHorizontalSourceScroll */
440 ** tuiSetHasExecPointAt().
441 ** Set or clear the hasBreak flag in the line whose line is lineNo.
444 tuiSetIsExecPointAt (TuiLineOrAddress l
, TuiWinInfoPtr winInfo
)
447 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
450 while (i
< winInfo
->generic
.contentSize
)
452 if (content
[i
]->whichElement
.source
.lineOrAddr
.addr
== l
.addr
)
453 content
[i
]->whichElement
.source
.isExecPoint
= TRUE
;
455 content
[i
]->whichElement
.source
.isExecPoint
= FALSE
;
460 } /* tuiSetIsExecPointAt */
463 ** tuiSetHasBreakAt().
464 ** Set or clear the hasBreak flag in the line whose line is lineNo.
467 tuiSetHasBreakAt (struct breakpoint
*bp
, TuiWinInfoPtr winInfo
, int hasBreak
)
470 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
473 while (i
< winInfo
->generic
.contentSize
)
476 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
478 if (winInfo
== srcWin
)
480 char *fileNameDisplayed
= (char *) NULL
;
482 if (((TuiWinElementPtr
)
483 locator
->content
[0])->whichElement
.locator
.fileName
!=
485 fileNameDisplayed
= ((TuiWinElementPtr
)
486 locator
->content
[0])->whichElement
.locator
.fileName
;
487 else if (current_source_symtab
!= (struct symtab
*) NULL
)
488 fileNameDisplayed
= current_source_symtab
->filename
;
490 gotIt
= (fileNameDisplayed
!= (char *) NULL
&&
491 bp
->source_file
!= NULL
&&
492 (strcmp (bp
->source_file
, fileNameDisplayed
) == 0) &&
493 content
[i
]->whichElement
.source
.lineOrAddr
.lineNo
==
497 gotIt
= (content
[i
]->whichElement
.source
.lineOrAddr
.addr
501 content
[i
]->whichElement
.source
.hasBreak
= hasBreak
;
508 } /* tuiSetHasBreakAt */
512 ** tuiAllSetHasBreakAt().
513 ** Set or clear the hasBreak flag in all displayed source windows.
516 tuiAllSetHasBreakAt (struct breakpoint
*bp
, int hasBreak
)
520 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
521 tuiSetHasBreakAt (bp
,
522 (TuiWinInfoPtr
) (sourceWindows ())->list
[i
], hasBreak
);
525 } /* tuiAllSetHasBreakAt */
528 /*********************************
529 ** EXECUTION INFO FUNCTIONS **
530 *********************************/
533 ** tuiSetExecInfoContent().
534 ** Function to initialize the content of the execution info window,
535 ** based upon the input window which is either the source or
536 ** disassembly window.
539 tuiSetExecInfoContent (TuiWinInfoPtr winInfo
)
541 TuiStatus ret
= TUI_SUCCESS
;
543 if (winInfo
->detail
.sourceInfo
.executionInfo
!= (TuiGenWinInfoPtr
) NULL
)
545 TuiGenWinInfoPtr execInfoPtr
= winInfo
->detail
.sourceInfo
.executionInfo
;
547 if (execInfoPtr
->content
== (OpaquePtr
) NULL
)
548 execInfoPtr
->content
=
549 (OpaquePtr
) allocContent (winInfo
->generic
.height
,
551 if (execInfoPtr
->content
!= (OpaquePtr
) NULL
)
555 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
557 TuiWinElementPtr element
;
558 TuiWinElementPtr srcElement
;
560 element
= (TuiWinElementPtr
) execInfoPtr
->content
[i
];
561 srcElement
= (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
563 ** First check to see if we have a breakpoint that is
564 ** temporary. If so, and this is our current execution point,
565 ** then clear the break indicator.
567 if (srcElement
->whichElement
.source
.hasBreak
&&
568 srcElement
->whichElement
.source
.isExecPoint
)
570 struct breakpoint
*bp
;
572 extern struct breakpoint
*breakpoint_chain
;
574 for (bp
= breakpoint_chain
;
575 (bp
!= (struct breakpoint
*) NULL
&& !found
);
579 (winInfo
== srcWin
&&
581 srcElement
->whichElement
.source
.lineOrAddr
.lineNo
) ||
582 (winInfo
== disassemWin
&&
583 bp
->address
== (CORE_ADDR
)
584 srcElement
->whichElement
.source
.lineOrAddr
.addr
);
586 srcElement
->whichElement
.source
.hasBreak
=
587 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0);
590 srcElement
->whichElement
.source
.hasBreak
= FALSE
;
593 ** Now update the exec info content based upon the state
594 ** of each line as indicated by the source content.
596 if (srcElement
->whichElement
.source
.hasBreak
&&
597 srcElement
->whichElement
.source
.isExecPoint
)
598 element
->whichElement
.simpleString
= breakLocationStr ();
599 else if (srcElement
->whichElement
.source
.hasBreak
)
600 element
->whichElement
.simpleString
= breakStr ();
601 else if (srcElement
->whichElement
.source
.isExecPoint
)
602 element
->whichElement
.simpleString
= locationStr ();
604 element
->whichElement
.simpleString
= blankStr ();
606 execInfoPtr
->contentSize
= winInfo
->generic
.contentSize
;
613 } /* tuiSetExecInfoContent */
617 ** tuiShowExecInfoContent().
620 tuiShowExecInfoContent (TuiWinInfoPtr winInfo
)
622 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
625 werase (execInfo
->handle
);
626 tuiRefreshWin (execInfo
);
627 for (curLine
= 1; (curLine
<= execInfo
->contentSize
); curLine
++)
628 mvwaddstr (execInfo
->handle
,
632 execInfo
->content
[curLine
- 1])->whichElement
.simpleString
);
633 tuiRefreshWin (execInfo
);
634 execInfo
->contentInUse
= TRUE
;
637 } /* tuiShowExecInfoContent */
641 ** tuiShowAllExecInfosContent()
644 tuiShowAllExecInfosContent (void)
648 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
649 tuiShowExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
652 } /* tuiShowAllExecInfosContent */
656 ** tuiEraseExecInfoContent().
659 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo
)
661 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
663 werase (execInfo
->handle
);
664 tuiRefreshWin (execInfo
);
667 } /* tuiEraseExecInfoContent */
671 ** tuiEraseAllExecInfosContent()
674 tuiEraseAllExecInfosContent (void)
678 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
679 tuiEraseExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
682 } /* tuiEraseAllExecInfosContent */
686 ** tuiClearExecInfoContent().
689 tuiClearExecInfoContent (TuiWinInfoPtr winInfo
)
691 winInfo
->detail
.sourceInfo
.executionInfo
->contentInUse
= FALSE
;
692 tuiEraseExecInfoContent (winInfo
);
695 } /* tuiClearExecInfoContent */
699 ** tuiClearAllExecInfosContent()
702 tuiClearAllExecInfosContent (void)
706 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
707 tuiClearExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
710 } /* tuiClearAllExecInfosContent */
714 ** tuiUpdateExecInfo().
715 ** Function to update the execution info window
718 tuiUpdateExecInfo (TuiWinInfoPtr winInfo
)
720 tuiSetExecInfoContent (winInfo
);
721 tuiShowExecInfoContent (winInfo
);
722 } /* tuiUpdateExecInfo */
726 ** tuiUpdateAllExecInfos()
729 tuiUpdateAllExecInfos (void)
733 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
734 tuiUpdateExecInfo ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
737 } /* tuiUpdateAllExecInfos */
742 ** elz: This function clears the execution info from the source windows
743 ** and resets the locator to display no line info, procedure info, pc
744 ** info. It is called by stack_publish_stopped_with_no_frame, which
745 ** is called then the target terminates execution
748 tuiUpdateOnEnd (void)
751 TuiGenWinInfoPtr locator
;
753 TuiWinInfoPtr winInfo
;
755 locator
= locatorWinInfoPtr ();
757 /* for all the windows (src, asm) */
758 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
762 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
766 tuiSetIsExecPointAt (l
, winInfo
); /* the target is'n running */
767 /* -1 should not match any line number or pc */
768 tuiSetExecInfoContent (winInfo
); /*set winInfo so that > is'n displayed */
769 tuiShowExecInfoContent (winInfo
); /* display the new contents */
772 /*now update the locator */
773 tuiClearLocatorDisplay ();
774 tuiGetLocatorFilename (locator
, &filename
);
780 &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
);
781 tuiShowLocatorContent ();
784 } /* tuiUpdateOnEnd */
789 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo
)
791 register char *srcLine
, *srcLineBuf
;
792 register int i
, lineWidth
, c
, maxLines
;
793 TuiStatus ret
= TUI_FAILURE
;
795 maxLines
= winInfo
->generic
.height
; /* less the highlight box */
796 lineWidth
= winInfo
->generic
.width
- 1;
798 ** Allocate the buffer for the source lines. Do this only once since they
799 ** will be re-used for all source displays. The only other time this will
800 ** be done is when a window's size changes.
802 if (winInfo
->generic
.content
== (OpaquePtr
) NULL
)
804 srcLineBuf
= (char *) xmalloc ((maxLines
* lineWidth
) * sizeof (char));
805 if (srcLineBuf
== (char *) NULL
)
807 "Unable to Allocate Memory for Source or Disassembly Display.\n",
811 /* allocate the content list */
812 if ((winInfo
->generic
.content
=
813 (OpaquePtr
) allocContent (maxLines
, SRC_WIN
)) == (OpaquePtr
) NULL
)
815 tuiFree (srcLineBuf
);
816 srcLineBuf
= (char *) NULL
;
818 "Unable to Allocate Memory for Source or Disassembly Display.\n",
822 for (i
= 0; i
< maxLines
; i
++)
824 winInfo
->generic
.content
[i
])->whichElement
.source
.line
=
825 srcLineBuf
+ (lineWidth
* i
);
832 } /* tuiAllocSourceBuffer */
836 ** tuiLineIsDisplayed().
837 ** Answer whether the a particular line number or address is displayed
838 ** in the current source window.
841 tuiLineIsDisplayed (int line
, TuiWinInfoPtr winInfo
,
844 int isDisplayed
= FALSE
;
848 threshold
= SCROLL_THRESHOLD
;
852 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
854 isDisplayed
= (((TuiWinElementPtr
)
855 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.lineNo
861 } /* tuiLineIsDisplayed */
865 ** tuiLineIsDisplayed().
866 ** Answer whether the a particular line number or address is displayed
867 ** in the current source window.
870 tuiAddrIsDisplayed (CORE_ADDR addr
, TuiWinInfoPtr winInfo
,
873 int isDisplayed
= FALSE
;
877 threshold
= SCROLL_THRESHOLD
;
881 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
883 isDisplayed
= (((TuiWinElementPtr
)
884 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.addr
893 /*****************************************
894 ** STATIC LOCAL FUNCTIONS **
895 ******************************************/