1 /* TUI display source 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 "tuiSourceWin.h"
54 #include "tuiSource.h"
57 /*****************************************
58 ** EXTERNAL DATA DECLS **
59 ******************************************/
60 extern int current_source_line
;
61 extern struct symtab
*current_source_symtab
;
64 /*****************************************
65 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
66 ******************************************/
68 static struct breakpoint
*_hasBreak (char *, int);
71 /*****************************************
72 ** STATIC LOCAL DATA **
73 ******************************************/
76 /*****************************************
77 ** PUBLIC FUNCTIONS **
78 ******************************************/
80 /*********************************
81 ** SOURCE/DISASSEM FUNCTIONS **
82 *********************************/
85 ** tuiSetSourceContent().
86 ** Function to display source in the source window.
89 tuiSetSourceContent (struct symtab
*s
, int lineNo
, int noerror
)
91 TuiStatus ret
= TUI_FAILURE
;
93 if (s
!= (struct symtab
*) NULL
&& s
->filename
!= (char *) NULL
)
95 register FILE *stream
;
96 register int i
, desc
, c
, lineWidth
, nlines
;
97 register char *srcLine
;
99 if ((ret
= tuiAllocSourceBuffer (srcWin
)) == TUI_SUCCESS
)
101 lineWidth
= srcWin
->generic
.width
- 1;
103 ** Take hilite (window border) into account, when calculating
104 ** the number of lines
106 nlines
= (lineNo
+ (srcWin
->generic
.height
- 2)) - lineNo
;
107 desc
= open_source_file (s
);
112 char *name
= alloca (strlen (s
->filename
) + 100);
113 sprintf (name
, "%s:%d", s
->filename
, lineNo
);
114 print_sys_errmsg (name
, errno
);
120 if (s
->line_charpos
== 0)
121 find_source_lines (s
, desc
);
123 if (lineNo
< 1 || lineNo
> s
->nlines
)
127 "Line number %d out of range; %s has %d lines.\n",
128 lineNo
, s
->filename
, s
->nlines
);
130 else if (lseek (desc
, s
->line_charpos
[lineNo
- 1], 0) < 0)
133 perror_with_name (s
->filename
);
137 register int offset
, curLineNo
, curLine
, curLen
, threshold
;
138 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
140 ** Determine the threshold for the length of the line
141 ** and the offset to start the display
143 offset
= srcWin
->detail
.sourceInfo
.horizontalOffset
;
144 threshold
= (lineWidth
- 1) + offset
;
145 stream
= fdopen (desc
, FOPEN_RT
);
149 srcWin
->detail
.sourceInfo
.startLineOrAddr
.lineNo
= lineNo
;
151 srcLine
= (char *) xmalloc (
152 (threshold
+ 1) * sizeof (char));
153 while (curLine
< nlines
)
155 TuiWinElementPtr element
= (TuiWinElementPtr
)
156 srcWin
->generic
.content
[curLine
];
157 struct breakpoint
*bp
;
159 /* get the first character in the line */
163 srcLine
= ((TuiWinElementPtr
)
164 srcWin
->generic
.content
[
165 curLine
])->whichElement
.source
.line
;
166 /* Init the line with the line number */
167 sprintf (srcLine
, "%-6d", curLineNo
);
168 curLen
= strlen (srcLine
);
170 ((curLen
/ tuiDefaultTabLen ()) * tuiDefaultTabLen ());
171 while (i
< tuiDefaultTabLen ())
173 srcLine
[curLen
] = ' ';
177 srcLine
[curLen
] = (char) 0;
180 ** Set whether element is the execution point and
181 ** whether there is a break point on it.
183 element
->whichElement
.source
.lineOrAddr
.lineNo
=
185 element
->whichElement
.source
.isExecPoint
=
186 (strcmp (((TuiWinElementPtr
)
187 locator
->content
[0])->whichElement
.locator
.fileName
,
189 && curLineNo
== ((TuiWinElementPtr
)
190 locator
->content
[0])->whichElement
.locator
.lineNo
);
191 bp
= _hasBreak (s
->filename
, curLineNo
);
192 element
->whichElement
.source
.hasBreak
=
193 (bp
!= (struct breakpoint
*) NULL
&&
194 (!element
->whichElement
.source
.isExecPoint
||
195 (bp
->disposition
!= disp_del
|| bp
->hit_count
<= 0)));
198 i
= strlen (srcLine
) - 1;
202 (c
!= '\r') && (++i
< threshold
))
204 if (c
< 040 && c
!= '\t')
207 srcLine
[i
] = c
+ 0100;
216 ** Store the charcter in the line
217 ** buffer. If it is a tab, then
218 ** translate to the correct number of
219 ** chars so we don't overwrite our
224 int j
, maxTabLen
= tuiDefaultTabLen ();
227 (i
/ maxTabLen
) * maxTabLen
);
241 ** if we have not reached EOL, then eat
244 while (c
!= EOF
&& c
!= '\n' && c
!= '\r')
248 while (c
!= EOF
&& c
!= '\n' && c
!= '\r' &&
249 i
< threshold
&& (c
= fgetc (stream
)));
251 /* Now copy the line taking the offset into account */
252 if (strlen (srcLine
) > offset
)
253 strcpy (((TuiWinElementPtr
) srcWin
->generic
.content
[
254 curLine
])->whichElement
.source
.line
,
258 srcWin
->generic
.content
[
259 curLine
])->whichElement
.source
.line
[0] = (char) 0;
266 srcWin
->generic
.contentSize
= nlines
;
273 } /* tuiSetSourceContent */
276 /* elz: this function sets the contents of the source window to empty
277 except for a line in the middle with a warning message about the
278 source not being available. This function is called by
279 tuiEraseSourceContents, which in turn is invoked when the source files
280 cannot be accessed */
283 tuiSetSourceContentNil (TuiWinInfoPtr winInfo
, char *warning_string
)
289 lineWidth
= winInfo
->generic
.width
- 1;
290 nLines
= winInfo
->generic
.height
- 2;
292 /* set to empty each line in the window, except for the one
293 which contains the message */
294 while (curr_line
< winInfo
->generic
.contentSize
)
296 /* set the information related to each displayed line
297 to null: i.e. the line number is 0, there is no bp,
298 it is not where the program is stopped */
300 TuiWinElementPtr element
=
301 (TuiWinElementPtr
) winInfo
->generic
.content
[curr_line
];
302 element
->whichElement
.source
.lineOrAddr
.lineNo
= 0;
303 element
->whichElement
.source
.isExecPoint
= FALSE
;
304 element
->whichElement
.source
.hasBreak
= FALSE
;
306 /* set the contents of the line to blank */
307 element
->whichElement
.source
.line
[0] = (char) 0;
309 /* if the current line is in the middle of the screen, then we want to
310 display the 'no source available' message in it.
311 Note: the 'weird' arithmetic with the line width and height comes from
312 the function tuiEraseSourceContent. We need to keep the screen and the
313 window's actual contents in synch */
315 if (curr_line
== (nLines
/ 2 + 1))
319 int warning_length
= strlen (warning_string
);
322 srcLine
= element
->whichElement
.source
.line
;
324 if (warning_length
>= ((lineWidth
- 1) / 2))
327 xpos
= (lineWidth
- 1) / 2 - warning_length
;
329 for (i
= 0; i
< xpos
; i
++)
332 sprintf (srcLine
+ i
, "%s", warning_string
);
334 for (i
= xpos
+ warning_length
; i
< lineWidth
; i
++)
345 } /*tuiSetSourceContentNil */
352 ** Function to display source in the source window. This function
353 ** initializes the horizontal scroll to 0.
356 tuiShowSource (struct symtab
*s
, TuiLineOrAddress line
, int noerror
)
358 srcWin
->detail
.sourceInfo
.horizontalOffset
= 0;
359 tuiUpdateSourceWindowAsIs(srcWin
, s
, line
, noerror
);
362 } /* tuiShowSource */
366 ** tuiSourceIsDisplayed().
367 ** Answer whether the source is currently displayed in the source window.
370 tuiSourceIsDisplayed (char *fname
)
372 return (srcWin
->generic
.contentInUse
&&
373 (strcmp (((TuiWinElementPtr
) (locatorWinInfoPtr ())->
374 content
[0])->whichElement
.locator
.fileName
, fname
) == 0));
375 } /* tuiSourceIsDisplayed */
379 ** tuiVerticalSourceScroll().
380 ** Scroll the source forward or backward vertically
383 tuiVerticalSourceScroll (TuiScrollDirection scrollDirection
,
386 if (srcWin
->generic
.content
!= (OpaquePtr
) NULL
)
390 TuiWinContent content
= (TuiWinContent
) srcWin
->generic
.content
;
392 if (current_source_symtab
== (struct symtab
*) NULL
)
393 s
= find_pc_symtab (selected_frame
->pc
);
395 s
= current_source_symtab
;
397 if (scrollDirection
== FORWARD_SCROLL
)
399 l
.lineNo
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
+
401 if (l
.lineNo
> s
->nlines
)
402 /*line = s->nlines - winInfo->generic.contentSize + 1; */
403 /*elz: fix for dts 23398 */
404 l
.lineNo
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
;
408 l
.lineNo
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
-
413 if (identify_source_line (s
, l
.lineNo
, 0, -1) == 1)
414 tuiUpdateSourceWindowAsIs (srcWin
, s
, l
, FALSE
);
418 } /* tuiVerticalSourceScroll */
421 /*****************************************
422 ** STATIC LOCAL FUNCTIONS **
423 ******************************************/
427 ** Answer whether there is a break point at the input line in
428 ** the source file indicated
430 static struct breakpoint
*
431 _hasBreak (char *sourceFileName
, int lineNo
)
433 struct breakpoint
*bpWithBreak
= (struct breakpoint
*) NULL
;
434 struct breakpoint
*bp
;
435 extern struct breakpoint
*breakpoint_chain
;
438 for (bp
= breakpoint_chain
;
439 (bp
!= (struct breakpoint
*) NULL
&&
440 bpWithBreak
== (struct breakpoint
*) NULL
);
443 && (strcmp (sourceFileName
, bp
->source_file
) == 0)
444 && (lineNo
== bp
->line_number
))