Save plain text in the source cache
[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
TT
138 tui_alloc_source_buffer (win_info);
139 line_width = win_info->width - 1;
29d2c474
TT
140 /* Take hilite (window border) into account, when
141 calculating the number of lines. */
5813316f 142 nlines = (line_no + (win_info->height - 2)) - line_no;
29d2c474
TT
143
144 std::string srclines;
145 if (!g_source_cache.get_source_lines (s, line_no, line_no + nlines,
146 &srclines))
c906108c 147 {
29d2c474 148 if (!noerror)
c906108c 149 {
29d2c474
TT
150 const char *filename = symtab_to_filename_for_display (s);
151 char *name = (char *) alloca (strlen (filename) + 100);
152
153 sprintf (name, "%s:%d", filename, line_no);
154 print_sys_errmsg (name, errno);
c906108c 155 }
29d2c474
TT
156 ret = TUI_FAILURE;
157 }
158 else
159 {
160 int cur_line_no, cur_line;
3add462f 161 struct tui_locator_window *locator
29d2c474 162 = tui_locator_win_info_ptr ();
29d2c474
TT
163 const char *s_filename = symtab_to_filename_for_display (s);
164
5813316f
TT
165 xfree (win_info->title);
166 win_info->title = xstrdup (s_filename);
29d2c474 167
5813316f
TT
168 xfree (win_info->fullname);
169 win_info->fullname = xstrdup (symtab_to_fullname (s));
29d2c474
TT
170
171 cur_line = 0;
5813316f
TT
172 win_info->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
173 win_info->start_line_or_addr.loa = LOA_LINE;
174 cur_line_no = win_info->start_line_or_addr.u.line_no = line_no;
29d2c474
TT
175
176 const char *iter = srclines.c_str ();
5813316f 177 win_info->content.resize (nlines);
29d2c474 178 while (cur_line < nlines)
c906108c 179 {
53e7cdba 180 struct tui_source_element *element
5813316f 181 = &win_info->content[cur_line];
29d2c474
TT
182
183 std::string text;
184 if (*iter != '\0')
185 text = copy_source_line (&iter, cur_line_no,
5813316f 186 win_info->horizontal_offset,
29d2c474
TT
187 line_width);
188
189 /* Set whether element is the execution point
190 and whether there is a break point on it. */
53e7cdba
TT
191 element->line_or_addr.loa = LOA_LINE;
192 element->line_or_addr.u.line_no = cur_line_no;
193 element->is_exec_point
194 = (filename_cmp (locator->full_name,
195 symtab_to_fullname (s)) == 0
196 && cur_line_no == locator->line_no);
197
5813316f
TT
198 xfree (win_info->content[cur_line].line);
199 win_info->content[cur_line].line
29d2c474
TT
200 = xstrdup (text.c_str ());
201
202 cur_line++;
203 cur_line_no++;
c906108c 204 }
29d2c474 205 ret = TUI_SUCCESS;
c906108c
SS
206 }
207 }
208 return ret;
98427f35 209}
c906108c
SS
210
211
98427f35
SC
212/* Function to display source in the source window. This function
213 initializes the horizontal scroll to 0. */
c906108c 214void
5813316f
TT
215tui_show_symtab_source (tui_source_window_base *win_info,
216 struct gdbarch *gdbarch, struct symtab *s,
08ef48c5
MS
217 struct tui_line_or_address line,
218 int noerror)
c906108c 219{
5813316f
TT
220 win_info->horizontal_offset = 0;
221 tui_update_source_window_as_is (win_info, gdbarch, s, line, noerror);
98427f35 222}
c906108c 223
c906108c 224
a358af15
AC
225/* Answer whether the source is currently displayed in the source
226 window. */
a38da35d
TT
227bool
228tui_source_window::showing_source_p (const char *fullname) const
c906108c 229{
f6cc34a9 230 return (!content.empty ()
3add462f 231 && (filename_cmp (tui_locator_win_info_ptr ()->full_name,
56d397a3 232 fullname) == 0));
98427f35 233}
c906108c
SS
234
235
98427f35 236/* Scroll the source forward or backward vertically. */
c906108c 237void
c3bd716f 238tui_source_window::do_scroll_vertical (int num_to_scroll)
c906108c 239{
53e7cdba 240 if (!content.empty ())
c906108c 241 {
362c05fe 242 struct tui_line_or_address l;
c906108c 243 struct symtab *s;
52575520 244 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 245
cafb3438 246 if (cursal.symtab == NULL)
34248c3a 247 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 248 else
52575520 249 s = cursal.symtab;
c906108c 250
362c05fe 251 l.loa = LOA_LINE;
53e7cdba 252 l.u.line_no = content[0].line_or_addr.u.line_no
c3bd716f
TT
253 + num_to_scroll;
254 if (l.u.line_no > s->nlines)
255 /* line = s->nlines - win_info->content_size + 1; */
256 /* elz: fix for dts 23398. */
53e7cdba 257 l.u.line_no = content[0].line_or_addr.u.line_no;
c3bd716f
TT
258 if (l.u.line_no <= 0)
259 l.u.line_no = 1;
27229e99 260
362c05fe 261 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 262 }
98427f35 263}
b73dd877
TT
264
265tui_source_window::tui_source_window ()
266 : tui_source_window_base (SRC_WIN)
267{
268 gdb::observers::source_styling_changed.attach
269 (std::bind (&tui_source_window::style_changed, this),
270 m_observable);
271}
272
273tui_source_window::~tui_source_window ()
274{
275 gdb::observers::source_styling_changed.detach (m_observable);
276}
277
278void
279tui_source_window::style_changed ()
280{
281 if (tui_active && is_visible)
282 refill ();
283}
c2cd8994
TT
284
285bool
286tui_source_window::location_matches_p (struct bp_location *loc, int line_no)
287{
288 return (content[line_no].line_or_addr.loa == LOA_LINE
289 && content[line_no].line_or_addr.u.line_no == loc->line_number
290 && loc->symtab != NULL
291 && filename_cmp (fullname,
292 symtab_to_fullname (loc->symtab)) == 0);
293}
This page took 1.99915 seconds and 4 git commands to generate.