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"
32 #include "tuiGeneralWin.h"
33 #include "tuiSourceWin.h"
34 #include "tuiSource.h"
35 #include "tuiDisassem.h"
38 /*****************************************
39 ** EXTERNAL FUNCTION DECLS **
40 ******************************************/
42 /*****************************************
43 ** EXTERNAL DATA DECLS **
44 ******************************************/
45 extern int current_source_line
;
46 extern struct symtab
*current_source_symtab
;
49 /*****************************************
50 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
51 ******************************************/
53 /*****************************************
54 ** STATIC LOCAL DATA **
55 ******************************************/
58 /*****************************************
59 ** PUBLIC FUNCTIONS **
60 ******************************************/
62 /*********************************
63 ** SOURCE/DISASSEM FUNCTIONS **
64 *********************************/
67 ** tuiSrcWinIsDisplayed().
70 tuiSrcWinIsDisplayed (void)
72 return (m_winPtrNotNull (srcWin
) && srcWin
->generic
.isVisible
);
73 } /* tuiSrcWinIsDisplayed */
77 ** tuiAsmWinIsDisplayed().
80 tuiAsmWinIsDisplayed (void)
82 return (m_winPtrNotNull (disassemWin
) && disassemWin
->generic
.isVisible
);
83 } /* tuiAsmWinIsDisplayed */
87 ** tuiDisplayMainFunction().
88 ** Function to display the "main" routine"
91 tuiDisplayMainFunction (void)
93 if ((sourceWindows ())->count
> 0)
97 addr
= parse_and_eval_address ("main");
98 if (addr
== (CORE_ADDR
) 0)
99 addr
= parse_and_eval_address ("MAIN");
100 if (addr
!= (CORE_ADDR
) 0)
102 struct symtab_and_line sal
;
104 tuiUpdateSourceWindowsWithAddr (addr
);
105 sal
= find_pc_line (addr
, 0);
106 tuiSwitchFilename (sal
.symtab
->filename
);
111 } /* tuiDisplayMainFunction */
116 ** tuiUpdateSourceWindow().
117 ** Function to display source in the source window. This function
118 ** initializes the horizontal scroll to 0.
121 tuiUpdateSourceWindow (TuiWinInfoPtr winInfo
, struct symtab
*s
,
122 TuiLineOrAddress lineOrAddr
, int noerror
)
124 winInfo
->detail
.sourceInfo
.horizontalOffset
= 0;
125 tuiUpdateSourceWindowAsIs (winInfo
, s
, lineOrAddr
, noerror
);
128 } /* tuiUpdateSourceWindow */
132 ** tuiUpdateSourceWindowAsIs().
133 ** Function to display source in the source/asm window. This
134 ** function shows the source as specified by the horizontal offset.
137 tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo
, struct symtab
*s
,
138 TuiLineOrAddress lineOrAddr
, int noerror
)
142 if (winInfo
->generic
.type
== SRC_WIN
)
143 ret
= tuiSetSourceContent (s
, lineOrAddr
.lineNo
, noerror
);
145 ret
= tuiSetDisassemContent (s
, lineOrAddr
.addr
);
147 if (ret
== TUI_FAILURE
)
149 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
150 tuiClearExecInfoContent (winInfo
);
154 tuiEraseSourceContent (winInfo
, NO_EMPTY_SOURCE_PROMPT
);
155 tuiShowSourceContent (winInfo
);
156 tuiUpdateExecInfo (winInfo
);
157 if (winInfo
->generic
.type
== SRC_WIN
)
159 current_source_line
= lineOrAddr
.lineNo
+
160 (winInfo
->generic
.contentSize
- 2);
161 current_source_symtab
= s
;
163 ** If the focus was in the asm win, put it in the src
164 ** win if we don't have a split layout
166 if (tuiWinWithFocus () == disassemWin
&&
167 currentLayout () != SRC_DISASSEM_COMMAND
)
168 tuiSetWinFocusTo (srcWin
);
174 } /* tuiUpdateSourceWindowAsIs */
178 ** tuiUpdateSourceWindowsWithAddr().
179 ** Function to ensure that the source and/or disassemly windows
180 ** reflect the input address.
183 tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr
)
187 struct symtab_and_line sal
;
190 switch (currentLayout ())
192 case DISASSEM_COMMAND
:
193 case DISASSEM_DATA_COMMAND
:
194 tuiShowDisassem (addr
);
196 case SRC_DISASSEM_COMMAND
:
197 tuiShowDisassemAndUpdateSource (addr
);
200 sal
= find_pc_line (addr
, 0);
202 tuiShowSource (sal
.symtab
, l
, FALSE
);
210 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
212 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
214 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
215 tuiClearExecInfoContent (winInfo
);
220 } /* tuiUpdateSourceWindowsWithAddr */
223 ** tuiUpdateSourceWindowsWithLine().
224 ** Function to ensure that the source and/or disassemly windows
225 ** reflect the input address.
228 tuiUpdateSourceWindowsWithLine (struct symtab
*s
, int line
)
233 switch (currentLayout ())
235 case DISASSEM_COMMAND
:
236 case DISASSEM_DATA_COMMAND
:
237 find_line_pc (s
, line
, &pc
);
238 tuiUpdateSourceWindowsWithAddr (pc
);
242 tuiShowSource (s
, l
, FALSE
);
243 if (currentLayout () == SRC_DISASSEM_COMMAND
)
245 find_line_pc (s
, line
, &pc
);
246 tuiShowDisassem (pc
);
252 } /* tuiUpdateSourceWindowsWithLine */
255 ** tuiClearSourceContent().
258 tuiClearSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
260 if (m_winPtrNotNull (winInfo
))
264 winInfo
->generic
.contentInUse
= FALSE
;
265 tuiEraseSourceContent (winInfo
, displayPrompt
);
266 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
268 TuiWinElementPtr element
=
269 (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
270 element
->whichElement
.source
.hasBreak
= FALSE
;
271 element
->whichElement
.source
.isExecPoint
= FALSE
;
276 } /* tuiClearSourceContent */
280 ** tuiClearAllSourceWinsContent().
283 tuiClearAllSourceWinsContent (int displayPrompt
)
287 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
288 tuiClearSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
292 } /* tuiClearAllSourceWinsContent */
296 ** tuiEraseSourceContent().
299 tuiEraseSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
302 int halfWidth
= (winInfo
->generic
.width
- 2) / 2;
304 if (winInfo
->generic
.handle
!= (WINDOW
*) NULL
)
306 werase (winInfo
->generic
.handle
);
307 checkAndDisplayHighlightIfNeeded (winInfo
);
308 if (displayPrompt
== EMPTY_SOURCE_PROMPT
)
312 if (winInfo
->generic
.type
== SRC_WIN
)
313 noSrcStr
= NO_SRC_STRING
;
315 noSrcStr
= NO_DISASSEM_STRING
;
316 if (strlen (noSrcStr
) >= halfWidth
)
319 xPos
= halfWidth
- strlen (noSrcStr
);
320 mvwaddstr (winInfo
->generic
.handle
,
321 (winInfo
->generic
.height
/ 2),
325 /* elz: added this function call to set the real contents of
326 the window to what is on the screen, so that later calls
327 to refresh, do display
328 the correct stuff, and not the old image */
330 tuiSetSourceContentNil (winInfo
, noSrcStr
);
332 tuiRefreshWin (&winInfo
->generic
);
335 } /* tuiEraseSourceContent */
339 ** tuiEraseAllSourceContent().
342 tuiEraseAllSourceWinsContent (int displayPrompt
)
346 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
347 tuiEraseSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
],
351 } /* tuiEraseAllSourceWinsContent */
355 ** tuiShowSourceContent().
358 tuiShowSourceContent (TuiWinInfoPtr winInfo
)
360 int curLine
, i
, curX
;
362 tuiEraseSourceContent (winInfo
, (winInfo
->generic
.contentSize
<= 0));
363 if (winInfo
->generic
.contentSize
> 0)
367 for (curLine
= 1; (curLine
<= winInfo
->generic
.contentSize
); curLine
++)
369 winInfo
->generic
.handle
,
373 winInfo
->generic
.content
[curLine
- 1])->whichElement
.source
.line
);
375 checkAndDisplayHighlightIfNeeded (winInfo
);
376 tuiRefreshWin (&winInfo
->generic
);
377 winInfo
->generic
.contentInUse
= TRUE
;
380 } /* tuiShowSourceContent */
384 ** tuiShowAllSourceWinsContent()
387 tuiShowAllSourceWinsContent (void)
391 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
392 tuiShowSourceContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
395 } /* tuiShowAllSourceWinsContent */
399 ** tuiHorizontalSourceScroll().
400 ** Scroll the source forward or backward horizontally
403 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo
,
404 TuiScrollDirection direction
,
407 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
412 if (current_source_symtab
== (struct symtab
*) NULL
)
413 s
= find_pc_symtab (selected_frame
->pc
);
415 s
= current_source_symtab
;
417 if (direction
== LEFT_SCROLL
)
418 offset
= winInfo
->detail
.sourceInfo
.horizontalOffset
+ numToScroll
;
422 winInfo
->detail
.sourceInfo
.horizontalOffset
- numToScroll
) < 0)
425 winInfo
->detail
.sourceInfo
.horizontalOffset
= offset
;
426 tuiUpdateSourceWindowAsIs (
430 winInfo
->generic
.content
[0])->whichElement
.source
.lineOrAddr
,
435 } /* tuiHorizontalSourceScroll */
439 ** tuiSetHasExecPointAt().
440 ** Set or clear the hasBreak flag in the line whose line is lineNo.
443 tuiSetIsExecPointAt (TuiLineOrAddress l
, TuiWinInfoPtr winInfo
)
446 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
449 while (i
< winInfo
->generic
.contentSize
)
451 if (content
[i
]->whichElement
.source
.lineOrAddr
.addr
== l
.addr
)
452 content
[i
]->whichElement
.source
.isExecPoint
= TRUE
;
454 content
[i
]->whichElement
.source
.isExecPoint
= FALSE
;
459 } /* tuiSetIsExecPointAt */
462 ** tuiSetHasBreakAt().
463 ** Set or clear the hasBreak flag in the line whose line is lineNo.
466 tuiSetHasBreakAt (struct breakpoint
*bp
, TuiWinInfoPtr winInfo
, int hasBreak
)
469 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
472 while (i
< winInfo
->generic
.contentSize
)
475 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
477 if (winInfo
== srcWin
)
479 char *fileNameDisplayed
= (char *) NULL
;
481 if (((TuiWinElementPtr
)
482 locator
->content
[0])->whichElement
.locator
.fileName
!=
484 fileNameDisplayed
= ((TuiWinElementPtr
)
485 locator
->content
[0])->whichElement
.locator
.fileName
;
486 else if (current_source_symtab
!= (struct symtab
*) NULL
)
487 fileNameDisplayed
= current_source_symtab
->filename
;
489 gotIt
= (fileNameDisplayed
!= (char *) NULL
&&
490 bp
->source_file
!= NULL
&&
491 (strcmp (bp
->source_file
, fileNameDisplayed
) == 0) &&
492 content
[i
]->whichElement
.source
.lineOrAddr
.lineNo
==
496 gotIt
= (content
[i
]->whichElement
.source
.lineOrAddr
.addr
500 content
[i
]->whichElement
.source
.hasBreak
= hasBreak
;
507 } /* tuiSetHasBreakAt */
511 ** tuiAllSetHasBreakAt().
512 ** Set or clear the hasBreak flag in all displayed source windows.
515 tuiAllSetHasBreakAt (struct breakpoint
*bp
, int hasBreak
)
519 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
520 tuiSetHasBreakAt (bp
,
521 (TuiWinInfoPtr
) (sourceWindows ())->list
[i
], hasBreak
);
524 } /* tuiAllSetHasBreakAt */
527 /*********************************
528 ** EXECUTION INFO FUNCTIONS **
529 *********************************/
532 ** tuiSetExecInfoContent().
533 ** Function to initialize the content of the execution info window,
534 ** based upon the input window which is either the source or
535 ** disassembly window.
538 tuiSetExecInfoContent (TuiWinInfoPtr winInfo
)
540 TuiStatus ret
= TUI_SUCCESS
;
542 if (winInfo
->detail
.sourceInfo
.executionInfo
!= (TuiGenWinInfoPtr
) NULL
)
544 TuiGenWinInfoPtr execInfoPtr
= winInfo
->detail
.sourceInfo
.executionInfo
;
546 if (execInfoPtr
->content
== (OpaquePtr
) NULL
)
547 execInfoPtr
->content
=
548 (OpaquePtr
) allocContent (winInfo
->generic
.height
,
550 if (execInfoPtr
->content
!= (OpaquePtr
) NULL
)
554 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
556 TuiWinElementPtr element
;
557 TuiWinElementPtr srcElement
;
559 element
= (TuiWinElementPtr
) execInfoPtr
->content
[i
];
560 srcElement
= (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
562 ** First check to see if we have a breakpoint that is
563 ** temporary. If so, and this is our current execution point,
564 ** then clear the break indicator.
566 if (srcElement
->whichElement
.source
.hasBreak
&&
567 srcElement
->whichElement
.source
.isExecPoint
)
569 struct breakpoint
*bp
;
571 extern struct breakpoint
*breakpoint_chain
;
573 for (bp
= breakpoint_chain
;
574 (bp
!= (struct breakpoint
*) NULL
&& !found
);
578 (winInfo
== srcWin
&&
580 srcElement
->whichElement
.source
.lineOrAddr
.lineNo
) ||
581 (winInfo
== disassemWin
&&
582 bp
->address
== (CORE_ADDR
)
583 srcElement
->whichElement
.source
.lineOrAddr
.addr
);
585 srcElement
->whichElement
.source
.hasBreak
=
586 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0);
589 srcElement
->whichElement
.source
.hasBreak
= FALSE
;
592 ** Now update the exec info content based upon the state
593 ** of each line as indicated by the source content.
595 if (srcElement
->whichElement
.source
.hasBreak
&&
596 srcElement
->whichElement
.source
.isExecPoint
)
597 element
->whichElement
.simpleString
= breakLocationStr ();
598 else if (srcElement
->whichElement
.source
.hasBreak
)
599 element
->whichElement
.simpleString
= breakStr ();
600 else if (srcElement
->whichElement
.source
.isExecPoint
)
601 element
->whichElement
.simpleString
= locationStr ();
603 element
->whichElement
.simpleString
= blankStr ();
605 execInfoPtr
->contentSize
= winInfo
->generic
.contentSize
;
612 } /* tuiSetExecInfoContent */
616 ** tuiShowExecInfoContent().
619 tuiShowExecInfoContent (TuiWinInfoPtr winInfo
)
621 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
624 werase (execInfo
->handle
);
625 tuiRefreshWin (execInfo
);
626 for (curLine
= 1; (curLine
<= execInfo
->contentSize
); curLine
++)
627 mvwaddstr (execInfo
->handle
,
631 execInfo
->content
[curLine
- 1])->whichElement
.simpleString
);
632 tuiRefreshWin (execInfo
);
633 execInfo
->contentInUse
= TRUE
;
636 } /* tuiShowExecInfoContent */
640 ** tuiShowAllExecInfosContent()
643 tuiShowAllExecInfosContent (void)
647 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
648 tuiShowExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
651 } /* tuiShowAllExecInfosContent */
655 ** tuiEraseExecInfoContent().
658 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo
)
660 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
662 werase (execInfo
->handle
);
663 tuiRefreshWin (execInfo
);
666 } /* tuiEraseExecInfoContent */
670 ** tuiEraseAllExecInfosContent()
673 tuiEraseAllExecInfosContent (void)
677 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
678 tuiEraseExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
681 } /* tuiEraseAllExecInfosContent */
685 ** tuiClearExecInfoContent().
688 tuiClearExecInfoContent (TuiWinInfoPtr winInfo
)
690 winInfo
->detail
.sourceInfo
.executionInfo
->contentInUse
= FALSE
;
691 tuiEraseExecInfoContent (winInfo
);
694 } /* tuiClearExecInfoContent */
698 ** tuiClearAllExecInfosContent()
701 tuiClearAllExecInfosContent (void)
705 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
706 tuiClearExecInfoContent ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
709 } /* tuiClearAllExecInfosContent */
713 ** tuiUpdateExecInfo().
714 ** Function to update the execution info window
717 tuiUpdateExecInfo (TuiWinInfoPtr winInfo
)
719 tuiSetExecInfoContent (winInfo
);
720 tuiShowExecInfoContent (winInfo
);
721 } /* tuiUpdateExecInfo */
725 ** tuiUpdateAllExecInfos()
728 tuiUpdateAllExecInfos (void)
732 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
733 tuiUpdateExecInfo ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
736 } /* tuiUpdateAllExecInfos */
741 ** elz: This function clears the execution info from the source windows
742 ** and resets the locator to display no line info, procedure info, pc
743 ** info. It is called by stack_publish_stopped_with_no_frame, which
744 ** is called then the target terminates execution
747 tuiUpdateOnEnd (void)
750 TuiGenWinInfoPtr locator
;
752 TuiWinInfoPtr winInfo
;
754 locator
= locatorWinInfoPtr ();
756 /* for all the windows (src, asm) */
757 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
761 winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
765 tuiSetIsExecPointAt (l
, winInfo
); /* the target is'n running */
766 /* -1 should not match any line number or pc */
767 tuiSetExecInfoContent (winInfo
); /*set winInfo so that > is'n displayed */
768 tuiShowExecInfoContent (winInfo
); /* display the new contents */
771 /*now update the locator */
772 tuiClearLocatorDisplay ();
773 tuiGetLocatorFilename (locator
, &filename
);
779 &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
);
780 tuiShowLocatorContent ();
783 } /* tuiUpdateOnEnd */
788 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo
)
790 register char *srcLine
, *srcLineBuf
;
791 register int i
, lineWidth
, c
, maxLines
;
792 TuiStatus ret
= TUI_FAILURE
;
794 maxLines
= winInfo
->generic
.height
; /* less the highlight box */
795 lineWidth
= winInfo
->generic
.width
- 1;
797 ** Allocate the buffer for the source lines. Do this only once since they
798 ** will be re-used for all source displays. The only other time this will
799 ** be done is when a window's size changes.
801 if (winInfo
->generic
.content
== (OpaquePtr
) NULL
)
803 srcLineBuf
= (char *) xmalloc ((maxLines
* lineWidth
) * sizeof (char));
804 if (srcLineBuf
== (char *) NULL
)
806 "Unable to Allocate Memory for Source or Disassembly Display.\n",
810 /* allocate the content list */
811 if ((winInfo
->generic
.content
=
812 (OpaquePtr
) allocContent (maxLines
, SRC_WIN
)) == (OpaquePtr
) NULL
)
814 tuiFree (srcLineBuf
);
815 srcLineBuf
= (char *) NULL
;
817 "Unable to Allocate Memory for Source or Disassembly Display.\n",
821 for (i
= 0; i
< maxLines
; i
++)
823 winInfo
->generic
.content
[i
])->whichElement
.source
.line
=
824 srcLineBuf
+ (lineWidth
* i
);
831 } /* tuiAllocSourceBuffer */
835 ** tuiLineIsDisplayed().
836 ** Answer whether the a particular line number or address is displayed
837 ** in the current source window.
840 tuiLineIsDisplayed (int line
, TuiWinInfoPtr winInfo
,
843 int isDisplayed
= FALSE
;
847 threshold
= SCROLL_THRESHOLD
;
851 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
853 isDisplayed
= (((TuiWinElementPtr
)
854 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.lineNo
860 } /* tuiLineIsDisplayed */
864 ** tuiLineIsDisplayed().
865 ** Answer whether the a particular line number or address is displayed
866 ** in the current source window.
869 tuiAddrIsDisplayed (CORE_ADDR addr
, TuiWinInfoPtr winInfo
,
872 int isDisplayed
= FALSE
;
876 threshold
= SCROLL_THRESHOLD
;
880 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
882 isDisplayed
= (((TuiWinElementPtr
)
883 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.addr
892 /*****************************************
893 ** STATIC LOCAL FUNCTIONS **
894 ******************************************/