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