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))