3 ** This module contains functions for displaying source in the source window
10 #include "breakpoint.h"
15 #include "tuiSourceWin.h"
16 #include "tuiSource.h"
19 /*****************************************
20 ** EXTERNAL FUNCTION DECLS **
21 ******************************************/
23 extern int open_source_file
PARAMS ((struct symtab
*));
24 extern void find_source_lines
PARAMS ((struct symtab
*, int));
26 /*****************************************
27 ** EXTERNAL DATA DECLS **
28 ******************************************/
29 extern int current_source_line
;
30 extern struct symtab
*current_source_symtab
;
33 /*****************************************
34 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
35 ******************************************/
37 static struct breakpoint
*_hasBreak
PARAMS ((char *, int));
40 /*****************************************
41 ** STATIC LOCAL DATA **
42 ******************************************/
45 /*****************************************
46 ** PUBLIC FUNCTIONS **
47 ******************************************/
49 /*********************************
50 ** SOURCE/DISASSEM FUNCTIONS **
51 *********************************/
54 ** tuiSetSourceContent().
55 ** Function to display source in the source window.
64 tuiSetSourceContent (s
, lineNo
, noerror
)
70 TuiStatus ret
= TUI_FAILURE
;
72 if (s
!= (struct symtab
*) NULL
&& s
->filename
!= (char *) NULL
)
74 register FILE *stream
;
75 register int i
, desc
, c
, lineWidth
, nlines
;
76 register char *srcLine
;
78 if ((ret
= tuiAllocSourceBuffer (srcWin
)) == TUI_SUCCESS
)
80 lineWidth
= srcWin
->generic
.width
- 1;
82 ** Take hilite (window border) into account, when calculating
83 ** the number of lines
85 nlines
= (lineNo
+ (srcWin
->generic
.height
- 2)) - lineNo
;
86 desc
= open_source_file (s
);
91 char *name
= alloca (strlen (s
->filename
) + 100);
92 sprintf (name
, "%s:%d", s
->filename
, lineNo
);
93 print_sys_errmsg (name
, errno
);
99 if (s
->line_charpos
== 0)
100 find_source_lines (s
, desc
);
102 if (lineNo
< 1 || lineNo
> s
->nlines
)
106 "Line number %d out of range; %s has %d lines.\n",
107 lineNo
, s
->filename
, s
->nlines
);
109 else if (lseek (desc
, s
->line_charpos
[lineNo
- 1], 0) < 0)
112 perror_with_name (s
->filename
);
116 register int offset
, curLineNo
, curLine
, curLen
, threshold
;
117 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
119 ** Determine the threshold for the length of the line
120 ** and the offset to start the display
122 offset
= srcWin
->detail
.sourceInfo
.horizontalOffset
;
123 threshold
= (lineWidth
- 1) + offset
;
124 stream
= fdopen (desc
, FOPEN_RT
);
128 srcWin
->detail
.sourceInfo
.startLineOrAddr
.lineNo
= lineNo
;
130 srcLine
= (char *) xmalloc (
131 (threshold
+ 1) * sizeof (char));
132 while (curLine
< nlines
)
134 TuiWinElementPtr element
= (TuiWinElementPtr
)
135 srcWin
->generic
.content
[curLine
];
136 struct breakpoint
*bp
;
138 /* get the first character in the line */
142 srcLine
= ((TuiWinElementPtr
)
143 srcWin
->generic
.content
[
144 curLine
])->whichElement
.source
.line
;
145 /* Init the line with the line number */
146 sprintf (srcLine
, "%-6d", curLineNo
);
147 curLen
= strlen (srcLine
);
149 ((curLen
/ tuiDefaultTabLen ()) * tuiDefaultTabLen ());
150 while (i
< tuiDefaultTabLen ())
152 srcLine
[curLen
] = ' ';
156 srcLine
[curLen
] = (char) 0;
159 ** Set whether element is the execution point and
160 ** whether there is a break point on it.
162 element
->whichElement
.source
.lineOrAddr
.lineNo
=
164 element
->whichElement
.source
.isExecPoint
=
165 (strcmp (((TuiWinElementPtr
)
166 locator
->content
[0])->whichElement
.locator
.fileName
,
168 && curLineNo
== ((TuiWinElementPtr
)
169 locator
->content
[0])->whichElement
.locator
.lineNo
);
170 bp
= _hasBreak (s
->filename
, curLineNo
);
171 element
->whichElement
.source
.hasBreak
=
172 (bp
!= (struct breakpoint
*) NULL
&&
173 (!element
->whichElement
.source
.isExecPoint
||
174 (bp
->disposition
!= del
|| bp
->hit_count
<= 0)));
177 i
= strlen (srcLine
) - 1;
181 (c
!= '\r') && (++i
< threshold
))
183 if (c
< 040 && c
!= '\t')
186 srcLine
[i
] = c
+ 0100;
195 ** Store the charcter in the line
196 ** buffer. If it is a tab, then
197 ** translate to the correct number of
198 ** chars so we don't overwrite our
203 int j
, maxTabLen
= tuiDefaultTabLen ();
206 (i
/ maxTabLen
) * maxTabLen
);
220 ** if we have not reached EOL, then eat
223 while (c
!= EOF
&& c
!= '\n' && c
!= '\r')
227 while (c
!= EOF
&& c
!= '\n' && c
!= '\r' &&
228 i
< threshold
&& (c
= fgetc (stream
)));
230 /* Now copy the line taking the offset into account */
231 if (strlen (srcLine
) > offset
)
232 strcpy (((TuiWinElementPtr
) srcWin
->generic
.content
[
233 curLine
])->whichElement
.source
.line
,
237 srcWin
->generic
.content
[
238 curLine
])->whichElement
.source
.line
[0] = (char) 0;
245 srcWin
->generic
.contentSize
= nlines
;
252 } /* tuiSetSourceContent */
255 /* elz: this function sets the contents of the source window to empty
256 except for a line in the middle with a warning message about the
257 source not being available. This function is called by
258 tuiEraseSourceContents, which in turn is invoked when the source files
263 tuiSetSourceContentNil (
264 TuiWinInfoPtr winInfo
,
265 char *warning_string
)
267 tuiSetSourceContentNil (winInfo
, warning_string
)
268 TuiWinInfoPtr winInfo
;
269 char *warning_string
;
276 lineWidth
= winInfo
->generic
.width
- 1;
277 nLines
= winInfo
->generic
.height
- 2;
279 /* set to empty each line in the window, except for the one
280 which contains the message*/
281 while (curr_line
< winInfo
->generic
.contentSize
)
283 /* set the information related to each displayed line
284 to null: i.e. the line number is 0, there is no bp,
285 it is not where the program is stopped */
287 TuiWinElementPtr element
=
288 (TuiWinElementPtr
) winInfo
->generic
.content
[curr_line
];
289 element
->whichElement
.source
.lineOrAddr
.lineNo
= 0;
290 element
->whichElement
.source
.isExecPoint
= FALSE
;
291 element
->whichElement
.source
.hasBreak
= FALSE
;
293 /* set the contents of the line to blank*/
294 element
->whichElement
.source
.line
[0] = (char) 0;
296 /* if the current line is in the middle of the screen, then we want to
297 display the 'no source available' message in it.
298 Note: the 'weird' arithmetic with the line width and height comes from
299 the function tuiEraseSourceContent. We need to keep the screen and the
300 window's actual contents in synch */
302 if (curr_line
== (nLines
/ 2 + 1))
306 int warning_length
= strlen (warning_string
);
309 srcLine
= element
->whichElement
.source
.line
;
311 if (warning_length
>= ((lineWidth
- 1) / 2))
314 xpos
= (lineWidth
- 1) / 2 - warning_length
;
316 for (i
= 0; i
< xpos
; i
++)
319 sprintf (srcLine
+ i
, "%s", warning_string
);
321 for (i
= xpos
+ warning_length
; i
< lineWidth
; i
++)
332 } /*tuiSetSourceContentNil*/
339 ** Function to display source in the source window. This function
340 ** initializes the horizontal scroll to 0.
349 tuiShowSource (s
, line
, noerror
)
355 srcWin
->detail
.sourceInfo
.horizontalOffset
= 0;
356 m_tuiShowSourceAsIs (s
, line
, noerror
);
359 } /* tuiShowSource */
363 ** tuiSourceIsDisplayed().
364 ** Answer whether the source is currently displayed in the source window.
368 tuiSourceIsDisplayed (
371 tuiSourceIsDisplayed (fname
)
375 return (srcWin
->generic
.contentInUse
&&
376 (strcmp (((TuiWinElementPtr
) (locatorWinInfoPtr ())->
377 content
[0])->whichElement
.locator
.fileName
, fname
) == 0));
378 } /* tuiSourceIsDisplayed */
382 ** tuiVerticalSourceScroll().
383 ** Scroll the source forward or backward vertically
387 tuiVerticalSourceScroll (
388 TuiScrollDirection scrollDirection
,
391 tuiVerticalSourceScroll (scrollDirection
, numToScroll
)
392 TuiScrollDirection scrollDirection
;
396 if (srcWin
->generic
.content
!= (OpaquePtr
) NULL
)
401 TuiWinContent content
= (TuiWinContent
) srcWin
->generic
.content
;
403 if (current_source_symtab
== (struct symtab
*) NULL
)
404 s
= find_pc_symtab (selected_frame
->pc
);
406 s
= current_source_symtab
;
408 if (scrollDirection
== FORWARD_SCROLL
)
410 line
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
+
412 if (line
> s
->nlines
)
413 /*line = s->nlines - winInfo->generic.contentSize + 1;*/
414 /*elz: fix for dts 23398*/
415 line
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
;
419 line
= content
[0]->whichElement
.source
.lineOrAddr
.lineNo
-
424 tuiUpdateSourceWindowAsIs (srcWin
, s
, (Opaque
) line
, FALSE
);
428 } /* tuiVerticalSourceScroll */
431 /*****************************************
432 ** STATIC LOCAL FUNCTIONS **
433 ******************************************/
437 ** Answer whether there is a break point at the input line in
438 ** the source file indicated
440 static struct breakpoint
*
443 char *sourceFileName
,
446 _hasBreak (sourceFileName
, lineNo
)
447 char *sourceFileName
;
451 struct breakpoint
*bpWithBreak
= (struct breakpoint
*) NULL
;
452 struct breakpoint
*bp
;
453 extern struct breakpoint
*breakpoint_chain
;
456 for (bp
= breakpoint_chain
;
457 (bp
!= (struct breakpoint
*) NULL
&&
458 bpWithBreak
== (struct breakpoint
*) NULL
);
460 if ((strcmp (sourceFileName
, bp
->source_file
) == 0) &&
461 (lineNo
== bp
->line_number
))