Fix pager bugs with style output
[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;
74 /* We have to process all the text in order to pick up all the
75 escapes. */
76 if (column < first_col || column > first_col + line_width)
77 continue;
78
79 if (c == '\n' || c == '\r' || c == '\0')
80 {
81 /* Nothing. */
82 }
83 else if (c < 040 && c != '\t')
84 {
85 result.push_back ('^');
86 result.push_back (c + 0100);
87 }
88 else if (c == 0177)
89 {
90 result.push_back ('^');
91 result.push_back ('?');
92 }
93 else if (c == '\t')
94 {
95 int j, max_tab_len = tui_tab_width;
96
97 for (j = column - ((column / max_tab_len) * max_tab_len);
98 j < max_tab_len && column < first_col + line_width;
99 column++, j++)
100 result.push_back (' ');
101 }
102 else
103 result.push_back (c);
104 }
105 while (c != '\0' && c != '\n' && c != '\r');
106
107 if (c == '\r' && *lineptr == '\n')
108 ++lineptr;
109 *ptr = lineptr;
110
111 return result;
112}
113
98427f35 114/* Function to display source in the source window. */
a358af15 115enum tui_status
08ef48c5
MS
116tui_set_source_content (struct symtab *s,
117 int line_no,
118 int noerror)
c906108c 119{
22940a24 120 enum tui_status ret = TUI_FAILURE;
c906108c 121
4e04028d 122 if (s != (struct symtab *) NULL)
c906108c 123 {
62f29fda 124 int line_width, nlines;
c906108c 125
6d012f14 126 if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
c906108c 127 {
6ba8e26f 128 line_width = TUI_SRC_WIN->generic.width - 1;
1cc6d956
MS
129 /* Take hilite (window border) into account, when
130 calculating the number of lines. */
6d012f14 131 nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
62f29fda
TT
132
133 std::string srclines;
134 if (!g_source_cache.get_source_lines (s, line_no, line_no + nlines,
135 &srclines))
c906108c
SS
136 {
137 if (!noerror)
138 {
05cba821 139 const char *filename = symtab_to_filename_for_display (s);
224c3ddb 140 char *name = (char *) alloca (strlen (filename) + 100);
1c5313c5 141
05cba821 142 sprintf (name, "%s:%d", filename, line_no);
c906108c
SS
143 print_sys_errmsg (name, errno);
144 }
145 ret = TUI_FAILURE;
146 }
147 else
148 {
62f29fda
TT
149 int cur_line_no, cur_line;
150 struct tui_gen_win_info *locator
151 = tui_locator_win_info_ptr ();
152 struct tui_source_info *src
153 = &TUI_SRC_WIN->detail.source_info;
154 const char *s_filename = symtab_to_filename_for_display (s);
155
156 if (TUI_SRC_WIN->generic.title)
157 xfree (TUI_SRC_WIN->generic.title);
158 TUI_SRC_WIN->generic.title = xstrdup (s_filename);
159
160 xfree (src->fullname);
161 src->fullname = xstrdup (symtab_to_fullname (s));
162
163 cur_line = 0;
164 src->gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
165 src->start_line_or_addr.loa = LOA_LINE;
166 cur_line_no = src->start_line_or_addr.u.line_no = line_no;
167
168 const char *iter = srclines.c_str ();
169 while (cur_line < nlines)
c906108c 170 {
62f29fda
TT
171 struct tui_win_element *element
172 = TUI_SRC_WIN->generic.content[cur_line];
173
174 std::string text;
175 if (*iter != '\0')
176 text = copy_source_line (&iter, cur_line_no,
177 src->horizontal_offset,
178 line_width);
179
180 /* Set whether element is the execution point
181 and whether there is a break point on it. */
182 element->which_element.source.line_or_addr.loa =
183 LOA_LINE;
184 element->which_element.source.line_or_addr.u.line_no =
185 cur_line_no;
186 element->which_element.source.is_exec_point =
187 (filename_cmp (locator->content[0]
188 ->which_element.locator.full_name,
189 symtab_to_fullname (s)) == 0
190 && cur_line_no
191 == locator->content[0]
192 ->which_element.locator.line_no);
193
194 xfree (TUI_SRC_WIN->generic.content[cur_line]
195 ->which_element.source.line);
62f29fda
TT
196 TUI_SRC_WIN->generic.content[cur_line]
197 ->which_element.source.line
986041cd 198 = xstrdup (text.c_str ());
62f29fda
TT
199
200 cur_line++;
201 cur_line_no++;
c906108c 202 }
62f29fda
TT
203 TUI_SRC_WIN->generic.content_size = nlines;
204 ret = TUI_SUCCESS;
c906108c
SS
205 }
206 }
207 }
208 return ret;
98427f35 209}
c906108c
SS
210
211
1cc6d956 212/* elz: This function sets the contents of the source window to empty
c906108c 213 except for a line in the middle with a warning message about the
1cc6d956 214 source not being available. This function is called by
6ba8e26f
AC
215 tui_erase_source_contents(), which in turn is invoked when the
216 source files cannot be accessed. */
c906108c
SS
217
218void
08ef48c5 219tui_set_source_content_nil (struct tui_win_info *win_info,
a121b7c1 220 const char *warning_string)
c906108c 221{
6ba8e26f
AC
222 int line_width;
223 int n_lines;
c906108c
SS
224 int curr_line = 0;
225
6ba8e26f
AC
226 line_width = win_info->generic.width - 1;
227 n_lines = win_info->generic.height - 2;
c906108c 228
1cc6d956
MS
229 /* Set to empty each line in the window, except for the one which
230 contains the message. */
6ba8e26f 231 while (curr_line < win_info->generic.content_size)
c906108c 232 {
1cc6d956
MS
233 /* Set the information related to each displayed line to null:
234 i.e. the line number is 0, there is no bp, it is not where
235 the program is stopped. */
c906108c 236
63ed8182 237 struct tui_win_element *element = win_info->generic.content[curr_line];
1c5313c5 238
362c05fe
AS
239 element->which_element.source.line_or_addr.loa = LOA_LINE;
240 element->which_element.source.line_or_addr.u.line_no = 0;
6d012f14
AC
241 element->which_element.source.is_exec_point = FALSE;
242 element->which_element.source.has_break = FALSE;
c906108c 243
1cc6d956 244 /* Set the contents of the line to blank. */
6d012f14 245 element->which_element.source.line[0] = (char) 0;
c906108c 246
1cc6d956 247 /* If the current line is in the middle of the screen, then we
6ba8e26f
AC
248 want to display the 'no source available' message in it.
249 Note: the 'weird' arithmetic with the line width and height
1cc6d956
MS
250 comes from the function tui_erase_source_content(). We need
251 to keep the screen and the window's actual contents in
252 synch. */
c906108c 253
6ba8e26f 254 if (curr_line == (n_lines / 2 + 1))
c906108c
SS
255 {
256 int i;
257 int xpos;
258 int warning_length = strlen (warning_string);
6ba8e26f 259 char *src_line;
c906108c 260
6ba8e26f 261 src_line = element->which_element.source.line;
c906108c 262
6ba8e26f 263 if (warning_length >= ((line_width - 1) / 2))
c906108c
SS
264 xpos = 1;
265 else
6ba8e26f 266 xpos = (line_width - 1) / 2 - warning_length;
c906108c
SS
267
268 for (i = 0; i < xpos; i++)
6ba8e26f 269 src_line[i] = ' ';
c906108c 270
6ba8e26f 271 sprintf (src_line + i, "%s", warning_string);
c906108c 272
6ba8e26f
AC
273 for (i = xpos + warning_length; i < line_width; i++)
274 src_line[i] = ' ';
c906108c 275
6ba8e26f 276 src_line[i] = '\n';
c906108c
SS
277
278 } /* end if */
279
280 curr_line++;
281
c5aa993b 282 } /* end while */
98427f35 283}
c906108c
SS
284
285
98427f35
SC
286/* Function to display source in the source window. This function
287 initializes the horizontal scroll to 0. */
c906108c 288void
13274fc3 289tui_show_symtab_source (struct gdbarch *gdbarch, struct symtab *s,
08ef48c5
MS
290 struct tui_line_or_address line,
291 int noerror)
c906108c 292{
6d012f14 293 TUI_SRC_WIN->detail.source_info.horizontal_offset = 0;
13274fc3 294 tui_update_source_window_as_is (TUI_SRC_WIN, gdbarch, s, line, noerror);
98427f35 295}
c906108c 296
c906108c 297
a358af15
AC
298/* Answer whether the source is currently displayed in the source
299 window. */
c906108c 300int
56d397a3 301tui_source_is_displayed (const char *fullname)
c906108c 302{
f629cd75
L
303 return (TUI_SRC_WIN != NULL
304 && TUI_SRC_WIN->generic.content_in_use
63ed8182
PP
305 && (filename_cmp (tui_locator_win_info_ptr ()->content[0]
306 ->which_element.locator.full_name,
56d397a3 307 fullname) == 0));
98427f35 308}
c906108c
SS
309
310
98427f35 311/* Scroll the source forward or backward vertically. */
c906108c 312void
6ba8e26f
AC
313tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction,
314 int num_to_scroll)
c906108c 315{
6d012f14 316 if (TUI_SRC_WIN->generic.content != NULL)
c906108c 317 {
362c05fe 318 struct tui_line_or_address l;
c906108c 319 struct symtab *s;
63a33118 320 tui_win_content content = TUI_SRC_WIN->generic.content;
52575520 321 struct symtab_and_line cursal = get_current_source_symtab_and_line ();
c906108c 322
52575520 323 if (cursal.symtab == (struct symtab *) NULL)
34248c3a 324 s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
c906108c 325 else
52575520 326 s = cursal.symtab;
c906108c 327
362c05fe 328 l.loa = LOA_LINE;
6ba8e26f 329 if (scroll_direction == FORWARD_SCROLL)
c906108c 330 {
362c05fe
AS
331 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
332 + num_to_scroll;
333 if (l.u.line_no > s->nlines)
1cc6d956
MS
334 /* line = s->nlines - win_info->generic.content_size + 1; */
335 /* elz: fix for dts 23398. */
9a2b4c1b
MS
336 l.u.line_no
337 = content[0]->which_element.source.line_or_addr.u.line_no;
c906108c
SS
338 }
339 else
340 {
362c05fe
AS
341 l.u.line_no = content[0]->which_element.source.line_or_addr.u.line_no
342 - num_to_scroll;
343 if (l.u.line_no <= 0)
344 l.u.line_no = 1;
c906108c 345 }
27229e99 346
362c05fe 347 print_source_lines (s, l.u.line_no, l.u.line_no + 1, 0);
c906108c 348 }
98427f35 349}
This page took 1.940964 seconds and 4 git commands to generate.