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