2004-02-06 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
96ec9981 3 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
f33c6cbf
AC
4 Inc.
5
f377b406
SC
6 Contributed by Hewlett-Packard Company.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
c906108c
SS
24
25#include "defs.h"
26#include <ctype.h>
27#include "symtab.h"
28#include "frame.h"
29#include "breakpoint.h"
c2c6d25f 30#include "source.h"
a4b99e53 31#include "symtab.h"
c906108c 32
d7b2e967
AC
33#include "tui/tui.h"
34#include "tui/tui-data.h"
35#include "tui/tui-stack.h"
36#include "tui/tui-winsource.h"
37#include "tui/tui-source.h"
c906108c 38
96ec9981
DJ
39#ifdef HAVE_NCURSES_H
40#include <ncurses.h>
41#else
42#ifdef HAVE_CURSES_H
43#include <curses.h>
44#endif
45#endif
c906108c 46
98427f35 47/* Function to display source in the source window. */
c906108c 48TuiStatus
eca6576c 49tuiSetSourceContent (struct symtab *s, int lineNo, int noerror)
c906108c
SS
50{
51 TuiStatus ret = TUI_FAILURE;
52
53 if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
54 {
55 register FILE *stream;
56 register int i, desc, c, lineWidth, nlines;
bc6b7f04 57 register char *srcLine = 0;
c906108c 58
f80bda8e 59 if ((ret = tui_alloc_source_buffer (srcWin)) == TUI_SUCCESS)
c906108c
SS
60 {
61 lineWidth = srcWin->generic.width - 1;
98427f35
SC
62 /* Take hilite (window border) into account, when calculating
63 the number of lines */
c906108c
SS
64 nlines = (lineNo + (srcWin->generic.height - 2)) - lineNo;
65 desc = open_source_file (s);
66 if (desc < 0)
67 {
68 if (!noerror)
69 {
70 char *name = alloca (strlen (s->filename) + 100);
71 sprintf (name, "%s:%d", s->filename, lineNo);
72 print_sys_errmsg (name, errno);
73 }
74 ret = TUI_FAILURE;
75 }
76 else
77 {
78 if (s->line_charpos == 0)
79 find_source_lines (s, desc);
80
81 if (lineNo < 1 || lineNo > s->nlines)
82 {
83 close (desc);
84 printf_unfiltered (
85 "Line number %d out of range; %s has %d lines.\n",
86 lineNo, s->filename, s->nlines);
87 }
88 else if (lseek (desc, s->line_charpos[lineNo - 1], 0) < 0)
89 {
90 close (desc);
91 perror_with_name (s->filename);
92 }
93 else
94 {
95 register int offset, curLineNo, curLine, curLen, threshold;
96 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
bc6b7f04
SC
97 TuiSourceInfoPtr src = &srcWin->detail.sourceInfo;
98
99 if (srcWin->generic.title)
100 xfree (srcWin->generic.title);
101 srcWin->generic.title = xstrdup (s->filename);
102
103 if (src->filename)
104 xfree (src->filename);
105 src->filename = xstrdup (s->filename);
106
107 /* Determine the threshold for the length of the line
108 and the offset to start the display. */
109 offset = src->horizontalOffset;
c906108c
SS
110 threshold = (lineWidth - 1) + offset;
111 stream = fdopen (desc, FOPEN_RT);
112 clearerr (stream);
113 curLine = 0;
bc6b7f04 114 curLineNo = src->startLineOrAddr.lineNo = lineNo;
c906108c
SS
115 if (offset > 0)
116 srcLine = (char *) xmalloc (
117 (threshold + 1) * sizeof (char));
118 while (curLine < nlines)
119 {
120 TuiWinElementPtr element = (TuiWinElementPtr)
121 srcWin->generic.content[curLine];
c906108c
SS
122
123 /* get the first character in the line */
124 c = fgetc (stream);
125
126 if (offset == 0)
127 srcLine = ((TuiWinElementPtr)
128 srcWin->generic.content[
129 curLine])->whichElement.source.line;
130 /* Init the line with the line number */
131 sprintf (srcLine, "%-6d", curLineNo);
132 curLen = strlen (srcLine);
133 i = curLen -
134 ((curLen / tuiDefaultTabLen ()) * tuiDefaultTabLen ());
135 while (i < tuiDefaultTabLen ())
136 {
137 srcLine[curLen] = ' ';
138 i++;
139 curLen++;
140 }
141 srcLine[curLen] = (char) 0;
142
98427f35
SC
143 /* Set whether element is the execution point and
144 whether there is a break point on it. */
c906108c
SS
145 element->whichElement.source.lineOrAddr.lineNo =
146 curLineNo;
147 element->whichElement.source.isExecPoint =
148 (strcmp (((TuiWinElementPtr)
149 locator->content[0])->whichElement.locator.fileName,
150 s->filename) == 0
151 && curLineNo == ((TuiWinElementPtr)
152 locator->content[0])->whichElement.locator.lineNo);
c906108c
SS
153 if (c != EOF)
154 {
155 i = strlen (srcLine) - 1;
156 do
157 {
158 if ((c != '\n') &&
159 (c != '\r') && (++i < threshold))
160 {
161 if (c < 040 && c != '\t')
162 {
163 srcLine[i++] = '^';
164 srcLine[i] = c + 0100;
165 }
166 else if (c == 0177)
167 {
168 srcLine[i++] = '^';
169 srcLine[i] = '?';
170 }
171 else
98427f35
SC
172 { /* Store the charcter in the line
173 buffer. If it is a tab, then
174 translate to the correct number of
175 chars so we don't overwrite our
176 buffer. */
c906108c
SS
177 if (c == '\t')
178 {
179 int j, maxTabLen = tuiDefaultTabLen ();
180
181 for (j = i - (
182 (i / maxTabLen) * maxTabLen);
183 ((j < maxTabLen) &&
184 i < threshold);
185 i++, j++)
186 srcLine[i] = ' ';
187 i--;
188 }
189 else
190 srcLine[i] = c;
191 }
192 srcLine[i + 1] = 0;
193 }
194 else
98427f35
SC
195 { /* If we have not reached EOL, then eat
196 chars until we do */
c906108c
SS
197 while (c != EOF && c != '\n' && c != '\r')
198 c = fgetc (stream);
199 }
200 }
201 while (c != EOF && c != '\n' && c != '\r' &&
202 i < threshold && (c = fgetc (stream)));
203 }
204 /* Now copy the line taking the offset into account */
205 if (strlen (srcLine) > offset)
206 strcpy (((TuiWinElementPtr) srcWin->generic.content[
207 curLine])->whichElement.source.line,
208 &srcLine[offset]);
209 else
210 ((TuiWinElementPtr)
211 srcWin->generic.content[
212 curLine])->whichElement.source.line[0] = (char) 0;
213 curLine++;
214 curLineNo++;
215 }
216 if (offset > 0)
217 tuiFree (srcLine);
218 fclose (stream);
219 srcWin->generic.contentSize = nlines;
220 ret = TUI_SUCCESS;
221 }
222 }
223 }
224 }
225 return ret;
98427f35 226}
c906108c
SS
227
228
229/* elz: this function sets the contents of the source window to empty
230 except for a line in the middle with a warning message about the
231 source not being available. This function is called by
f80bda8e
AC
232 tuiEraseSourceContents, which in turn is invoked when the source
233 files cannot be accessed. */
c906108c
SS
234
235void
f80bda8e 236tui_set_source_content_nil (TuiWinInfoPtr winInfo, char *warning_string)
c906108c
SS
237{
238 int lineWidth;
239 int nLines;
240 int curr_line = 0;
241
242 lineWidth = winInfo->generic.width - 1;
243 nLines = winInfo->generic.height - 2;
244
245 /* set to empty each line in the window, except for the one
c5aa993b 246 which contains the message */
c906108c
SS
247 while (curr_line < winInfo->generic.contentSize)
248 {
249 /* set the information related to each displayed line
c5aa993b
JM
250 to null: i.e. the line number is 0, there is no bp,
251 it is not where the program is stopped */
c906108c
SS
252
253 TuiWinElementPtr element =
254 (TuiWinElementPtr) winInfo->generic.content[curr_line];
255 element->whichElement.source.lineOrAddr.lineNo = 0;
256 element->whichElement.source.isExecPoint = FALSE;
257 element->whichElement.source.hasBreak = FALSE;
258
c5aa993b 259 /* set the contents of the line to blank */
c906108c
SS
260 element->whichElement.source.line[0] = (char) 0;
261
262 /* if the current line is in the middle of the screen, then we want to
c5aa993b
JM
263 display the 'no source available' message in it.
264 Note: the 'weird' arithmetic with the line width and height comes from
265 the function tuiEraseSourceContent. We need to keep the screen and the
266 window's actual contents in synch */
c906108c
SS
267
268 if (curr_line == (nLines / 2 + 1))
269 {
270 int i;
271 int xpos;
272 int warning_length = strlen (warning_string);
273 char *srcLine;
274
275 srcLine = element->whichElement.source.line;
276
277 if (warning_length >= ((lineWidth - 1) / 2))
278 xpos = 1;
279 else
280 xpos = (lineWidth - 1) / 2 - warning_length;
281
282 for (i = 0; i < xpos; i++)
283 srcLine[i] = ' ';
284
285 sprintf (srcLine + i, "%s", warning_string);
286
287 for (i = xpos + warning_length; i < lineWidth; i++)
288 srcLine[i] = ' ';
289
290 srcLine[i] = '\n';
291
292 } /* end if */
293
294 curr_line++;
295
c5aa993b 296 } /* end while */
98427f35 297}
c906108c
SS
298
299
98427f35
SC
300/* Function to display source in the source window. This function
301 initializes the horizontal scroll to 0. */
c906108c 302void
a4b99e53 303tuiShowSource (struct symtab *s, TuiLineOrAddress line, int noerror)
c906108c
SS
304{
305 srcWin->detail.sourceInfo.horizontalOffset = 0;
f80bda8e 306 tui_update_source_window_as_is (srcWin, s, line, noerror);
98427f35 307}
c906108c 308
c906108c 309
98427f35 310/* Answer whether the source is currently displayed in the source window. */
c906108c 311int
eca6576c 312tuiSourceIsDisplayed (char *fname)
c906108c
SS
313{
314 return (srcWin->generic.contentInUse &&
315 (strcmp (((TuiWinElementPtr) (locatorWinInfoPtr ())->
316 content[0])->whichElement.locator.fileName, fname) == 0));
98427f35 317}
c906108c
SS
318
319
98427f35 320/* Scroll the source forward or backward vertically. */
c906108c 321void
a4b99e53
SC
322tuiVerticalSourceScroll (TuiScrollDirection scrollDirection,
323 int numToScroll)
c906108c
SS
324{
325 if (srcWin->generic.content != (OpaquePtr) NULL)
326 {
a4b99e53 327 TuiLineOrAddress l;
c906108c
SS
328 struct symtab *s;
329 TuiWinContent content = (TuiWinContent) srcWin->generic.content;
52575520 330 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 331
52575520 332 if (cursal.symtab == (struct symtab *) NULL)
f70a7d61 333 s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
c906108c 334 else
52575520 335 s = cursal.symtab;
c906108c
SS
336
337 if (scrollDirection == FORWARD_SCROLL)
338 {
a4b99e53 339 l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo +
c906108c 340 numToScroll;
a4b99e53 341 if (l.lineNo > s->nlines)
c5aa993b
JM
342 /*line = s->nlines - winInfo->generic.contentSize + 1; */
343 /*elz: fix for dts 23398 */
a4b99e53 344 l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo;
c906108c
SS
345 }
346 else
347 {
a4b99e53 348 l.lineNo = content[0]->whichElement.source.lineOrAddr.lineNo -
c906108c 349 numToScroll;
a4b99e53
SC
350 if (l.lineNo <= 0)
351 l.lineNo = 1;
c906108c 352 }
27229e99
SC
353
354 print_source_lines (s, l.lineNo, l.lineNo + 1, 0);
c906108c 355 }
98427f35 356}
This page took 0.630164 seconds and 4 git commands to generate.