]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-source.c
daily update
[thirdparty/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
9b254dd1 3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008
6aba47ca 4 Free Software 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
a9762ec7 12 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
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
a9762ec7 21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
22
23#include "defs.h"
24#include <ctype.h>
25#include "symtab.h"
26#include "frame.h"
27#include "breakpoint.h"
c2c6d25f 28#include "source.h"
a4b99e53 29#include "symtab.h"
c906108c 30
d7b2e967
AC
31#include "tui/tui.h"
32#include "tui/tui-data.h"
33#include "tui/tui-stack.h"
34#include "tui/tui-winsource.h"
35#include "tui/tui-source.h"
c906108c 36
88289b6e 37#include "gdb_string.h"
6a83354a 38#include "gdb_curses.h"
c906108c 39
98427f35 40/* Function to display source in the source window. */
a358af15 41enum tui_status
08ef48c5
MS
42tui_set_source_content (struct symtab *s,
43 int line_no,
44 int noerror)
c906108c 45{
22940a24 46 enum tui_status ret = TUI_FAILURE;
c906108c
SS
47
48 if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
49 {
d02c80cd
AC
50 FILE *stream;
51 int i, desc, c, line_width, nlines;
52 char *src_line = 0;
c906108c 53
6d012f14 54 if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
c906108c 55 {
6ba8e26f 56 line_width = TUI_SRC_WIN->generic.width - 1;
1cc6d956
MS
57 /* Take hilite (window border) into account, when
58 calculating the number of lines. */
6d012f14 59 nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
c906108c
SS
60 desc = open_source_file (s);
61 if (desc < 0)
62 {
63 if (!noerror)
64 {
65 char *name = alloca (strlen (s->filename) + 100);
6d012f14 66 sprintf (name, "%s:%d", s->filename, line_no);
c906108c
SS
67 print_sys_errmsg (name, errno);
68 }
69 ret = TUI_FAILURE;
70 }
71 else
72 {
73 if (s->line_charpos == 0)
74 find_source_lines (s, desc);
75
6d012f14 76 if (line_no < 1 || line_no > s->nlines)
c906108c
SS
77 {
78 close (desc);
79 printf_unfiltered (
80 "Line number %d out of range; %s has %d lines.\n",
6d012f14 81 line_no, s->filename, s->nlines);
c906108c 82 }
6d012f14 83 else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
c906108c
SS
84 {
85 close (desc);
86 perror_with_name (s->filename);
87 }
88 else
89 {
d02c80cd 90 int offset, cur_line_no, cur_line, cur_len, threshold;
5b6fe301
MS
91 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
92 struct tui_source_info *src = &TUI_SRC_WIN->detail.source_info;
bc6b7f04 93
6d012f14
AC
94 if (TUI_SRC_WIN->generic.title)
95 xfree (TUI_SRC_WIN->generic.title);
96 TUI_SRC_WIN->generic.title = xstrdup (s->filename);
bc6b7f04
SC
97
98 if (src->filename)
99 xfree (src->filename);
100 src->filename = xstrdup (s->filename);
101
1cc6d956
MS
102 /* Determine the threshold for the length of the
103 line and the offset to start the display. */
6d012f14 104 offset = src->horizontal_offset;
6ba8e26f 105 threshold = (line_width - 1) + offset;
c906108c
SS
106 stream = fdopen (desc, FOPEN_RT);
107 clearerr (stream);
6ba8e26f 108 cur_line = 0;
362c05fe
AS
109 src->start_line_or_addr.loa = LOA_LINE;
110 cur_line_no = src->start_line_or_addr.u.line_no = line_no;
c906108c 111 if (offset > 0)
6ba8e26f 112 src_line = (char *) xmalloc (
c906108c 113 (threshold + 1) * sizeof (char));
6ba8e26f 114 while (cur_line < nlines)
c906108c 115 {
5b6fe301 116 struct tui_win_element *element = (struct tui_win_element *)
6ba8e26f 117 TUI_SRC_WIN->generic.content[cur_line];
c906108c 118
1cc6d956 119 /* Get the first character in the line. */
c906108c
SS
120 c = fgetc (stream);
121
122 if (offset == 0)
6ba8e26f 123 src_line = ((struct tui_win_element *)
6d012f14 124 TUI_SRC_WIN->generic.content[
6ba8e26f 125 cur_line])->which_element.source.line;
1cc6d956 126 /* Init the line with the line number. */
6ba8e26f
AC
127 sprintf (src_line, "%-6d", cur_line_no);
128 cur_len = strlen (src_line);
129 i = cur_len -
130 ((cur_len / tui_default_tab_len ()) * tui_default_tab_len ());
dd1abb8c 131 while (i < tui_default_tab_len ())
c906108c 132 {
6ba8e26f 133 src_line[cur_len] = ' ';
c906108c 134 i++;
6ba8e26f 135 cur_len++;
c906108c 136 }
6ba8e26f 137 src_line[cur_len] = (char) 0;
c906108c 138
1cc6d956
MS
139 /* Set whether element is the execution point
140 and whether there is a break point on it. */
362c05fe
AS
141 element->which_element.source.line_or_addr.loa =
142 LOA_LINE;
143 element->which_element.source.line_or_addr.u.line_no =
6ba8e26f 144 cur_line_no;
6d012f14 145 element->which_element.source.is_exec_point =
2a8854a7 146 (strcmp (((struct tui_win_element *)
e5908723 147 locator->content[0])->which_element.locator.file_name,
c906108c 148 s->filename) == 0
6ba8e26f 149 && cur_line_no == ((struct tui_win_element *)
e5908723 150 locator->content[0])->which_element.locator.line_no);
c906108c
SS
151 if (c != EOF)
152 {
6ba8e26f 153 i = strlen (src_line) - 1;
c906108c
SS
154 do
155 {
e5908723
MS
156 if ((c != '\n') && (c != '\r')
157 && (++i < threshold))
c906108c
SS
158 {
159 if (c < 040 && c != '\t')
160 {
6ba8e26f
AC
161 src_line[i++] = '^';
162 src_line[i] = c + 0100;
c906108c
SS
163 }
164 else if (c == 0177)
165 {
6ba8e26f
AC
166 src_line[i++] = '^';
167 src_line[i] = '?';
c906108c
SS
168 }
169 else
1cc6d956
MS
170 { /* Store the charcter in the
171 line buffer. If it is a tab,
172 then translate to the correct
173 number of chars so we don't
174 overwrite our buffer. */
c906108c
SS
175 if (c == '\t')
176 {
6ba8e26f 177 int j, max_tab_len = tui_default_tab_len ();
c906108c 178
e5908723
MS
179 for (j = i - ((i / max_tab_len) * max_tab_len);
180 j < max_tab_len
181 && i < threshold;
c906108c 182 i++, j++)
6ba8e26f 183 src_line[i] = ' ';
c906108c
SS
184 i--;
185 }
186 else
6ba8e26f 187 src_line[i] = c;
c906108c 188 }
6ba8e26f 189 src_line[i + 1] = 0;
c906108c
SS
190 }
191 else
1cc6d956
MS
192 { /* If we have not reached EOL, then
193 eat chars until we do. */
c906108c
SS
194 while (c != EOF && c != '\n' && c != '\r')
195 c = fgetc (stream);
861cf606 196 /* Handle non-'\n' end-of-line. */
e5908723
MS
197 if (c == '\r'
198 && (c = fgetc (stream)) != '\n'
199 && c != EOF)
861cf606
FR
200 {
201 ungetc (c, stream);
202 c = '\r';
203 }
204
c906108c
SS
205 }
206 }
e5908723
MS
207 while (c != EOF && c != '\n' && c != '\r'
208 && i < threshold
209 && (c = fgetc (stream)));
c906108c 210 }
1cc6d956
MS
211 /* Now copy the line taking the offset into
212 account. */
6ba8e26f 213 if (strlen (src_line) > offset)
6d012f14 214 strcpy (((struct tui_win_element *) TUI_SRC_WIN->generic.content[
6ba8e26f
AC
215 cur_line])->which_element.source.line,
216 &src_line[offset]);
c906108c 217 else
2a8854a7 218 ((struct tui_win_element *)
6d012f14 219 TUI_SRC_WIN->generic.content[
6ba8e26f
AC
220 cur_line])->which_element.source.line[0] = (char) 0;
221 cur_line++;
222 cur_line_no++;
c906108c
SS
223 }
224 if (offset > 0)
6ba8e26f 225 xfree (src_line);
c906108c 226 fclose (stream);
6d012f14 227 TUI_SRC_WIN->generic.content_size = nlines;
c906108c
SS
228 ret = TUI_SUCCESS;
229 }
230 }
231 }
232 }
233 return ret;
98427f35 234}
c906108c
SS
235
236
1cc6d956 237/* elz: This function sets the contents of the source window to empty
c906108c 238 except for a line in the middle with a warning message about the
1cc6d956 239 source not being available. This function is called by
6ba8e26f
AC
240 tui_erase_source_contents(), which in turn is invoked when the
241 source files cannot be accessed. */
c906108c
SS
242
243void
08ef48c5
MS
244tui_set_source_content_nil (struct tui_win_info *win_info,
245 char *warning_string)
c906108c 246{
6ba8e26f
AC
247 int line_width;
248 int n_lines;
c906108c
SS
249 int curr_line = 0;
250
6ba8e26f
AC
251 line_width = win_info->generic.width - 1;
252 n_lines = win_info->generic.height - 2;
c906108c 253
1cc6d956
MS
254 /* Set to empty each line in the window, except for the one which
255 contains the message. */
6ba8e26f 256 while (curr_line < win_info->generic.content_size)
c906108c 257 {
1cc6d956
MS
258 /* Set the information related to each displayed line to null:
259 i.e. the line number is 0, there is no bp, it is not where
260 the program is stopped. */
c906108c 261
5b6fe301
MS
262 struct tui_win_element *element =
263 (struct tui_win_element *) win_info->generic.content[curr_line];
362c05fe
AS
264 element->which_element.source.line_or_addr.loa = LOA_LINE;
265 element->which_element.source.line_or_addr.u.line_no = 0;
6d012f14
AC
266 element->which_element.source.is_exec_point = FALSE;
267 element->which_element.source.has_break = FALSE;
c906108c 268
1cc6d956 269 /* Set the contents of the line to blank. */
6d012f14 270 element->which_element.source.line[0] = (char) 0;
c906108c 271
1cc6d956 272 /* If the current line is in the middle of the screen, then we
6ba8e26f
AC
273 want to display the 'no source available' message in it.
274 Note: the 'weird' arithmetic with the line width and height
1cc6d956
MS
275 comes from the function tui_erase_source_content(). We need
276 to keep the screen and the window's actual contents in
277 synch. */
c906108c 278
6ba8e26f 279 if (curr_line == (n_lines / 2 + 1))
c906108c
SS
280 {
281 int i;
282 int xpos;
283 int warning_length = strlen (warning_string);
6ba8e26f 284 char *src_line;
c906108c 285
6ba8e26f 286 src_line = element->which_element.source.line;
c906108c 287
6ba8e26f 288 if (warning_length >= ((line_width - 1) / 2))
c906108c
SS
289 xpos = 1;
290 else
6ba8e26f 291 xpos = (line_width - 1) / 2 - warning_length;
c906108c
SS
292
293 for (i = 0; i < xpos; i++)
6ba8e26f 294 src_line[i] = ' ';
c906108c 295
6ba8e26f 296 sprintf (src_line + i, "%s", warning_string);
c906108c 297
6ba8e26f
AC
298 for (i = xpos + warning_length; i < line_width; i++)
299 src_line[i] = ' ';
c906108c 300
6ba8e26f 301 src_line[i] = '\n';
c906108c
SS
302
303 } /* end if */
304
305 curr_line++;
306
c5aa993b 307 } /* end while */
98427f35 308}
c906108c
SS
309
310
98427f35
SC
311/* Function to display source in the source window. This function
312 initializes the horizontal scroll to 0. */
c906108c 313void
08ef48c5
MS
314tui_show_symtab_source (struct symtab *s,
315 struct tui_line_or_address line,
316 int noerror)
c906108c 317{
6d012f14
AC
318 TUI_SRC_WIN->detail.source_info.horizontal_offset = 0;
319 tui_update_source_window_as_is (TUI_SRC_WIN, s, line, noerror);
98427f35 320}
c906108c 321
c906108c 322
a358af15
AC
323/* Answer whether the source is currently displayed in the source
324 window. */
c906108c 325int
a358af15 326tui_source_is_displayed (char *fname)
c906108c 327{
e5908723
MS
328 return (TUI_SRC_WIN->generic.content_in_use
329 && (strcmp (((struct tui_win_element *) (tui_locator_win_info_ptr ())->
330 content[0])->which_element.locator.file_name, fname) == 0));
98427f35 331}
c906108c
SS
332
333
98427f35 334/* Scroll the source forward or backward vertically. */
c906108c 335void
6ba8e26f
AC
336tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction,
337 int num_to_scroll)
c906108c 338{
6d012f14 339 if (TUI_SRC_WIN->generic.content != NULL)
c906108c 340 {
362c05fe 341 struct tui_line_or_address l;
c906108c 342 struct symtab *s;
6d012f14 343 tui_win_content content = (tui_win_content) TUI_SRC_WIN->generic.content;
52575520 344 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 345
52575520 346 if (cursal.symtab == (struct symtab *) NULL)
206415a3 347 s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 348 else
52575520 349 s = cursal.symtab;
c906108c 350
362c05fe 351 l.loa = LOA_LINE;
6ba8e26f 352 if (scroll_direction == FORWARD_SCROLL)
c906108c 353 {
362c05fe
AS
354 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
355 + num_to_scroll;
356 if (l.u.line_no > s->nlines)
1cc6d956
MS
357 /* line = s->nlines - win_info->generic.content_size + 1; */
358 /* elz: fix for dts 23398. */
362c05fe 359 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no;
c906108c
SS
360 }
361 else
362 {
362c05fe
AS
363 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
364 - num_to_scroll;
365 if (l.u.line_no <= 0)
366 l.u.line_no = 1;
c906108c 367 }
27229e99 368
362c05fe 369 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 370 }
98427f35 371}