Change tui_update_breakpoint_info to be a method
[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,
20149b6b 128 int line_no)
c906108c 129{
22940a24 130 enum tui_status ret = TUI_FAILURE;
c906108c 131
cafb3438 132 if (s != NULL)
c906108c 133 {
62f29fda 134 int line_width, nlines;
c906108c 135
29d2c474 136 ret = TUI_SUCCESS;
5813316f 137 line_width = win_info->width - 1;
29d2c474
TT
138 /* Take hilite (window border) into account, when
139 calculating the number of lines. */
5813316f 140 nlines = (line_no + (win_info->height - 2)) - line_no;
29d2c474
TT
141
142 std::string srclines;
143 if (!g_source_cache.get_source_lines (s, line_no, line_no + nlines,
144 &srclines))
20149b6b 145 ret = TUI_FAILURE;
29d2c474
TT
146 else
147 {
148 int cur_line_no, cur_line;
3add462f 149 struct tui_locator_window *locator
29d2c474 150 = tui_locator_win_info_ptr ();
29d2c474
TT
151 const char *s_filename = symtab_to_filename_for_display (s);
152
5813316f
TT
153 xfree (win_info->title);
154 win_info->title = xstrdup (s_filename);
29d2c474 155
5813316f
TT
156 xfree (win_info->fullname);
157 win_info->fullname = xstrdup (symtab_to_fullname (s));
29d2c474
TT
158
159 cur_line = 0;
5813316f
TT
160 win_info->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
161 win_info->start_line_or_addr.loa = LOA_LINE;
162 cur_line_no = win_info->start_line_or_addr.u.line_no = line_no;
29d2c474
TT
163
164 const char *iter = srclines.c_str ();
5813316f 165 win_info->content.resize (nlines);
29d2c474 166 while (cur_line < nlines)
c906108c 167 {
53e7cdba 168 struct tui_source_element *element
5813316f 169 = &win_info->content[cur_line];
29d2c474
TT
170
171 std::string text;
172 if (*iter != '\0')
173 text = copy_source_line (&iter, cur_line_no,
5813316f 174 win_info->horizontal_offset,
29d2c474
TT
175 line_width);
176
177 /* Set whether element is the execution point
178 and whether there is a break point on it. */
53e7cdba
TT
179 element->line_or_addr.loa = LOA_LINE;
180 element->line_or_addr.u.line_no = cur_line_no;
181 element->is_exec_point
182 = (filename_cmp (locator->full_name,
183 symtab_to_fullname (s)) == 0
184 && cur_line_no == locator->line_no);
185
5813316f
TT
186 xfree (win_info->content[cur_line].line);
187 win_info->content[cur_line].line
29d2c474
TT
188 = xstrdup (text.c_str ());
189
190 cur_line++;
191 cur_line_no++;
c906108c 192 }
29d2c474 193 ret = TUI_SUCCESS;
c906108c
SS
194 }
195 }
196 return ret;
98427f35 197}
c906108c
SS
198
199
98427f35
SC
200/* Function to display source in the source window. This function
201 initializes the horizontal scroll to 0. */
c906108c 202void
5813316f
TT
203tui_show_symtab_source (tui_source_window_base *win_info,
204 struct gdbarch *gdbarch, struct symtab *s,
20149b6b 205 struct tui_line_or_address line)
c906108c 206{
5813316f 207 win_info->horizontal_offset = 0;
ed8358e9 208 win_info->update_source_window_as_is (gdbarch, s, line);
98427f35 209}
c906108c 210
c906108c 211
a358af15
AC
212/* Answer whether the source is currently displayed in the source
213 window. */
a38da35d
TT
214bool
215tui_source_window::showing_source_p (const char *fullname) const
c906108c 216{
f6cc34a9 217 return (!content.empty ()
3add462f 218 && (filename_cmp (tui_locator_win_info_ptr ()->full_name,
56d397a3 219 fullname) == 0));
98427f35 220}
c906108c
SS
221
222
98427f35 223/* Scroll the source forward or backward vertically. */
c906108c 224void
c3bd716f 225tui_source_window::do_scroll_vertical (int num_to_scroll)
c906108c 226{
53e7cdba 227 if (!content.empty ())
c906108c 228 {
362c05fe 229 struct tui_line_or_address l;
c906108c 230 struct symtab *s;
52575520 231 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 232
cafb3438 233 if (cursal.symtab == NULL)
34248c3a 234 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 235 else
52575520 236 s = cursal.symtab;
c906108c 237
362c05fe 238 l.loa = LOA_LINE;
53e7cdba 239 l.u.line_no = content[0].line_or_addr.u.line_no
c3bd716f 240 + num_to_scroll;
cb44333d
TT
241 const std::vector<off_t> *offsets;
242 if (g_source_cache.get_line_charpos (s, &offsets)
243 && l.u.line_no > offsets->size ())
c3bd716f
TT
244 /* line = s->nlines - win_info->content_size + 1; */
245 /* elz: fix for dts 23398. */
53e7cdba 246 l.u.line_no = content[0].line_or_addr.u.line_no;
c3bd716f
TT
247 if (l.u.line_no <= 0)
248 l.u.line_no = 1;
27229e99 249
362c05fe 250 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 251 }
98427f35 252}
b73dd877
TT
253
254tui_source_window::tui_source_window ()
255 : tui_source_window_base (SRC_WIN)
256{
257 gdb::observers::source_styling_changed.attach
258 (std::bind (&tui_source_window::style_changed, this),
259 m_observable);
260}
261
262tui_source_window::~tui_source_window ()
263{
264 gdb::observers::source_styling_changed.detach (m_observable);
265}
266
267void
268tui_source_window::style_changed ()
269{
2d83e710 270 if (tui_active && is_visible ())
b73dd877
TT
271 refill ();
272}
c2cd8994
TT
273
274bool
275tui_source_window::location_matches_p (struct bp_location *loc, int line_no)
276{
277 return (content[line_no].line_or_addr.loa == LOA_LINE
278 && content[line_no].line_or_addr.u.line_no == loc->line_number
279 && loc->symtab != NULL
280 && filename_cmp (fullname,
281 symtab_to_fullname (loc->symtab)) == 0);
282}
a54700c6 283
c9033fe8
TT
284/* See tui-source.h. */
285
286bool
287tui_source_window::line_is_displayed (int line) const
288{
289 bool is_displayed = false;
290 int threshold = SCROLL_THRESHOLD;
291 int i = 0;
292 while (i < content.size () - threshold && !is_displayed)
293 {
294 is_displayed
295 = (content[i].line_or_addr.loa == LOA_LINE
296 && content[i].line_or_addr.u.line_no == line);
297 i++;
298 }
299
300 return is_displayed;
301}
302
a54700c6
TT
303void
304tui_source_window::maybe_update (struct frame_info *fi, symtab_and_line sal,
305 int line_no, CORE_ADDR addr)
306{
307 int start_line = (line_no - (viewport_height / 2)) + 1;
308 if (start_line <= 0)
309 start_line = 1;
310
311 bool source_already_displayed = (sal.symtab != 0
312 && showing_source_p (fullname));
313
314 struct tui_line_or_address l;
315
316 l.loa = LOA_LINE;
317 l.u.line_no = start_line;
318 if (!(source_already_displayed
c9033fe8 319 && line_is_displayed (line_no)))
017f9828 320 update_source_window (get_frame_arch (fi), sal.symtab, l);
a54700c6
TT
321 else
322 {
323 l.u.line_no = line_no;
324 set_is_exec_point_at (l);
325 }
326}
This page took 1.986553 seconds and 4 git commands to generate.