Make type-safe the 'content' field of struct tui_gen_win_info
[deliverable/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
32d0add0 3 Copyright (C) 1998-2015 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
5 Contributed by Hewlett-Packard Company.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
23#include <ctype.h>
24#include "symtab.h"
25#include "frame.h"
26#include "breakpoint.h"
c2c6d25f 27#include "source.h"
a4b99e53 28#include "symtab.h"
13274fc3 29#include "objfiles.h"
a7417d46 30#include "filenames.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"
6a83354a 37#include "gdb_curses.h"
c906108c 38
98427f35 39/* Function to display source in the source window. */
a358af15 40enum tui_status
08ef48c5
MS
41tui_set_source_content (struct symtab *s,
42 int line_no,
43 int noerror)
c906108c 44{
22940a24 45 enum tui_status ret = TUI_FAILURE;
c906108c 46
4e04028d 47 if (s != (struct symtab *) NULL)
c906108c 48 {
d02c80cd
AC
49 FILE *stream;
50 int i, desc, c, line_width, nlines;
51 char *src_line = 0;
c906108c 52
6d012f14 53 if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
c906108c 54 {
6ba8e26f 55 line_width = TUI_SRC_WIN->generic.width - 1;
1cc6d956
MS
56 /* Take hilite (window border) into account, when
57 calculating the number of lines. */
6d012f14 58 nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
c906108c
SS
59 desc = open_source_file (s);
60 if (desc < 0)
61 {
62 if (!noerror)
63 {
05cba821
JK
64 const char *filename = symtab_to_filename_for_display (s);
65 char *name = alloca (strlen (filename) + 100);
1c5313c5 66
05cba821 67 sprintf (name, "%s:%d", 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);
05cba821
JK
80 printf_unfiltered ("Line number %d out of range; "
81 "%s has %d lines.\n",
82 line_no,
83 symtab_to_filename_for_display (s),
84 s->nlines);
c906108c 85 }
6d012f14 86 else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
c906108c
SS
87 {
88 close (desc);
05cba821 89 perror_with_name (symtab_to_filename_for_display (s));
c906108c
SS
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;
05cba821 98 const char *s_filename = symtab_to_filename_for_display (s);
bc6b7f04 99
6d012f14
AC
100 if (TUI_SRC_WIN->generic.title)
101 xfree (TUI_SRC_WIN->generic.title);
05cba821 102 TUI_SRC_WIN->generic.title = xstrdup (s_filename);
bc6b7f04 103
aa079c93
JK
104 xfree (src->fullname);
105 src->fullname = xstrdup (symtab_to_fullname (s));
bc6b7f04 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;
eb822aa6 114 src->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
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 122 struct tui_win_element *element
63ed8182 123 = TUI_SRC_WIN->generic.content[cur_line];
c906108c 124
1cc6d956 125 /* Get the first character in the line. */
c906108c
SS
126 c = fgetc (stream);
127
128 if (offset == 0)
63ed8182
PP
129 src_line = TUI_SRC_WIN->generic.content[cur_line]
130 ->which_element.source.line;
1cc6d956 131 /* Init the line with the line number. */
6ba8e26f
AC
132 sprintf (src_line, "%-6d", cur_line_no);
133 cur_len = strlen (src_line);
9a2b4c1b
MS
134 i = cur_len - ((cur_len / tui_default_tab_len ())
135 * tui_default_tab_len ());
dd1abb8c 136 while (i < tui_default_tab_len ())
c906108c 137 {
6ba8e26f 138 src_line[cur_len] = ' ';
c906108c 139 i++;
6ba8e26f 140 cur_len++;
c906108c 141 }
6ba8e26f 142 src_line[cur_len] = (char) 0;
c906108c 143
1cc6d956
MS
144 /* Set whether element is the execution point
145 and whether there is a break point on it. */
362c05fe
AS
146 element->which_element.source.line_or_addr.loa =
147 LOA_LINE;
148 element->which_element.source.line_or_addr.u.line_no =
6ba8e26f 149 cur_line_no;
6d012f14 150 element->which_element.source.is_exec_point =
63ed8182
PP
151 (filename_cmp (locator->content[0]
152 ->which_element.locator.full_name,
56d397a3 153 symtab_to_fullname (s)) == 0
63ed8182
PP
154 && cur_line_no
155 == locator->content[0]
156 ->which_element.locator.line_no);
c906108c
SS
157 if (c != EOF)
158 {
6ba8e26f 159 i = strlen (src_line) - 1;
c906108c
SS
160 do
161 {
e5908723
MS
162 if ((c != '\n') && (c != '\r')
163 && (++i < threshold))
c906108c
SS
164 {
165 if (c < 040 && c != '\t')
166 {
6ba8e26f
AC
167 src_line[i++] = '^';
168 src_line[i] = c + 0100;
c906108c
SS
169 }
170 else if (c == 0177)
171 {
6ba8e26f
AC
172 src_line[i++] = '^';
173 src_line[i] = '?';
c906108c
SS
174 }
175 else
1cc6d956
MS
176 { /* Store the charcter in the
177 line buffer. If it is a tab,
178 then translate to the correct
179 number of chars so we don't
180 overwrite our buffer. */
c906108c
SS
181 if (c == '\t')
182 {
9a2b4c1b
MS
183 int j, max_tab_len
184 = tui_default_tab_len ();
c906108c 185
9a2b4c1b
MS
186 for (j = i - ((i / max_tab_len)
187 * max_tab_len);
e5908723
MS
188 j < max_tab_len
189 && i < threshold;
c906108c 190 i++, j++)
6ba8e26f 191 src_line[i] = ' ';
c906108c
SS
192 i--;
193 }
194 else
6ba8e26f 195 src_line[i] = c;
c906108c 196 }
6ba8e26f 197 src_line[i + 1] = 0;
c906108c
SS
198 }
199 else
1cc6d956
MS
200 { /* If we have not reached EOL, then
201 eat chars until we do. */
c906108c
SS
202 while (c != EOF && c != '\n' && c != '\r')
203 c = fgetc (stream);
861cf606 204 /* Handle non-'\n' end-of-line. */
e5908723
MS
205 if (c == '\r'
206 && (c = fgetc (stream)) != '\n'
207 && c != EOF)
861cf606
FR
208 {
209 ungetc (c, stream);
210 c = '\r';
211 }
212
c906108c
SS
213 }
214 }
e5908723
MS
215 while (c != EOF && c != '\n' && c != '\r'
216 && i < threshold
217 && (c = fgetc (stream)));
c906108c 218 }
1cc6d956
MS
219 /* Now copy the line taking the offset into
220 account. */
6ba8e26f 221 if (strlen (src_line) > offset)
63ed8182
PP
222 strcpy (TUI_SRC_WIN->generic.content[cur_line]
223 ->which_element.source.line,
6ba8e26f 224 &src_line[offset]);
c906108c 225 else
63ed8182
PP
226 TUI_SRC_WIN->generic.content[cur_line]
227 ->which_element.source.line[0] = (char) 0;
6ba8e26f
AC
228 cur_line++;
229 cur_line_no++;
c906108c
SS
230 }
231 if (offset > 0)
6ba8e26f 232 xfree (src_line);
c906108c 233 fclose (stream);
6d012f14 234 TUI_SRC_WIN->generic.content_size = nlines;
c906108c
SS
235 ret = TUI_SUCCESS;
236 }
237 }
238 }
239 }
240 return ret;
98427f35 241}
c906108c
SS
242
243
1cc6d956 244/* elz: This function sets the contents of the source window to empty
c906108c 245 except for a line in the middle with a warning message about the
1cc6d956 246 source not being available. This function is called by
6ba8e26f
AC
247 tui_erase_source_contents(), which in turn is invoked when the
248 source files cannot be accessed. */
c906108c
SS
249
250void
08ef48c5
MS
251tui_set_source_content_nil (struct tui_win_info *win_info,
252 char *warning_string)
c906108c 253{
6ba8e26f
AC
254 int line_width;
255 int n_lines;
c906108c
SS
256 int curr_line = 0;
257
6ba8e26f
AC
258 line_width = win_info->generic.width - 1;
259 n_lines = win_info->generic.height - 2;
c906108c 260
1cc6d956
MS
261 /* Set to empty each line in the window, except for the one which
262 contains the message. */
6ba8e26f 263 while (curr_line < win_info->generic.content_size)
c906108c 264 {
1cc6d956
MS
265 /* Set the information related to each displayed line to null:
266 i.e. the line number is 0, there is no bp, it is not where
267 the program is stopped. */
c906108c 268
63ed8182 269 struct tui_win_element *element = win_info->generic.content[curr_line];
1c5313c5 270
362c05fe
AS
271 element->which_element.source.line_or_addr.loa = LOA_LINE;
272 element->which_element.source.line_or_addr.u.line_no = 0;
6d012f14
AC
273 element->which_element.source.is_exec_point = FALSE;
274 element->which_element.source.has_break = FALSE;
c906108c 275
1cc6d956 276 /* Set the contents of the line to blank. */
6d012f14 277 element->which_element.source.line[0] = (char) 0;
c906108c 278
1cc6d956 279 /* If the current line is in the middle of the screen, then we
6ba8e26f
AC
280 want to display the 'no source available' message in it.
281 Note: the 'weird' arithmetic with the line width and height
1cc6d956
MS
282 comes from the function tui_erase_source_content(). We need
283 to keep the screen and the window's actual contents in
284 synch. */
c906108c 285
6ba8e26f 286 if (curr_line == (n_lines / 2 + 1))
c906108c
SS
287 {
288 int i;
289 int xpos;
290 int warning_length = strlen (warning_string);
6ba8e26f 291 char *src_line;
c906108c 292
6ba8e26f 293 src_line = element->which_element.source.line;
c906108c 294
6ba8e26f 295 if (warning_length >= ((line_width - 1) / 2))
c906108c
SS
296 xpos = 1;
297 else
6ba8e26f 298 xpos = (line_width - 1) / 2 - warning_length;
c906108c
SS
299
300 for (i = 0; i < xpos; i++)
6ba8e26f 301 src_line[i] = ' ';
c906108c 302
6ba8e26f 303 sprintf (src_line + i, "%s", warning_string);
c906108c 304
6ba8e26f
AC
305 for (i = xpos + warning_length; i < line_width; i++)
306 src_line[i] = ' ';
c906108c 307
6ba8e26f 308 src_line[i] = '\n';
c906108c
SS
309
310 } /* end if */
311
312 curr_line++;
313
c5aa993b 314 } /* end while */
98427f35 315}
c906108c
SS
316
317
98427f35
SC
318/* Function to display source in the source window. This function
319 initializes the horizontal scroll to 0. */
c906108c 320void
13274fc3 321tui_show_symtab_source (struct gdbarch *gdbarch, struct symtab *s,
08ef48c5
MS
322 struct tui_line_or_address line,
323 int noerror)
c906108c 324{
6d012f14 325 TUI_SRC_WIN->detail.source_info.horizontal_offset = 0;
13274fc3 326 tui_update_source_window_as_is (TUI_SRC_WIN, gdbarch, s, line, noerror);
98427f35 327}
c906108c 328
c906108c 329
a358af15
AC
330/* Answer whether the source is currently displayed in the source
331 window. */
c906108c 332int
56d397a3 333tui_source_is_displayed (const char *fullname)
c906108c 334{
f629cd75
L
335 return (TUI_SRC_WIN != NULL
336 && TUI_SRC_WIN->generic.content_in_use
63ed8182
PP
337 && (filename_cmp (tui_locator_win_info_ptr ()->content[0]
338 ->which_element.locator.full_name,
56d397a3 339 fullname) == 0));
98427f35 340}
c906108c
SS
341
342
98427f35 343/* Scroll the source forward or backward vertically. */
c906108c 344void
6ba8e26f
AC
345tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction,
346 int num_to_scroll)
c906108c 347{
6d012f14 348 if (TUI_SRC_WIN->generic.content != NULL)
c906108c 349 {
362c05fe 350 struct tui_line_or_address l;
c906108c 351 struct symtab *s;
6d012f14 352 tui_win_content content = (tui_win_content) TUI_SRC_WIN->generic.content;
52575520 353 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 354
52575520 355 if (cursal.symtab == (struct symtab *) NULL)
34248c3a 356 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 357 else
52575520 358 s = cursal.symtab;
c906108c 359
362c05fe 360 l.loa = LOA_LINE;
6ba8e26f 361 if (scroll_direction == FORWARD_SCROLL)
c906108c 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 > s->nlines)
1cc6d956
MS
366 /* line = s->nlines - win_info->generic.content_size + 1; */
367 /* elz: fix for dts 23398. */
9a2b4c1b
MS
368 l.u.line_no
369 = content[0]->which_element.source.line_or_addr.u.line_no;
c906108c
SS
370 }
371 else
372 {
362c05fe
AS
373 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
374 - num_to_scroll;
375 if (l.u.line_no <= 0)
376 l.u.line_no = 1;
c906108c 377 }
27229e99 378
362c05fe 379 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 380 }
98427f35 381}
This page took 1.566764 seconds and 4 git commands to generate.