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