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 ** tuiDisplayMainFunction().
71 ** Function to display the "main" routine"
74 tuiDisplayMainFunction (void)
76 if ((sourceWindows ())->count
> 0)
80 addr
= parse_and_eval_address ("main");
81 if (addr
== (CORE_ADDR
) 0)
82 addr
= parse_and_eval_address ("MAIN");
83 if (addr
!= (CORE_ADDR
) 0)
85 struct symtab_and_line sal
;
87 tuiUpdateSourceWindowsWithAddr (addr
);
88 sal
= find_pc_line (addr
, 0);
90 tuiUpdateLocatorFilename (sal
.symtab
->filename
);
92 tuiUpdateLocatorFilename ("??");
100 ** tuiUpdateSourceWindow().
101 ** Function to display source in the source window. This function
102 ** initializes the horizontal scroll to 0.
105 tuiUpdateSourceWindow (TuiWinInfoPtr winInfo
, struct symtab
*s
,
106 TuiLineOrAddress lineOrAddr
, int noerror
)
108 winInfo
->detail
.sourceInfo
.horizontalOffset
= 0;
109 tuiUpdateSourceWindowAsIs (winInfo
, s
, lineOrAddr
, noerror
);
112 } /* tuiUpdateSourceWindow */
116 ** tuiUpdateSourceWindowAsIs().
117 ** Function to display source in the source/asm window. This
118 ** function shows the source as specified by the horizontal offset.
121 tuiUpdateSourceWindowAsIs (TuiWinInfoPtr winInfo
, struct symtab
*s
,
122 TuiLineOrAddress lineOrAddr
, int noerror
)
126 if (winInfo
->generic
.type
== SRC_WIN
)
127 ret
= tuiSetSourceContent (s
, lineOrAddr
.lineNo
, noerror
);
129 ret
= tuiSetDisassemContent (s
, lineOrAddr
.addr
);
131 if (ret
== TUI_FAILURE
)
133 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
134 tuiClearExecInfoContent (winInfo
);
138 tuiEraseSourceContent (winInfo
, NO_EMPTY_SOURCE_PROMPT
);
139 tuiShowSourceContent (winInfo
);
140 tuiUpdateExecInfo (winInfo
);
141 if (winInfo
->generic
.type
== SRC_WIN
)
143 current_source_line
= lineOrAddr
.lineNo
+
144 (winInfo
->generic
.contentSize
- 2);
145 current_source_symtab
= s
;
147 ** If the focus was in the asm win, put it in the src
148 ** win if we don't have a split layout
150 if (tuiWinWithFocus () == disassemWin
&&
151 currentLayout () != SRC_DISASSEM_COMMAND
)
152 tuiSetWinFocusTo (srcWin
);
158 } /* tuiUpdateSourceWindowAsIs */
162 ** tuiUpdateSourceWindowsWithAddr().
163 ** Function to ensure that the source and/or disassemly windows
164 ** reflect the input address.
167 tuiUpdateSourceWindowsWithAddr (CORE_ADDR addr
)
171 struct symtab_and_line sal
;
174 switch (currentLayout ())
176 case DISASSEM_COMMAND
:
177 case DISASSEM_DATA_COMMAND
:
178 tuiShowDisassem (addr
);
180 case SRC_DISASSEM_COMMAND
:
181 tuiShowDisassemAndUpdateSource (addr
);
184 sal
= find_pc_line (addr
, 0);
186 tuiShowSource (sal
.symtab
, l
, FALSE
);
194 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
196 TuiWinInfoPtr winInfo
= (TuiWinInfoPtr
) (sourceWindows ())->list
[i
];
198 tuiClearSourceContent (winInfo
, EMPTY_SOURCE_PROMPT
);
199 tuiClearExecInfoContent (winInfo
);
204 } /* tuiUpdateSourceWindowsWithAddr */
207 ** tuiUpdateSourceWindowsWithLine().
208 ** Function to ensure that the source and/or disassemly windows
209 ** reflect the input address.
212 tuiUpdateSourceWindowsWithLine (struct symtab
*s
, int line
)
217 switch (currentLayout ())
219 case DISASSEM_COMMAND
:
220 case DISASSEM_DATA_COMMAND
:
221 find_line_pc (s
, line
, &pc
);
222 tuiUpdateSourceWindowsWithAddr (pc
);
226 tuiShowSource (s
, l
, FALSE
);
227 if (currentLayout () == SRC_DISASSEM_COMMAND
)
229 find_line_pc (s
, line
, &pc
);
230 tuiShowDisassem (pc
);
236 } /* tuiUpdateSourceWindowsWithLine */
239 ** tuiClearSourceContent().
242 tuiClearSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
244 if (m_winPtrNotNull (winInfo
))
248 winInfo
->generic
.contentInUse
= FALSE
;
249 tuiEraseSourceContent (winInfo
, displayPrompt
);
250 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
252 TuiWinElementPtr element
=
253 (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
254 element
->whichElement
.source
.hasBreak
= FALSE
;
255 element
->whichElement
.source
.isExecPoint
= FALSE
;
260 } /* tuiClearSourceContent */
264 ** tuiEraseSourceContent().
267 tuiEraseSourceContent (TuiWinInfoPtr winInfo
, int displayPrompt
)
270 int halfWidth
= (winInfo
->generic
.width
- 2) / 2;
272 if (winInfo
->generic
.handle
!= (WINDOW
*) NULL
)
274 werase (winInfo
->generic
.handle
);
275 checkAndDisplayHighlightIfNeeded (winInfo
);
276 if (displayPrompt
== EMPTY_SOURCE_PROMPT
)
280 if (winInfo
->generic
.type
== SRC_WIN
)
281 noSrcStr
= NO_SRC_STRING
;
283 noSrcStr
= NO_DISASSEM_STRING
;
284 if (strlen (noSrcStr
) >= halfWidth
)
287 xPos
= halfWidth
- strlen (noSrcStr
);
288 mvwaddstr (winInfo
->generic
.handle
,
289 (winInfo
->generic
.height
/ 2),
293 /* elz: added this function call to set the real contents of
294 the window to what is on the screen, so that later calls
295 to refresh, do display
296 the correct stuff, and not the old image */
298 tuiSetSourceContentNil (winInfo
, noSrcStr
);
300 tuiRefreshWin (&winInfo
->generic
);
303 } /* tuiEraseSourceContent */
306 /* Redraw the complete line of a source or disassembly window. */
308 tui_show_source_line (TuiWinInfoPtr winInfo
, int lineno
)
310 TuiWinElementPtr line
;
313 line
= (TuiWinElementPtr
) winInfo
->generic
.content
[lineno
- 1];
314 if (line
->whichElement
.source
.isExecPoint
)
315 wattron (winInfo
->generic
.handle
, A_STANDOUT
);
317 mvwaddstr (winInfo
->generic
.handle
, lineno
, 1,
318 line
->whichElement
.source
.line
);
319 if (line
->whichElement
.source
.isExecPoint
)
320 wattroff (winInfo
->generic
.handle
, A_STANDOUT
);
322 /* Clear to end of line but stop before the border. */
323 getyx (winInfo
->generic
.handle
, y
, x
);
324 while (x
+ 1 < winInfo
->generic
.width
)
326 waddch (winInfo
->generic
.handle
, ' ');
327 getyx (winInfo
->generic
.handle
, y
, x
);
332 ** tuiShowSourceContent().
335 tuiShowSourceContent (TuiWinInfoPtr winInfo
)
337 if (winInfo
->generic
.contentSize
> 0)
341 for (lineno
= 1; lineno
<= winInfo
->generic
.contentSize
; lineno
++)
342 tui_show_source_line (winInfo
, lineno
);
345 tuiEraseSourceContent (winInfo
, TRUE
);
347 checkAndDisplayHighlightIfNeeded (winInfo
);
348 tuiRefreshWin (&winInfo
->generic
);
349 winInfo
->generic
.contentInUse
= TRUE
;
354 ** tuiHorizontalSourceScroll().
355 ** Scroll the source forward or backward horizontally
358 tuiHorizontalSourceScroll (TuiWinInfoPtr winInfo
,
359 TuiScrollDirection direction
,
362 if (winInfo
->generic
.content
!= (OpaquePtr
) NULL
)
367 if (current_source_symtab
== (struct symtab
*) NULL
)
368 s
= find_pc_symtab (selected_frame
->pc
);
370 s
= current_source_symtab
;
372 if (direction
== LEFT_SCROLL
)
373 offset
= winInfo
->detail
.sourceInfo
.horizontalOffset
+ numToScroll
;
377 winInfo
->detail
.sourceInfo
.horizontalOffset
- numToScroll
) < 0)
380 winInfo
->detail
.sourceInfo
.horizontalOffset
= offset
;
381 tuiUpdateSourceWindowAsIs (
385 winInfo
->generic
.content
[0])->whichElement
.source
.lineOrAddr
,
390 } /* tuiHorizontalSourceScroll */
394 ** tuiSetHasExecPointAt().
395 ** Set or clear the hasBreak flag in the line whose line is lineNo.
398 tuiSetIsExecPointAt (TuiLineOrAddress l
, TuiWinInfoPtr winInfo
)
401 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
404 while (i
< winInfo
->generic
.contentSize
)
406 if (content
[i
]->whichElement
.source
.lineOrAddr
.addr
== l
.addr
)
407 content
[i
]->whichElement
.source
.isExecPoint
= TRUE
;
409 content
[i
]->whichElement
.source
.isExecPoint
= FALSE
;
414 } /* tuiSetIsExecPointAt */
417 ** tuiSetHasBreakAt().
418 ** Set or clear the hasBreak flag in the line whose line is lineNo.
421 tuiSetHasBreakAt (struct breakpoint
*bp
, TuiWinInfoPtr winInfo
, int hasBreak
)
424 TuiWinContent content
= (TuiWinContent
) winInfo
->generic
.content
;
427 while (i
< winInfo
->generic
.contentSize
)
430 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
432 if (winInfo
== srcWin
)
434 TuiSourceInfoPtr src
= &winInfo
->detail
.sourceInfo
;
436 gotIt
= (src
->filename
!= (char *) NULL
&&
437 bp
->source_file
!= NULL
&&
438 (strcmp (bp
->source_file
, src
->filename
) == 0) &&
439 content
[i
]->whichElement
.source
.lineOrAddr
.lineNo
==
443 gotIt
= (content
[i
]->whichElement
.source
.lineOrAddr
.addr
447 content
[i
]->whichElement
.source
.hasBreak
= hasBreak
;
454 } /* tuiSetHasBreakAt */
458 ** tuiAllSetHasBreakAt().
459 ** Set or clear the hasBreak flag in all displayed source windows.
462 tuiAllSetHasBreakAt (struct breakpoint
*bp
, int hasBreak
)
466 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
467 tuiSetHasBreakAt (bp
,
468 (TuiWinInfoPtr
) (sourceWindows ())->list
[i
], hasBreak
);
471 } /* tuiAllSetHasBreakAt */
474 /*********************************
475 ** EXECUTION INFO FUNCTIONS **
476 *********************************/
479 ** tuiSetExecInfoContent().
480 ** Function to initialize the content of the execution info window,
481 ** based upon the input window which is either the source or
482 ** disassembly window.
485 tuiSetExecInfoContent (TuiWinInfoPtr winInfo
)
487 TuiStatus ret
= TUI_SUCCESS
;
489 if (winInfo
->detail
.sourceInfo
.executionInfo
!= (TuiGenWinInfoPtr
) NULL
)
491 TuiGenWinInfoPtr execInfoPtr
= winInfo
->detail
.sourceInfo
.executionInfo
;
493 if (execInfoPtr
->content
== (OpaquePtr
) NULL
)
494 execInfoPtr
->content
=
495 (OpaquePtr
) allocContent (winInfo
->generic
.height
,
497 if (execInfoPtr
->content
!= (OpaquePtr
) NULL
)
501 for (i
= 0; i
< winInfo
->generic
.contentSize
; i
++)
503 TuiWinElementPtr element
;
504 TuiWinElementPtr srcElement
;
506 element
= (TuiWinElementPtr
) execInfoPtr
->content
[i
];
507 srcElement
= (TuiWinElementPtr
) winInfo
->generic
.content
[i
];
509 ** First check to see if we have a breakpoint that is
510 ** temporary. If so, and this is our current execution point,
511 ** then clear the break indicator.
513 if (srcElement
->whichElement
.source
.hasBreak
&&
514 srcElement
->whichElement
.source
.isExecPoint
)
516 struct breakpoint
*bp
;
518 extern struct breakpoint
*breakpoint_chain
;
520 for (bp
= breakpoint_chain
;
521 (bp
!= (struct breakpoint
*) NULL
&& !found
);
525 (winInfo
== srcWin
&&
527 srcElement
->whichElement
.source
.lineOrAddr
.lineNo
) ||
528 (winInfo
== disassemWin
&&
529 bp
->address
== (CORE_ADDR
)
530 srcElement
->whichElement
.source
.lineOrAddr
.addr
);
532 srcElement
->whichElement
.source
.hasBreak
=
533 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0);
536 srcElement
->whichElement
.source
.hasBreak
= FALSE
;
539 ** Now update the exec info content based upon the state
540 ** of each line as indicated by the source content.
542 if (srcElement
->whichElement
.source
.hasBreak
&&
543 srcElement
->whichElement
.source
.isExecPoint
)
544 element
->whichElement
.simpleString
= breakLocationStr ();
545 else if (srcElement
->whichElement
.source
.hasBreak
)
546 element
->whichElement
.simpleString
= breakStr ();
547 else if (srcElement
->whichElement
.source
.isExecPoint
)
548 element
->whichElement
.simpleString
= locationStr ();
550 element
->whichElement
.simpleString
= blankStr ();
552 execInfoPtr
->contentSize
= winInfo
->generic
.contentSize
;
559 } /* tuiSetExecInfoContent */
563 ** tuiShowExecInfoContent().
566 tuiShowExecInfoContent (TuiWinInfoPtr winInfo
)
568 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
571 werase (execInfo
->handle
);
572 tuiRefreshWin (execInfo
);
573 for (curLine
= 1; (curLine
<= execInfo
->contentSize
); curLine
++)
574 mvwaddstr (execInfo
->handle
,
578 execInfo
->content
[curLine
- 1])->whichElement
.simpleString
);
579 tuiRefreshWin (execInfo
);
580 execInfo
->contentInUse
= TRUE
;
583 } /* tuiShowExecInfoContent */
587 ** tuiEraseExecInfoContent().
590 tuiEraseExecInfoContent (TuiWinInfoPtr winInfo
)
592 TuiGenWinInfoPtr execInfo
= winInfo
->detail
.sourceInfo
.executionInfo
;
594 werase (execInfo
->handle
);
595 tuiRefreshWin (execInfo
);
598 } /* tuiEraseExecInfoContent */
601 ** tuiClearExecInfoContent().
604 tuiClearExecInfoContent (TuiWinInfoPtr winInfo
)
606 winInfo
->detail
.sourceInfo
.executionInfo
->contentInUse
= FALSE
;
607 tuiEraseExecInfoContent (winInfo
);
610 } /* tuiClearExecInfoContent */
613 ** tuiUpdateExecInfo().
614 ** Function to update the execution info window
617 tuiUpdateExecInfo (TuiWinInfoPtr winInfo
)
619 tuiSetExecInfoContent (winInfo
);
620 tuiShowExecInfoContent (winInfo
);
621 } /* tuiUpdateExecInfo */
625 ** tuiUpdateAllExecInfos()
628 tuiUpdateAllExecInfos (void)
632 for (i
= 0; i
< (sourceWindows ())->count
; i
++)
633 tuiUpdateExecInfo ((TuiWinInfoPtr
) (sourceWindows ())->list
[i
]);
636 } /* tuiUpdateAllExecInfos */
639 tuiAllocSourceBuffer (TuiWinInfoPtr winInfo
)
641 register char *srcLineBuf
;
642 register int i
, lineWidth
, maxLines
;
643 TuiStatus ret
= TUI_FAILURE
;
645 maxLines
= winInfo
->generic
.height
; /* less the highlight box */
646 lineWidth
= winInfo
->generic
.width
- 1;
648 ** Allocate the buffer for the source lines. Do this only once since they
649 ** will be re-used for all source displays. The only other time this will
650 ** be done is when a window's size changes.
652 if (winInfo
->generic
.content
== (OpaquePtr
) NULL
)
654 srcLineBuf
= (char *) xmalloc ((maxLines
* lineWidth
) * sizeof (char));
655 if (srcLineBuf
== (char *) NULL
)
657 "Unable to Allocate Memory for Source or Disassembly Display.\n",
661 /* allocate the content list */
662 if ((winInfo
->generic
.content
=
663 (OpaquePtr
) allocContent (maxLines
, SRC_WIN
)) == (OpaquePtr
) NULL
)
665 tuiFree (srcLineBuf
);
666 srcLineBuf
= (char *) NULL
;
668 "Unable to Allocate Memory for Source or Disassembly Display.\n",
672 for (i
= 0; i
< maxLines
; i
++)
674 winInfo
->generic
.content
[i
])->whichElement
.source
.line
=
675 srcLineBuf
+ (lineWidth
* i
);
682 } /* tuiAllocSourceBuffer */
686 ** tuiLineIsDisplayed().
687 ** Answer whether the a particular line number or address is displayed
688 ** in the current source window.
691 tuiLineIsDisplayed (int line
, TuiWinInfoPtr winInfo
,
694 int isDisplayed
= FALSE
;
698 threshold
= SCROLL_THRESHOLD
;
702 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
704 isDisplayed
= (((TuiWinElementPtr
)
705 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.lineNo
711 } /* tuiLineIsDisplayed */
715 ** tuiLineIsDisplayed().
716 ** Answer whether the a particular line number or address is displayed
717 ** in the current source window.
720 tuiAddrIsDisplayed (CORE_ADDR addr
, TuiWinInfoPtr winInfo
,
723 int isDisplayed
= FALSE
;
727 threshold
= SCROLL_THRESHOLD
;
731 while (i
< winInfo
->generic
.contentSize
- threshold
&& !isDisplayed
)
733 isDisplayed
= (((TuiWinElementPtr
)
734 winInfo
->generic
.content
[i
])->whichElement
.source
.lineOrAddr
.addr
743 /*****************************************
744 ** STATIC LOCAL FUNCTIONS **
745 ******************************************/