Remove union tui_which_element
[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
08ef48c5
MS
126tui_set_source_content (struct symtab *s,
127 int line_no,
128 int noerror)
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
TT
136 ret = TUI_SUCCESS;
137 tui_alloc_source_buffer (TUI_SRC_WIN);
138 line_width = TUI_SRC_WIN->width - 1;
139 /* Take hilite (window border) into account, when
140 calculating the number of lines. */
141 nlines = (line_no + (TUI_SRC_WIN->height - 2)) - line_no;
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
TT
161 = tui_locator_win_info_ptr ();
162 struct tui_source_window_base *src
163 = (struct tui_source_window_base *) TUI_SRC_WIN;
164 const char *s_filename = symtab_to_filename_for_display (s);
165
166 if (TUI_SRC_WIN->title)
167 xfree (TUI_SRC_WIN->title);
168 TUI_SRC_WIN->title = xstrdup (s_filename);
169
170 xfree (src->fullname);
171 src->fullname = xstrdup (symtab_to_fullname (s));
172
173 cur_line = 0;
174 src->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
175 src->start_line_or_addr.loa = LOA_LINE;
176 cur_line_no = src->start_line_or_addr.u.line_no = line_no;
177
178 const char *iter = srclines.c_str ();
53e7cdba 179 TUI_SRC_WIN->content.resize (nlines);
29d2c474 180 while (cur_line < nlines)
c906108c 181 {
53e7cdba
TT
182 struct tui_source_element *element
183 = &TUI_SRC_WIN->content[cur_line];
29d2c474
TT
184
185 std::string text;
186 if (*iter != '\0')
187 text = copy_source_line (&iter, cur_line_no,
188 src->horizontal_offset,
189 line_width);
190
191 /* Set whether element is the execution point
192 and whether there is a break point on it. */
53e7cdba
TT
193 element->line_or_addr.loa = LOA_LINE;
194 element->line_or_addr.u.line_no = cur_line_no;
195 element->is_exec_point
196 = (filename_cmp (locator->full_name,
197 symtab_to_fullname (s)) == 0
198 && cur_line_no == locator->line_no);
199
200 xfree (TUI_SRC_WIN->content[cur_line].line);
201 TUI_SRC_WIN->content[cur_line].line
29d2c474
TT
202 = xstrdup (text.c_str ());
203
204 cur_line++;
205 cur_line_no++;
c906108c 206 }
29d2c474 207 ret = TUI_SUCCESS;
c906108c
SS
208 }
209 }
210 return ret;
98427f35 211}
c906108c
SS
212
213
1cc6d956 214/* elz: This function sets the contents of the source window to empty
c906108c 215 except for a line in the middle with a warning message about the
1cc6d956 216 source not being available. This function is called by
6ba8e26f
AC
217 tui_erase_source_contents(), which in turn is invoked when the
218 source files cannot be accessed. */
c906108c
SS
219
220void
7908abbf 221tui_set_source_content_nil (struct tui_source_window_base *win_info,
a121b7c1 222 const char *warning_string)
c906108c 223{
6ba8e26f
AC
224 int line_width;
225 int n_lines;
c906108c
SS
226 int curr_line = 0;
227
cb2ce893
TT
228 line_width = win_info->width - 1;
229 n_lines = win_info->height - 2;
c906108c 230
1cc6d956
MS
231 /* Set to empty each line in the window, except for the one which
232 contains the message. */
53e7cdba 233 while (curr_line < win_info->content.size ())
c906108c 234 {
1cc6d956
MS
235 /* Set the information related to each displayed line to null:
236 i.e. the line number is 0, there is no bp, it is not where
237 the program is stopped. */
c906108c 238
53e7cdba 239 struct tui_source_element *element = &win_info->content[curr_line];
1c5313c5 240
53e7cdba
TT
241 element->line_or_addr.loa = LOA_LINE;
242 element->line_or_addr.u.line_no = 0;
243 element->is_exec_point = false;
244 element->has_break = FALSE;
c906108c 245
1cc6d956 246 /* Set the contents of the line to blank. */
53e7cdba 247 element->line[0] = (char) 0;
c906108c 248
1cc6d956 249 /* If the current line is in the middle of the screen, then we
6ba8e26f
AC
250 want to display the 'no source available' message in it.
251 Note: the 'weird' arithmetic with the line width and height
1cc6d956
MS
252 comes from the function tui_erase_source_content(). We need
253 to keep the screen and the window's actual contents in
254 synch. */
c906108c 255
6ba8e26f 256 if (curr_line == (n_lines / 2 + 1))
c906108c 257 {
c906108c
SS
258 int xpos;
259 int warning_length = strlen (warning_string);
6ba8e26f 260 char *src_line;
c906108c 261
6ba8e26f 262 if (warning_length >= ((line_width - 1) / 2))
c906108c
SS
263 xpos = 1;
264 else
6ba8e26f 265 xpos = (line_width - 1) / 2 - warning_length;
c906108c 266
0c820d67 267 src_line = xstrprintf ("%s%s", n_spaces (xpos), warning_string);
53e7cdba
TT
268 xfree (element->line);
269 element->line = src_line;
0c820d67 270 }
c906108c
SS
271
272 curr_line++;
0c820d67 273 }
98427f35 274}
c906108c
SS
275
276
98427f35
SC
277/* Function to display source in the source window. This function
278 initializes the horizontal scroll to 0. */
c906108c 279void
13274fc3 280tui_show_symtab_source (struct gdbarch *gdbarch, struct symtab *s,
08ef48c5
MS
281 struct tui_line_or_address line,
282 int noerror)
c906108c 283{
e6e41501 284 TUI_SRC_WIN->horizontal_offset = 0;
13274fc3 285 tui_update_source_window_as_is (TUI_SRC_WIN, gdbarch, s, line, noerror);
98427f35 286}
c906108c 287
c906108c 288
a358af15
AC
289/* Answer whether the source is currently displayed in the source
290 window. */
c906108c 291int
56d397a3 292tui_source_is_displayed (const char *fullname)
c906108c 293{
f629cd75 294 return (TUI_SRC_WIN != NULL
cb2ce893 295 && TUI_SRC_WIN->content_in_use
3add462f 296 && (filename_cmp (tui_locator_win_info_ptr ()->full_name,
56d397a3 297 fullname) == 0));
98427f35 298}
c906108c
SS
299
300
98427f35 301/* Scroll the source forward or backward vertically. */
c906108c 302void
c3bd716f 303tui_source_window::do_scroll_vertical (int num_to_scroll)
c906108c 304{
53e7cdba 305 if (!content.empty ())
c906108c 306 {
362c05fe 307 struct tui_line_or_address l;
c906108c 308 struct symtab *s;
52575520 309 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 310
cafb3438 311 if (cursal.symtab == NULL)
34248c3a 312 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 313 else
52575520 314 s = cursal.symtab;
c906108c 315
362c05fe 316 l.loa = LOA_LINE;
53e7cdba 317 l.u.line_no = content[0].line_or_addr.u.line_no
c3bd716f
TT
318 + num_to_scroll;
319 if (l.u.line_no > s->nlines)
320 /* line = s->nlines - win_info->content_size + 1; */
321 /* elz: fix for dts 23398. */
53e7cdba 322 l.u.line_no = content[0].line_or_addr.u.line_no;
c3bd716f
TT
323 if (l.u.line_no <= 0)
324 l.u.line_no = 1;
27229e99 325
362c05fe 326 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 327 }
98427f35 328}
This page took 2.06731 seconds and 4 git commands to generate.