]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-source.c
*** empty log message ***
[thirdparty/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
a358af15
AC
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
4 Foundation, Inc.
f33c6cbf 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. */
a358af15 48enum tui_status
6d012f14 49tui_set_source_content (struct symtab *s, int line_no, int noerror)
c906108c 50{
22940a24 51 enum tui_status ret = TUI_FAILURE;
c906108c
SS
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
6d012f14 59 if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
c906108c 60 {
6d012f14 61 lineWidth = TUI_SRC_WIN->generic.width - 1;
98427f35
SC
62 /* Take hilite (window border) into account, when calculating
63 the number of lines */
6d012f14 64 nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
c906108c
SS
65 desc = open_source_file (s);
66 if (desc < 0)
67 {
68 if (!noerror)
69 {
70 char *name = alloca (strlen (s->filename) + 100);
6d012f14 71 sprintf (name, "%s:%d", s->filename, line_no);
c906108c
SS
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
6d012f14 81 if (line_no < 1 || line_no > s->nlines)
c906108c
SS
82 {
83 close (desc);
84 printf_unfiltered (
85 "Line number %d out of range; %s has %d lines.\n",
6d012f14 86 line_no, s->filename, s->nlines);
c906108c 87 }
6d012f14 88 else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
c906108c
SS
89 {
90 close (desc);
91 perror_with_name (s->filename);
92 }
93 else
94 {
95 register int offset, curLineNo, curLine, curLen, threshold;
2a8854a7 96 struct tui_gen_win_info * locator = tui_locator_win_info_ptr ();
6d012f14 97 struct tui_source_info * src = &TUI_SRC_WIN->detail.source_info;
bc6b7f04 98
6d012f14
AC
99 if (TUI_SRC_WIN->generic.title)
100 xfree (TUI_SRC_WIN->generic.title);
101 TUI_SRC_WIN->generic.title = xstrdup (s->filename);
bc6b7f04
SC
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. */
6d012f14 109 offset = src->horizontal_offset;
c906108c
SS
110 threshold = (lineWidth - 1) + offset;
111 stream = fdopen (desc, FOPEN_RT);
112 clearerr (stream);
113 curLine = 0;
6d012f14 114 curLineNo = src->start_line_or_addr.line_no = line_no;
c906108c
SS
115 if (offset > 0)
116 srcLine = (char *) xmalloc (
117 (threshold + 1) * sizeof (char));
118 while (curLine < nlines)
119 {
2a8854a7 120 struct tui_win_element * element = (struct tui_win_element *)
6d012f14 121 TUI_SRC_WIN->generic.content[curLine];
c906108c
SS
122
123 /* get the first character in the line */
124 c = fgetc (stream);
125
126 if (offset == 0)
2a8854a7 127 srcLine = ((struct tui_win_element *)
6d012f14
AC
128 TUI_SRC_WIN->generic.content[
129 curLine])->which_element.source.line;
c906108c
SS
130 /* Init the line with the line number */
131 sprintf (srcLine, "%-6d", curLineNo);
132 curLen = strlen (srcLine);
133 i = curLen -
dd1abb8c
AC
134 ((curLen / tui_default_tab_len ()) * tui_default_tab_len ());
135 while (i < tui_default_tab_len ())
c906108c
SS
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. */
6d012f14 145 element->which_element.source.line_or_addr.line_no =
c906108c 146 curLineNo;
6d012f14 147 element->which_element.source.is_exec_point =
2a8854a7 148 (strcmp (((struct tui_win_element *)
6d012f14 149 locator->content[0])->which_element.locator.file_name,
c906108c 150 s->filename) == 0
2a8854a7 151 && curLineNo == ((struct tui_win_element *)
6d012f14 152 locator->content[0])->which_element.locator.line_no);
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 {
dd1abb8c 179 int j, maxTabLen = tui_default_tab_len ();
c906108c
SS
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)
6d012f14
AC
206 strcpy (((struct tui_win_element *) TUI_SRC_WIN->generic.content[
207 curLine])->which_element.source.line,
c906108c
SS
208 &srcLine[offset]);
209 else
2a8854a7 210 ((struct tui_win_element *)
6d012f14
AC
211 TUI_SRC_WIN->generic.content[
212 curLine])->which_element.source.line[0] = (char) 0;
c906108c
SS
213 curLine++;
214 curLineNo++;
215 }
216 if (offset > 0)
22940a24 217 xfree (srcLine);
c906108c 218 fclose (stream);
6d012f14 219 TUI_SRC_WIN->generic.content_size = nlines;
c906108c
SS
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
2a8854a7 236tui_set_source_content_nil (struct tui_win_info * 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 */
6d012f14 247 while (curr_line < winInfo->generic.content_size)
c906108c
SS
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 252
2a8854a7
AC
253 struct tui_win_element * element =
254 (struct tui_win_element *) winInfo->generic.content[curr_line];
6d012f14
AC
255 element->which_element.source.line_or_addr.line_no = 0;
256 element->which_element.source.is_exec_point = FALSE;
257 element->which_element.source.has_break = FALSE;
c906108c 258
c5aa993b 259 /* set the contents of the line to blank */
6d012f14 260 element->which_element.source.line[0] = (char) 0;
c906108c
SS
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
6d012f14 275 srcLine = element->which_element.source.line;
c906108c
SS
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
2a8854a7 303tui_show_symtab_source (struct symtab *s, union tui_line_or_address line, int noerror)
c906108c 304{
6d012f14
AC
305 TUI_SRC_WIN->detail.source_info.horizontal_offset = 0;
306 tui_update_source_window_as_is (TUI_SRC_WIN, s, line, noerror);
98427f35 307}
c906108c 308
c906108c 309
a358af15
AC
310/* Answer whether the source is currently displayed in the source
311 window. */
c906108c 312int
a358af15 313tui_source_is_displayed (char *fname)
c906108c 314{
6d012f14 315 return (TUI_SRC_WIN->generic.content_in_use &&
2a8854a7 316 (strcmp (((struct tui_win_element *) (tui_locator_win_info_ptr ())->
6d012f14 317 content[0])->which_element.locator.file_name, fname) == 0));
98427f35 318}
c906108c
SS
319
320
98427f35 321/* Scroll the source forward or backward vertically. */
c906108c 322void
2a8854a7 323tui_vertical_source_scroll (enum tui_scroll_direction scrollDirection,
a358af15 324 int numToScroll)
c906108c 325{
6d012f14 326 if (TUI_SRC_WIN->generic.content != NULL)
c906108c 327 {
2a8854a7 328 union tui_line_or_address l;
c906108c 329 struct symtab *s;
6d012f14 330 tui_win_content content = (tui_win_content) TUI_SRC_WIN->generic.content;
52575520 331 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 332
52575520 333 if (cursal.symtab == (struct symtab *) NULL)
f70a7d61 334 s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
c906108c 335 else
52575520 336 s = cursal.symtab;
c906108c
SS
337
338 if (scrollDirection == FORWARD_SCROLL)
339 {
6d012f14 340 l.line_no = content[0]->which_element.source.line_or_addr.line_no +
c906108c 341 numToScroll;
6d012f14
AC
342 if (l.line_no > s->nlines)
343 /*line = s->nlines - winInfo->generic.content_size + 1; */
c5aa993b 344 /*elz: fix for dts 23398 */
6d012f14 345 l.line_no = content[0]->which_element.source.line_or_addr.line_no;
c906108c
SS
346 }
347 else
348 {
6d012f14 349 l.line_no = content[0]->which_element.source.line_or_addr.line_no -
c906108c 350 numToScroll;
6d012f14
AC
351 if (l.line_no <= 0)
352 l.line_no = 1;
c906108c 353 }
27229e99 354
6d012f14 355 print_source_lines (s, l.line_no, l.line_no + 1, 0);
c906108c 356 }
98427f35 357}