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