import gdb-1999-09-21
[deliverable/binutils-gdb.git] / gdb / tui / tuiSource.c
CommitLineData
c906108c 1/*
c5aa993b
JM
2 ** tuiSource.c
3 ** This module contains functions for displaying source in the source window
4 */
c906108c
SS
5
6#include "defs.h"
7#include <ctype.h>
8#include "symtab.h"
9#include "frame.h"
10#include "breakpoint.h"
c2c6d25f 11#include "source.h"
c906108c
SS
12
13#include "tui.h"
14#include "tuiData.h"
15#include "tuiStack.h"
16#include "tuiSourceWin.h"
17#include "tuiSource.h"
18
19
c906108c
SS
20/*****************************************
21** EXTERNAL DATA DECLS **
22******************************************/
23extern int current_source_line;
24extern struct symtab *current_source_symtab;
25
26
27/*****************************************
28** STATIC LOCAL FUNCTIONS FORWARD DECLS **
29******************************************/
30
31static struct breakpoint *_hasBreak PARAMS ((char *, int));
32
33
34/*****************************************
35** STATIC LOCAL DATA **
36******************************************/
37
38
39/*****************************************
40** PUBLIC FUNCTIONS **
41******************************************/
42
43/*********************************
44** SOURCE/DISASSEM FUNCTIONS **
45*********************************/
46
47/*
c5aa993b
JM
48 ** tuiSetSourceContent().
49 ** Function to display source in the source window.
50 */
c906108c
SS
51TuiStatus
52#ifdef __STDC__
53tuiSetSourceContent (
54 struct symtab *s,
55 int lineNo,
56 int noerror)
57#else
58tuiSetSourceContent (s, lineNo, noerror)
59 struct symtab *s;
60 int lineNo;
61 int noerror;
62#endif
63{
64 TuiStatus ret = TUI_FAILURE;
65
66 if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
67 {
68 register FILE *stream;
69 register int i, desc, c, lineWidth, nlines;
70 register char *srcLine;
71
72 if ((ret = tuiAllocSourceBuffer (srcWin)) == TUI_SUCCESS)
73 {
74 lineWidth = srcWin->generic.width - 1;
75 /*
c5aa993b
JM
76 ** Take hilite (window border) into account, when calculating
77 ** the number of lines
78 */
c906108c
SS
79 nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo;
80 desc = open_source_file (s);
81 if (desc < 0)
82 {
83 if (!noerror)
84 {
85 char *name = alloca (strlen (s->filename) + 100);
86 sprintf (name, "%s:%d", s->filename, lineNo);
87 print_sys_errmsg (name, errno);
88 }
89 ret = TUI_FAILURE;
90 }
91 else
92 {
93 if (s->line_charpos == 0)
94 find_source_lines (s, desc);
95
96 if (lineNo < 1 || lineNo > s->nlines)
97 {
98 close (desc);
99 printf_unfiltered (
100 "Line number %d out of range; %s has %d lines.\n",
101 lineNo, s->filename, s->nlines);
102 }
103 else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0)
104 {
105 close (desc);
106 perror_with_name (s->filename);
107 }
108 else
109 {
110 register int offset, curLineNo, curLine, curLen, threshold;
111 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
112 /*
c5aa993b
JM
113 ** Determine the threshold for the length of the line
114 ** and the offset to start the display
115 */
c906108c
SS
116 offset = srcWin->detail.sourceInfo.horizontalOffset;
117 threshold = (lineWidth - 1) + offset;
118 stream = fdopen (desc, FOPEN_RT);
119 clearerr (stream);
120 curLine = 0;
121 curLineNo =
122 srcWin->detail.sourceInfo.startLineOrAddr.lineNo = lineNo;
123 if (offset > 0)
124 srcLine = (char *) xmalloc (
125 (threshold + 1) * sizeof (char));
126 while (curLine < nlines)
127 {
128 TuiWinElementPtr element = (TuiWinElementPtr)
129 srcWin->generic.content[curLine];
130 struct breakpoint *bp;
131
132 /* get the first character in the line */
133 c = fgetc (stream);
134
135 if (offset == 0)
136 srcLine = ((TuiWinElementPtr)
137 srcWin->generic.content[
138 curLine])->whichElement.source.line;
139 /* Init the line with the line number */
140 sprintf (srcLine, "%-6d", curLineNo);
141 curLen = strlen (srcLine);
142 i = curLen -
143 ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ());
144 while (i < tuiDefaultTabLen ())
145 {
146 srcLine[curLen] = ' ';
147 i++;
148 curLen++;
149 }
150 srcLine[curLen] = (char) 0;
151
152 /*
c5aa993b
JM
153 ** Set whether element is the execution point and
154 ** whether there is a break point on it.
155 */
c906108c
SS
156 element->whichElement.source.lineOrAddr.lineNo =
157 curLineNo;
158 element->whichElement.source.isExecPoint =
159 (strcmp (((TuiWinElementPtr)
160 locator->content[0])->whichElement.locator.fileName,
161 s->filename) == 0
162 && curLineNo == ((TuiWinElementPtr)
163 locator->content[0])->whichElement.locator.lineNo);
164 bp = _hasBreak (s->filename, curLineNo);
165 element->whichElement.source.hasBreak =
166 (bp != (struct breakpoint *) NULL &&
167 (!element->whichElement.source.isExecPoint ||
168 (bp->disposition != del || bp->hit_count <= 0)));
169 if (c != EOF)
170 {
171 i = strlen (srcLine) - 1;
172 do
173 {
174 if ((c != '\n') &&
175 (c != '\r') && (++i < threshold))
176 {
177 if (c < 040 && c != '\t')
178 {
179 srcLine[i++] = '^';
180 srcLine[i] = c + 0100;
181 }
182 else if (c == 0177)
183 {
184 srcLine[i++] = '^';
185 srcLine[i] = '?';
186 }
187 else
188 { /*
c5aa993b
JM
189 ** Store the charcter in the line
190 ** buffer. If it is a tab, then
191 ** translate to the correct number of
192 ** chars so we don't overwrite our
193 ** buffer.
194 */
c906108c
SS
195 if (c == '\t')
196 {
197 int j, maxTabLen = tuiDefaultTabLen ();
198
199 for (j = i - (
200 (i / maxTabLen) * maxTabLen);
201 ((j < maxTabLen) &&
202 i < threshold);
203 i++, j++)
204 srcLine[i] = ' ';
205 i--;
206 }
207 else
208 srcLine[i] = c;
209 }
210 srcLine[i + 1] = 0;
211 }
212 else
213 { /*
c5aa993b
JM
214 ** if we have not reached EOL, then eat
215 ** chars until we do
216 */
c906108c
SS
217 while (c != EOF && c != '\n' && c != '\r')
218 c = fgetc (stream);
219 }
220 }
221 while (c != EOF && c != '\n' && c != '\r' &&
222 i < threshold && (c = fgetc (stream)));
223 }
224 /* Now copy the line taking the offset into account */
225 if (strlen (srcLine) > offset)
226 strcpy (((TuiWinElementPtr) srcWin->generic.content[
227 curLine])->whichElement.source.line,
228 &srcLine[offset]);
229 else
230 ((TuiWinElementPtr)
231 srcWin->generic.content[
232 curLine])->whichElement.source.line[0] = (char) 0;
233 curLine++;
234 curLineNo++;
235 }
236 if (offset > 0)
237 tuiFree (srcLine);
238 fclose (stream);
239 srcWin->generic.contentSize = nlines;
240 ret = TUI_SUCCESS;
241 }
242 }
243 }
244 }
245 return ret;
246} /* tuiSetSourceContent */
247
248
249/* elz: this function sets the contents of the source window to empty
250 except for a line in the middle with a warning message about the
251 source not being available. This function is called by
252 tuiEraseSourceContents, which in turn is invoked when the source files
c5aa993b 253 cannot be accessed */
c906108c
SS
254
255void
256#ifdef __STDC__
257tuiSetSourceContentNil (
258 TuiWinInfoPtr winInfo,
259 char *warning_string)
260#else
261tuiSetSourceContentNil (winInfo, warning_string)
262 TuiWinInfoPtr winInfo;
263 char *warning_string;
264#endif
265{
266 int lineWidth;
267 int nLines;
268 int curr_line = 0;
269
270 lineWidth = winInfo->generic.width - 1;
271 nLines = winInfo->generic.height - 2;
272
273 /* set to empty each line in the window, except for the one
c5aa993b 274 which contains the message */
c906108c
SS
275 while (curr_line < winInfo->generic.contentSize)
276 {
277 /* set the information related to each displayed line
c5aa993b
JM
278 to null: i.e. the line number is 0, there is no bp,
279 it is not where the program is stopped */
c906108c
SS
280
281 TuiWinElementPtr element =
282 (TuiWinElementPtr) winInfo->generic.content[curr_line];
283 element->whichElement.source.lineOrAddr.lineNo = 0;
284 element->whichElement.source.isExecPoint = FALSE;
285 element->whichElement.source.hasBreak = FALSE;
286
c5aa993b 287 /* set the contents of the line to blank */
c906108c
SS
288 element->whichElement.source.line[0] = (char) 0;
289
290 /* if the current line is in the middle of the screen, then we want to
c5aa993b
JM
291 display the 'no source available' message in it.
292 Note: the 'weird' arithmetic with the line width and height comes from
293 the function tuiEraseSourceContent. We need to keep the screen and the
294 window's actual contents in synch */
c906108c
SS
295
296 if (curr_line == (nLines / 2 + 1))
297 {
298 int i;
299 int xpos;
300 int warning_length = strlen (warning_string);
301 char *srcLine;
302
303 srcLine = element->whichElement.source.line;
304
305 if (warning_length >= ((lineWidth - 1) / 2))
306 xpos = 1;
307 else
308 xpos = (lineWidth - 1) / 2 - warning_length;
309
310 for (i = 0; i < xpos; i++)
311 srcLine[i] = ' ';
312
313 sprintf (srcLine + i, "%s", warning_string);
314
315 for (i = xpos + warning_length; i < lineWidth; i++)
316 srcLine[i] = ' ';
317
318 srcLine[i] = '\n';
319
320 } /* end if */
321
322 curr_line++;
323
c5aa993b 324 } /* end while */
c906108c 325
c5aa993b 326} /*tuiSetSourceContentNil */
c906108c
SS
327
328
329
330
331/*
c5aa993b
JM
332 ** tuiShowSource().
333 ** Function to display source in the source window. This function
334 ** initializes the horizontal scroll to 0.
335 */
c906108c
SS
336void
337#ifdef __STDC__
338tuiShowSource (
339 struct symtab *s,
340 Opaque line,
341 int noerror)
342#else
343tuiShowSource (s, line, noerror)
344 struct symtab *s;
345 Opaque line;
346 int noerror;
347#endif
348{
349 srcWin->detail.sourceInfo.horizontalOffset = 0;
350 m_tuiShowSourceAsIs (s, line, noerror);
351
352 return;
353} /* tuiShowSource */
354
355
356/*
c5aa993b
JM
357 ** tuiSourceIsDisplayed().
358 ** Answer whether the source is currently displayed in the source window.
359 */
c906108c
SS
360int
361#ifdef __STDC__
362tuiSourceIsDisplayed (
363 char *fname)
364#else
365tuiSourceIsDisplayed (fname)
366 char *fname;
367#endif
368{
369 return (srcWin->generic.contentInUse &&
370 (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())->
371 content[0])->whichElement.locator.fileName, fname) == 0));
372} /* tuiSourceIsDisplayed */
373
374
375/*
c5aa993b
JM
376 ** tuiVerticalSourceScroll().
377 ** Scroll the source forward or backward vertically
378 */
c906108c
SS
379void
380#ifdef __STDC__
381tuiVerticalSourceScroll (
382 TuiScrollDirection scrollDirection,
383 int numToScroll)
384#else
385tuiVerticalSourceScroll (scrollDirection, numToScroll)
386 TuiScrollDirection scrollDirection;
387 int numToScroll;
388#endif
389{
390 if (srcWin->generic.content != (OpaquePtr) NULL)
391 {
392 int line;
393 Opaque addr;
394 struct symtab *s;
395 TuiWinContent content = (TuiWinContent) srcWin->generic.content;
396
397 if (current_source_symtab == (struct symtab *) NULL)
398 s = find_pc_symtab (selected_frame->pc);
399 else
400 s = current_source_symtab;
401
402 if (scrollDirection == FORWARD_SCROLL)
403 {
404 line = content[0]->whichElement.source.lineOrAddr.lineNo +
405 numToScroll;
406 if (line > s->nlines)
c5aa993b
JM
407 /*line = s->nlines - winInfo->generic.contentSize + 1; */
408 /*elz: fix for dts 23398 */
c906108c
SS
409 line = content[0]->whichElement.source.lineOrAddr.lineNo;
410 }
411 else
412 {
413 line = content[0]->whichElement.source.lineOrAddr.lineNo -
414 numToScroll;
415 if (line <= 0)
416 line = 1;
417 }
418 tuiUpdateSourceWindowAsIs (srcWin, s, (Opaque) line, FALSE);
419 }
420
421 return;
422} /* tuiVerticalSourceScroll */
423
424
425/*****************************************
426** STATIC LOCAL FUNCTIONS **
427******************************************/
428
429/*
c5aa993b
JM
430 ** _hasBreak().
431 ** Answer whether there is a break point at the input line in
432 ** the source file indicated
433 */
c906108c
SS
434static struct breakpoint *
435#ifdef __STDC__
436_hasBreak (
437 char *sourceFileName,
438 int lineNo)
439#else
440_hasBreak (sourceFileName, lineNo)
441 char *sourceFileName;
442 int lineNo;
443#endif
444{
445 struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
446 struct breakpoint *bp;
447 extern struct breakpoint *breakpoint_chain;
448
449
450 for (bp = breakpoint_chain;
451 (bp != (struct breakpoint *) NULL &&
452 bpWithBreak == (struct breakpoint *) NULL);
453 bp = bp->next)
454 if ((strcmp (sourceFileName, bp->source_file) == 0) &&
455 (lineNo == bp->line_number))
456 bpWithBreak = bp;
457
458 return bpWithBreak;
459} /* _hasBreak */
This page took 0.053534 seconds and 4 git commands to generate.