Remove separate visibility flag
[deliverable/binutils-gdb.git] / gdb / tui / tui-source.c
CommitLineData
f377b406 1/* TUI display source window.
f33c6cbf 2
42a4f53d 3 Copyright (C) 1998-2019 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"
13274fc3 28#include "objfiles.h"
a7417d46 29#include "filenames.h"
62f29fda 30#include "source-cache.h"
c906108c 31
d7b2e967
AC
32#include "tui/tui.h"
33#include "tui/tui-data.h"
62f29fda 34#include "tui/tui-io.h"
d7b2e967
AC
35#include "tui/tui-stack.h"
36#include "tui/tui-winsource.h"
37#include "tui/tui-source.h"
6a83354a 38#include "gdb_curses.h"
c906108c 39
62f29fda
TT
40/* A helper function for tui_set_source_content that extracts some
41 source text from PTR. LINE_NO is the line number; FIRST_COL is the
42 first column to extract, and LINE_WIDTH is the number of characters
43 to display. Returns a string holding the desired text. */
44
45static std::string
46copy_source_line (const char **ptr, int line_no, int first_col,
47 int line_width)
48{
49 const char *lineptr = *ptr;
50
51 /* Init the line with the line number. */
52 std::string result = string_printf ("%-6d", line_no);
53 int len = result.size ();
54 len = len - ((len / tui_tab_width) * tui_tab_width);
55 result.append (len, ' ');
56
57 int column = 0;
58 char c;
59 do
60 {
61 int skip_bytes;
62
63 c = *lineptr;
64 if (c == '\033' && skip_ansi_escape (lineptr, &skip_bytes))
65 {
66 /* We always have to preserve escapes. */
67 result.append (lineptr, lineptr + skip_bytes);
68 lineptr += skip_bytes;
69 continue;
70 }
71
72 ++lineptr;
73 ++column;
647bb750
HD
74
75 auto process_tab = [&] ()
76 {
77 int max_tab_len = tui_tab_width;
78
79 --column;
80 for (int j = column % max_tab_len;
81 j < max_tab_len && column < first_col + line_width;
82 column++, j++)
83 if (column >= first_col)
84 result.push_back (' ');
85 };
86
62f29fda
TT
87 /* We have to process all the text in order to pick up all the
88 escapes. */
647bb750
HD
89 if (column <= first_col || column > first_col + line_width)
90 {
91 if (c == '\t')
92 process_tab ();
93 continue;
94 }
62f29fda
TT
95
96 if (c == '\n' || c == '\r' || c == '\0')
97 {
98 /* Nothing. */
99 }
100 else if (c < 040 && c != '\t')
101 {
102 result.push_back ('^');
103 result.push_back (c + 0100);
104 }
105 else if (c == 0177)
106 {
107 result.push_back ('^');
108 result.push_back ('?');
109 }
110 else if (c == '\t')
647bb750 111 process_tab ();
62f29fda
TT
112 else
113 result.push_back (c);
114 }
115 while (c != '\0' && c != '\n' && c != '\r');
116
117 if (c == '\r' && *lineptr == '\n')
118 ++lineptr;
119 *ptr = lineptr;
120
121 return result;
122}
123
98427f35 124/* Function to display source in the source window. */
a358af15 125enum tui_status
5813316f
TT
126tui_set_source_content (tui_source_window_base *win_info,
127 struct symtab *s,
08ef48c5
MS
128 int line_no,
129 int noerror)
c906108c 130{
22940a24 131 enum tui_status ret = TUI_FAILURE;
c906108c 132
cafb3438 133 if (s != NULL)
c906108c 134 {
62f29fda 135 int line_width, nlines;
c906108c 136
29d2c474 137 ret = TUI_SUCCESS;
5813316f 138 line_width = win_info->width - 1;
29d2c474
TT
139 /* Take hilite (window border) into account, when
140 calculating the number of lines. */
5813316f 141 nlines = (line_no + (win_info->height - 2)) - line_no;
29d2c474
TT
142
143 std::string srclines;
144 if (!g_source_cache.get_source_lines (s, line_no, line_no + nlines,
145 &srclines))
c906108c 146 {
29d2c474 147 if (!noerror)
c906108c 148 {
29d2c474
TT
149 const char *filename = symtab_to_filename_for_display (s);
150 char *name = (char *) alloca (strlen (filename) + 100);
151
152 sprintf (name, "%s:%d", filename, line_no);
153 print_sys_errmsg (name, errno);
c906108c 154 }
29d2c474
TT
155 ret = TUI_FAILURE;
156 }
157 else
158 {
159 int cur_line_no, cur_line;
3add462f 160 struct tui_locator_window *locator
29d2c474 161 = tui_locator_win_info_ptr ();
29d2c474
TT
162 const char *s_filename = symtab_to_filename_for_display (s);
163
5813316f
TT
164 xfree (win_info->title);
165 win_info->title = xstrdup (s_filename);
29d2c474 166
5813316f
TT
167 xfree (win_info->fullname);
168 win_info->fullname = xstrdup (symtab_to_fullname (s));
29d2c474
TT
169
170 cur_line = 0;
5813316f
TT
171 win_info->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
172 win_info->start_line_or_addr.loa = LOA_LINE;
173 cur_line_no = win_info->start_line_or_addr.u.line_no = line_no;
29d2c474
TT
174
175 const char *iter = srclines.c_str ();
5813316f 176 win_info->content.resize (nlines);
29d2c474 177 while (cur_line < nlines)
c906108c 178 {
53e7cdba 179 struct tui_source_element *element
5813316f 180 = &win_info->content[cur_line];
29d2c474
TT
181
182 std::string text;
183 if (*iter != '\0')
184 text = copy_source_line (&iter, cur_line_no,
5813316f 185 win_info->horizontal_offset,
29d2c474
TT
186 line_width);
187
188 /* Set whether element is the execution point
189 and whether there is a break point on it. */
53e7cdba
TT
190 element->line_or_addr.loa = LOA_LINE;
191 element->line_or_addr.u.line_no = cur_line_no;
192 element->is_exec_point
193 = (filename_cmp (locator->full_name,
194 symtab_to_fullname (s)) == 0
195 && cur_line_no == locator->line_no);
196
5813316f
TT
197 xfree (win_info->content[cur_line].line);
198 win_info->content[cur_line].line
29d2c474
TT
199 = xstrdup (text.c_str ());
200
201 cur_line++;
202 cur_line_no++;
c906108c 203 }
29d2c474 204 ret = TUI_SUCCESS;
c906108c
SS
205 }
206 }
207 return ret;
98427f35 208}
c906108c
SS
209
210
98427f35
SC
211/* Function to display source in the source window. This function
212 initializes the horizontal scroll to 0. */
c906108c 213void
5813316f
TT
214tui_show_symtab_source (tui_source_window_base *win_info,
215 struct gdbarch *gdbarch, struct symtab *s,
08ef48c5
MS
216 struct tui_line_or_address line,
217 int noerror)
c906108c 218{
5813316f
TT
219 win_info->horizontal_offset = 0;
220 tui_update_source_window_as_is (win_info, gdbarch, s, line, noerror);
98427f35 221}
c906108c 222
c906108c 223
a358af15
AC
224/* Answer whether the source is currently displayed in the source
225 window. */
a38da35d
TT
226bool
227tui_source_window::showing_source_p (const char *fullname) const
c906108c 228{
f6cc34a9 229 return (!content.empty ()
3add462f 230 && (filename_cmp (tui_locator_win_info_ptr ()->full_name,
56d397a3 231 fullname) == 0));
98427f35 232}
c906108c
SS
233
234
98427f35 235/* Scroll the source forward or backward vertically. */
c906108c 236void
c3bd716f 237tui_source_window::do_scroll_vertical (int num_to_scroll)
c906108c 238{
53e7cdba 239 if (!content.empty ())
c906108c 240 {
362c05fe 241 struct tui_line_or_address l;
c906108c 242 struct symtab *s;
52575520 243 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 244
cafb3438 245 if (cursal.symtab == NULL)
34248c3a 246 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 247 else
52575520 248 s = cursal.symtab;
c906108c 249
362c05fe 250 l.loa = LOA_LINE;
53e7cdba 251 l.u.line_no = content[0].line_or_addr.u.line_no
c3bd716f 252 + num_to_scroll;
cb44333d
TT
253 const std::vector<off_t> *offsets;
254 if (g_source_cache.get_line_charpos (s, &offsets)
255 && l.u.line_no > offsets->size ())
c3bd716f
TT
256 /* line = s->nlines - win_info->content_size + 1; */
257 /* elz: fix for dts 23398. */
53e7cdba 258 l.u.line_no = content[0].line_or_addr.u.line_no;
c3bd716f
TT
259 if (l.u.line_no <= 0)
260 l.u.line_no = 1;
27229e99 261
362c05fe 262 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 263 }
98427f35 264}
b73dd877
TT
265
266tui_source_window::tui_source_window ()
267 : tui_source_window_base (SRC_WIN)
268{
269 gdb::observers::source_styling_changed.attach
270 (std::bind (&tui_source_window::style_changed, this),
271 m_observable);
272}
273
274tui_source_window::~tui_source_window ()
275{
276 gdb::observers::source_styling_changed.detach (m_observable);
277}
278
279void
280tui_source_window::style_changed ()
281{
2d83e710 282 if (tui_active && is_visible ())
b73dd877
TT
283 refill ();
284}
c2cd8994
TT
285
286bool
287tui_source_window::location_matches_p (struct bp_location *loc, int line_no)
288{
289 return (content[line_no].line_or_addr.loa == LOA_LINE
290 && content[line_no].line_or_addr.u.line_no == loc->line_number
291 && loc->symtab != NULL
292 && filename_cmp (fullname,
293 symtab_to_fullname (loc->symtab)) == 0);
294}
a54700c6 295
c9033fe8
TT
296/* See tui-source.h. */
297
298bool
299tui_source_window::line_is_displayed (int line) const
300{
301 bool is_displayed = false;
302 int threshold = SCROLL_THRESHOLD;
303 int i = 0;
304 while (i < content.size () - threshold && !is_displayed)
305 {
306 is_displayed
307 = (content[i].line_or_addr.loa == LOA_LINE
308 && content[i].line_or_addr.u.line_no == line);
309 i++;
310 }
311
312 return is_displayed;
313}
314
a54700c6
TT
315void
316tui_source_window::maybe_update (struct frame_info *fi, symtab_and_line sal,
317 int line_no, CORE_ADDR addr)
318{
319 int start_line = (line_no - (viewport_height / 2)) + 1;
320 if (start_line <= 0)
321 start_line = 1;
322
323 bool source_already_displayed = (sal.symtab != 0
324 && showing_source_p (fullname));
325
326 struct tui_line_or_address l;
327
328 l.loa = LOA_LINE;
329 l.u.line_no = start_line;
330 if (!(source_already_displayed
c9033fe8 331 && line_is_displayed (line_no)))
a54700c6
TT
332 tui_update_source_window (this, get_frame_arch (fi),
333 sal.symtab, l, TRUE);
334 else
335 {
336 l.u.line_no = line_no;
337 set_is_exec_point_at (l);
338 }
339}
This page took 2.127772 seconds and 4 git commands to generate.