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