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