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