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 Opaque 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 Opaque lineOrAddr, int noerror)
142 if (winInfo->generic.type == SRC_WIN)
143 ret = tuiSetSourceContent (s, (int) lineOrAddr, noerror);
145 ret = tuiSetDisassemContent (s, (Opaque) lineOrAddr);
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 = (int) lineOrAddr +
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;
189 switch (currentLayout ())
191 case DISASSEM_COMMAND:
192 case DISASSEM_DATA_COMMAND:
193 tuiShowDisassem (addr);
195 case SRC_DISASSEM_COMMAND:
196 tuiShowDisassemAndUpdateSource (addr);
199 sal = find_pc_line (addr, 0);
200 tuiShowSource (sal.symtab, sal.line, FALSE);
208 for (i = 0; i < (sourceWindows ())->count; i++)
210 TuiWinInfoPtr winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
212 tuiClearSourceContent (winInfo, EMPTY_SOURCE_PROMPT);
213 tuiClearExecInfoContent (winInfo);
218 } /* tuiUpdateSourceWindowsWithAddr */
222 ** tui_vUpdateSourceWindowsWithAddr()
223 ** Update the source window with the address in a va_list
226 tui_vUpdateSourceWindowsWithAddr (va_list args)
228 Opaque addr = va_arg (args, Opaque);
230 tuiUpdateSourceWindowsWithAddr (addr);
233 } /* tui_vUpdateSourceWindowsWithAddr */
237 ** tuiUpdateSourceWindowsWithLine().
238 ** Function to ensure that the source and/or disassemly windows
239 ** reflect the input address.
242 tuiUpdateSourceWindowsWithLine (struct symtab *s, int line)
246 switch (currentLayout ())
248 case DISASSEM_COMMAND:
249 case DISASSEM_DATA_COMMAND:
250 find_line_pc (s, line, &pc);
251 tuiUpdateSourceWindowsWithAddr (pc);
254 tuiShowSource (s, line, FALSE);
255 if (currentLayout () == SRC_DISASSEM_COMMAND)
257 find_line_pc (s, line, &pc);
258 tuiShowDisassem (pc);
264 } /* tuiUpdateSourceWindowsWithLine */
268 ** tui_vUpdateSourceWindowsWithLine()
269 ** Update the source window with the line number in a va_list
272 tui_vUpdateSourceWindowsWithLine (va_list args)
274 struct symtab *s = va_arg (args, struct symtab *);
275 int line = va_arg (args, int);
277 tuiUpdateSourceWindowsWithLine (s, line);
280 } /* tui_vUpdateSourceWindowsWithLine */
284 ** tuiClearSourceContent().
287 tuiClearSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
289 if (m_winPtrNotNull (winInfo))
293 winInfo->generic.contentInUse = FALSE;
294 tuiEraseSourceContent (winInfo, displayPrompt);
295 for (i = 0; i < winInfo->generic.contentSize; i++)
297 TuiWinElementPtr element =
298 (TuiWinElementPtr) winInfo->generic.content[i];
299 element->whichElement.source.hasBreak = FALSE;
300 element->whichElement.source.isExecPoint = FALSE;
305 } /* tuiClearSourceContent */
309 ** tuiClearAllSourceWinsContent().
312 tuiClearAllSourceWinsContent (int displayPrompt)
316 for (i = 0; i < (sourceWindows ())->count; i++)
317 tuiClearSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
321 } /* tuiClearAllSourceWinsContent */
325 ** tuiEraseSourceContent().
328 tuiEraseSourceContent (TuiWinInfoPtr winInfo, int displayPrompt)
331 int halfWidth = (winInfo->generic.width - 2) / 2;
333 if (winInfo->generic.handle != (WINDOW *) NULL)
335 werase (winInfo->generic.handle);
336 checkAndDisplayHighlightIfNeeded (winInfo);
337 if (displayPrompt == EMPTY_SOURCE_PROMPT)
341 if (winInfo->generic.type == SRC_WIN)
342 noSrcStr = NO_SRC_STRING;
344 noSrcStr = NO_DISASSEM_STRING;
345 if (strlen (noSrcStr) >= halfWidth)
348 xPos = halfWidth - strlen (noSrcStr);
349 mvwaddstr (winInfo->generic.handle,
350 (winInfo->generic.height / 2),
354 /* elz: added this function call to set the real contents of
355 the window to what is on the screen, so that later calls
356 to refresh, do display
357 the correct stuff, and not the old image */
359 tuiSetSourceContentNil (winInfo, noSrcStr);
361 tuiRefreshWin (&winInfo->generic);
364 } /* tuiEraseSourceContent */
368 ** tuiEraseAllSourceContent().
371 tuiEraseAllSourceWinsContent (int displayPrompt)
375 for (i = 0; i < (sourceWindows ())->count; i++)
376 tuiEraseSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i],
380 } /* tuiEraseAllSourceWinsContent */
384 ** tuiShowSourceContent().
387 tuiShowSourceContent (TuiWinInfoPtr winInfo)
389 int curLine, i, curX;
391 tuiEraseSourceContent (winInfo, (winInfo->generic.contentSize <= 0));
392 if (winInfo->generic.contentSize > 0)
396 for (curLine = 1; (curLine <= winInfo->generic.contentSize); curLine++)
398 winInfo->generic.handle,
402 winInfo->generic.content[curLine - 1])->whichElement.source.line);
404 checkAndDisplayHighlightIfNeeded (winInfo);
405 tuiRefreshWin (&winInfo->generic);
406 winInfo->generic.contentInUse = TRUE;
409 } /* tuiShowSourceContent */
413 ** tuiShowAllSourceWinsContent()
416 tuiShowAllSourceWinsContent (void)
420 for (i = 0; i < (sourceWindows ())->count; i++)
421 tuiShowSourceContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
424 } /* tuiShowAllSourceWinsContent */
428 ** tuiHorizontalSourceScroll().
429 ** Scroll the source forward or backward horizontally
432 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo,
433 TuiScrollDirection direction,
436 if (winInfo->generic.content != (OpaquePtr) NULL)
441 if (current_source_symtab == (struct symtab *) NULL)
442 s = find_pc_symtab (selected_frame->pc);
444 s = current_source_symtab;
446 if (direction == LEFT_SCROLL)
447 offset = winInfo->detail.sourceInfo.horizontalOffset + numToScroll;
451 winInfo->detail.sourceInfo.horizontalOffset - numToScroll) < 0)
454 winInfo->detail.sourceInfo.horizontalOffset = offset;
455 tuiUpdateSourceWindowAsIs (
458 ((winInfo == srcWin) ?
459 (Opaque) ((TuiWinElementPtr)
460 winInfo->generic.content[0])->whichElement.source.lineOrAddr.lineNo :
461 (Opaque) ((TuiWinElementPtr)
462 winInfo->generic.content[0])->whichElement.source.lineOrAddr.addr),
467 } /* tuiHorizontalSourceScroll */
471 ** tuiSetHasExecPointAt().
472 ** Set or clear the hasBreak flag in the line whose line is lineNo.
475 tuiSetIsExecPointAt (Opaque lineOrAddr, TuiWinInfoPtr winInfo)
478 TuiWinContent content = (TuiWinContent) winInfo->generic.content;
481 while (i < winInfo->generic.contentSize)
483 if (content[i]->whichElement.source.lineOrAddr.addr == lineOrAddr)
484 content[i]->whichElement.source.isExecPoint = TRUE;
486 content[i]->whichElement.source.isExecPoint = FALSE;
491 } /* tuiSetIsExecPointAt */
495 ** tuiSetHasBreakAt().
496 ** Set or clear the hasBreak flag in the line whose line is lineNo.
499 tuiSetHasBreakAt (struct breakpoint *bp, TuiWinInfoPtr winInfo, int hasBreak)
502 TuiWinContent content = (TuiWinContent) winInfo->generic.content;
505 while (i < winInfo->generic.contentSize)
508 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
510 if (winInfo == srcWin)
512 char *fileNameDisplayed = (char *) NULL;
514 if (((TuiWinElementPtr)
515 locator->content[0])->whichElement.locator.fileName !=
517 fileNameDisplayed = ((TuiWinElementPtr)
518 locator->content[0])->whichElement.locator.fileName;
519 else if (current_source_symtab != (struct symtab *) NULL)
520 fileNameDisplayed = current_source_symtab->filename;
522 gotIt = (fileNameDisplayed != (char *) NULL &&
523 bp->source_file != NULL &&
524 (strcmp (bp->source_file, fileNameDisplayed) == 0) &&
525 content[i]->whichElement.source.lineOrAddr.lineNo ==
529 gotIt = (content[i]->whichElement.source.lineOrAddr.addr
533 content[i]->whichElement.source.hasBreak = hasBreak;
540 } /* tuiSetHasBreakAt */
544 ** tuiAllSetHasBreakAt().
545 ** Set or clear the hasBreak flag in all displayed source windows.
548 tuiAllSetHasBreakAt (struct breakpoint *bp, int hasBreak)
552 for (i = 0; i < (sourceWindows ())->count; i++)
553 tuiSetHasBreakAt (bp,
554 (TuiWinInfoPtr) (sourceWindows ())->list[i], hasBreak);
557 } /* tuiAllSetHasBreakAt */
561 ** tui_vAllSetHasBreakAt()
562 ** Set or clear the hasBreak flag in all displayed source windows,
563 ** with params in a va_list
566 tui_vAllSetHasBreakAt (va_list args)
568 struct breakpoint *bp = va_arg (args, struct breakpoint *);
569 int hasBreak = va_arg (args, int);
571 tuiAllSetHasBreakAt (bp, hasBreak);
574 } /* tui_vAllSetHasBreakAt */
578 /*********************************
579 ** EXECUTION INFO FUNCTIONS **
580 *********************************/
583 ** tuiSetExecInfoContent().
584 ** Function to initialize the content of the execution info window,
585 ** based upon the input window which is either the source or
586 ** disassembly window.
589 tuiSetExecInfoContent (TuiWinInfoPtr winInfo)
591 TuiStatus ret = TUI_SUCCESS;
593 if (winInfo->detail.sourceInfo.executionInfo != (TuiGenWinInfoPtr) NULL)
595 TuiGenWinInfoPtr execInfoPtr = winInfo->detail.sourceInfo.executionInfo;
597 if (execInfoPtr->content == (OpaquePtr) NULL)
598 execInfoPtr->content =
599 (OpaquePtr) allocContent (winInfo->generic.height,
601 if (execInfoPtr->content != (OpaquePtr) NULL)
605 for (i = 0; i < winInfo->generic.contentSize; i++)
607 TuiWinElementPtr element;
608 TuiWinElementPtr srcElement;
610 element = (TuiWinElementPtr) execInfoPtr->content[i];
611 srcElement = (TuiWinElementPtr) winInfo->generic.content[i];
613 ** First check to see if we have a breakpoint that is
614 ** temporary. If so, and this is our current execution point,
615 ** then clear the break indicator.
617 if (srcElement->whichElement.source.hasBreak &&
618 srcElement->whichElement.source.isExecPoint)
620 struct breakpoint *bp;
622 extern struct breakpoint *breakpoint_chain;
624 for (bp = breakpoint_chain;
625 (bp != (struct breakpoint *) NULL && !found);
629 (winInfo == srcWin &&
631 srcElement->whichElement.source.lineOrAddr.lineNo) ||
632 (winInfo == disassemWin &&
633 bp->address == (CORE_ADDR)
634 srcElement->whichElement.source.lineOrAddr.addr);
636 srcElement->whichElement.source.hasBreak =
637 (bp->disposition != del || bp->hit_count <= 0);
640 srcElement->whichElement.source.hasBreak = FALSE;
643 ** Now update the exec info content based upon the state
644 ** of each line as indicated by the source content.
646 if (srcElement->whichElement.source.hasBreak &&
647 srcElement->whichElement.source.isExecPoint)
648 element->whichElement.simpleString = breakLocationStr ();
649 else if (srcElement->whichElement.source.hasBreak)
650 element->whichElement.simpleString = breakStr ();
651 else if (srcElement->whichElement.source.isExecPoint)
652 element->whichElement.simpleString = locationStr ();
654 element->whichElement.simpleString = blankStr ();
656 execInfoPtr->contentSize = winInfo->generic.contentSize;
663 } /* tuiSetExecInfoContent */
667 ** tuiShowExecInfoContent().
670 tuiShowExecInfoContent (TuiWinInfoPtr winInfo)
672 TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
675 werase (execInfo->handle);
676 tuiRefreshWin (execInfo);
677 for (curLine = 1; (curLine <= execInfo->contentSize); curLine++)
678 mvwaddstr (execInfo->handle,
682 execInfo->content[curLine - 1])->whichElement.simpleString);
683 tuiRefreshWin (execInfo);
684 execInfo->contentInUse = TRUE;
687 } /* tuiShowExecInfoContent */
691 ** tuiShowAllExecInfosContent()
694 tuiShowAllExecInfosContent (void)
698 for (i = 0; i < (sourceWindows ())->count; i++)
699 tuiShowExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
702 } /* tuiShowAllExecInfosContent */
706 ** tuiEraseExecInfoContent().
709 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo)
711 TuiGenWinInfoPtr execInfo = winInfo->detail.sourceInfo.executionInfo;
713 werase (execInfo->handle);
714 tuiRefreshWin (execInfo);
717 } /* tuiEraseExecInfoContent */
721 ** tuiEraseAllExecInfosContent()
724 tuiEraseAllExecInfosContent (void)
728 for (i = 0; i < (sourceWindows ())->count; i++)
729 tuiEraseExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
732 } /* tuiEraseAllExecInfosContent */
736 ** tuiClearExecInfoContent().
739 tuiClearExecInfoContent (TuiWinInfoPtr winInfo)
741 winInfo->detail.sourceInfo.executionInfo->contentInUse = FALSE;
742 tuiEraseExecInfoContent (winInfo);
745 } /* tuiClearExecInfoContent */
749 ** tuiClearAllExecInfosContent()
752 tuiClearAllExecInfosContent (void)
756 for (i = 0; i < (sourceWindows ())->count; i++)
757 tuiClearExecInfoContent ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
760 } /* tuiClearAllExecInfosContent */
764 ** tuiUpdateExecInfo().
765 ** Function to update the execution info window
768 tuiUpdateExecInfo (TuiWinInfoPtr winInfo)
770 tuiSetExecInfoContent (winInfo);
771 tuiShowExecInfoContent (winInfo);
772 } /* tuiUpdateExecInfo
776 ** tuiUpdateAllExecInfos()
779 tuiUpdateAllExecInfos (void)
783 for (i = 0; i < (sourceWindows ())->count; i++)
784 tuiUpdateExecInfo ((TuiWinInfoPtr) (sourceWindows ())->list[i]);
787 } /* tuiUpdateAllExecInfos */
792 ** elz: This function clears the execution info from the source windows
793 ** and resets the locator to display no line info, procedure info, pc
794 ** info. It is called by stack_publish_stopped_with_no_frame, which
795 ** is called then the target terminates execution
798 tuiUpdateOnEnd (void)
801 TuiGenWinInfoPtr locator;
803 TuiWinInfoPtr winInfo;
805 locator = locatorWinInfoPtr ();
807 /* for all the windows (src, asm) */
808 for (i = 0; i < (sourceWindows ())->count; i++)
810 winInfo = (TuiWinInfoPtr) (sourceWindows ())->list[i];
812 tuiSetIsExecPointAt ((Opaque) - 1, winInfo); /* the target is'n running */
813 /* -1 should not match any line number or pc */
814 tuiSetExecInfoContent (winInfo); /*set winInfo so that > is'n displayed */
815 tuiShowExecInfoContent (winInfo); /* display the new contents */
818 /*now update the locator */
819 tuiClearLocatorDisplay ();
820 tuiGetLocatorFilename (locator, &filename);
826 &((TuiWinElementPtr) locator->content[0])->whichElement.locator);
827 tuiShowLocatorContent ();
830 } /* tuiUpdateOnEnd */
835 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo)
837 register char *srcLine, *srcLineBuf;
838 register int i, lineWidth, c, maxLines;
839 TuiStatus ret = TUI_FAILURE;
841 maxLines = winInfo->generic.height; /* less the highlight box */
842 lineWidth = winInfo->generic.width - 1;
844 ** Allocate the buffer for the source lines. Do this only once since they
845 ** will be re-used for all source displays. The only other time this will
846 ** be done is when a window's size changes.
848 if (winInfo->generic.content == (OpaquePtr) NULL)
850 srcLineBuf = (char *) xmalloc ((maxLines * lineWidth) * sizeof (char));
851 if (srcLineBuf == (char *) NULL)
853 "Unable to Allocate Memory for Source or Disassembly Display.\n",
857 /* allocate the content list */
858 if ((winInfo->generic.content =
859 (OpaquePtr) allocContent (maxLines, SRC_WIN)) == (OpaquePtr) NULL)
861 tuiFree (srcLineBuf);
862 srcLineBuf = (char *) NULL;
864 "Unable to Allocate Memory for Source or Disassembly Display.\n",
868 for (i = 0; i < maxLines; i++)
870 winInfo->generic.content[i])->whichElement.source.line =
871 srcLineBuf + (lineWidth * i);
878 } /* tuiAllocSourceBuffer */
882 ** tuiLineIsDisplayed().
883 ** Answer whether the a particular line number or address is displayed
884 ** in the current source window.
887 tuiLineIsDisplayed (Opaque lineNoOrAddr, TuiWinInfoPtr winInfo,
890 int isDisplayed = FALSE;
894 threshold = SCROLL_THRESHOLD;
898 while (i < winInfo->generic.contentSize - threshold && !isDisplayed)
900 if (winInfo == srcWin)
901 isDisplayed = (((TuiWinElementPtr)
902 winInfo->generic.content[i])->whichElement.source.lineOrAddr.lineNo
903 == (int) lineNoOrAddr);
905 isDisplayed = (((TuiWinElementPtr)
906 winInfo->generic.content[i])->whichElement.source.lineOrAddr.addr
912 } /* tuiLineIsDisplayed */
915 /*****************************************
916 ** STATIC LOCAL FUNCTIONS **
917 ******************************************/