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