Change tui_source_element::line to have type std::string
[deliverable/binutils-gdb.git] / gdb / tui / tui-winsource.c
CommitLineData
f377b406 1/* TUI display source/assembly 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"
fd0407d6 27#include "value.h"
52575520 28#include "source.h"
13274fc3 29#include "objfiles.h"
a7417d46 30#include "filenames.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-win.h"
37#include "tui/tui-wingeneral.h"
38#include "tui/tui-winsource.h"
39#include "tui/tui-source.h"
40#include "tui/tui-disasm.h"
6a83354a 41#include "gdb_curses.h"
c906108c 42
1f393769 43/* Function to display the "main" routine. */
c906108c 44void
b4eb2452 45tui_display_main ()
c906108c 46{
3891b65e
TT
47 auto adapter = tui_source_windows ();
48 if (adapter.begin () != adapter.end ())
c906108c 49 {
13274fc3 50 struct gdbarch *gdbarch;
c906108c
SS
51 CORE_ADDR addr;
52
13274fc3 53 tui_get_begin_asm_address (&gdbarch, &addr);
c774cec6 54 if (addr != (CORE_ADDR) 0)
c906108c 55 {
34248c3a 56 struct symtab *s;
c906108c 57
13274fc3 58 tui_update_source_windows_with_addr (gdbarch, addr);
34248c3a
DE
59 s = find_pc_line_symtab (addr);
60 if (s != NULL)
61 tui_update_locator_fullname (symtab_to_fullname (s));
2e17b763 62 else
56d397a3 63 tui_update_locator_fullname ("??");
c906108c
SS
64 }
65 }
2e17b763 66}
c906108c
SS
67
68
69
f80bda8e
AC
70/* Function to display source in the source window. This function
71 initializes the horizontal scroll to 0. */
c906108c 72void
017f9828
TT
73tui_source_window_base::update_source_window
74 (struct gdbarch *gdbarch,
75 struct symtab *s,
76 struct tui_line_or_address line_or_addr)
c906108c 77{
017f9828
TT
78 horizontal_offset = 0;
79 update_source_window_as_is (gdbarch, s, line_or_addr);
f80bda8e 80}
c906108c
SS
81
82
f80bda8e
AC
83/* Function to display source in the source/asm window. This function
84 shows the source as specified by the horizontal offset. */
c906108c 85void
ed8358e9
TT
86tui_source_window_base::update_source_window_as_is
87 (struct gdbarch *gdbarch,
88 struct symtab *s,
89 struct tui_line_or_address line_or_addr)
c906108c 90{
81c82c4b
TT
91 enum tui_status ret
92 = set_contents (gdbarch, s, line_or_addr);
c906108c
SS
93
94 if (ret == TUI_FAILURE)
ed8358e9 95 erase_source_content ();
c906108c
SS
96 else
97 {
2ddaf614 98 update_breakpoint_info (nullptr, false);
ed8358e9
TT
99 show_source_content ();
100 update_exec_info ();
101 if (type == SRC_WIN)
c906108c 102 {
51abb421
PA
103 symtab_and_line sal;
104
ed8358e9 105 sal.line = line_or_addr.u.line_no + (content.size () - 2);
52575520 106 sal.symtab = s;
eb822aa6 107 sal.pspace = SYMTAB_PSPACE (s);
51abb421 108 set_current_source_symtab_and_line (sal);
ef5eab5a
MS
109 /* If the focus was in the asm win, put it in the src win if
110 we don't have a split layout. */
e5908723
MS
111 if (tui_win_with_focus () == TUI_DISASM_WIN
112 && tui_current_layout () != SRC_DISASSEM_COMMAND)
ed8358e9 113 tui_set_win_focus_to (this);
c906108c
SS
114 }
115 }
f80bda8e 116}
c906108c
SS
117
118
f80bda8e
AC
119/* Function to ensure that the source and/or disassemly windows
120 reflect the input address. */
c906108c 121void
13274fc3 122tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
c906108c 123{
c774cec6 124 if (addr != 0)
c906108c
SS
125 {
126 struct symtab_and_line sal;
362c05fe 127 struct tui_line_or_address l;
a4b99e53 128
dd1abb8c 129 switch (tui_current_layout ())
c906108c
SS
130 {
131 case DISASSEM_COMMAND:
132 case DISASSEM_DATA_COMMAND:
13274fc3 133 tui_show_disassem (gdbarch, addr);
c906108c
SS
134 break;
135 case SRC_DISASSEM_COMMAND:
13274fc3 136 tui_show_disassem_and_update_source (gdbarch, addr);
c906108c
SS
137 break;
138 default:
c774cec6 139 sal = find_pc_line (addr, 0);
362c05fe
AS
140 l.loa = LOA_LINE;
141 l.u.line_no = sal.line;
bb01dbfc 142 TUI_SRC_WIN->show_symtab_source (gdbarch, sal.symtab, l);
c906108c
SS
143 break;
144 }
145 }
146 else
147 {
ad54d15b 148 for (struct tui_source_window_base *win_info : tui_source_windows ())
c398c3d0 149 win_info->erase_source_content ();
c906108c 150 }
6ba8e26f 151}
c906108c 152
f80bda8e
AC
153/* Function to ensure that the source and/or disassemly windows
154 reflect the input address. */
c906108c 155void
f80bda8e 156tui_update_source_windows_with_line (struct symtab *s, int line)
c906108c 157{
13274fc3 158 struct gdbarch *gdbarch;
84b1e7c7 159 CORE_ADDR pc;
362c05fe 160 struct tui_line_or_address l;
13274fc3
UW
161
162 if (!s)
163 return;
164
eb822aa6 165 gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
13274fc3 166
dd1abb8c 167 switch (tui_current_layout ())
c906108c
SS
168 {
169 case DISASSEM_COMMAND:
170 case DISASSEM_DATA_COMMAND:
84b1e7c7 171 find_line_pc (s, line, &pc);
13274fc3 172 tui_update_source_windows_with_addr (gdbarch, pc);
c906108c
SS
173 break;
174 default:
362c05fe
AS
175 l.loa = LOA_LINE;
176 l.u.line_no = line;
bb01dbfc 177 TUI_SRC_WIN->show_symtab_source (gdbarch, s, l);
dd1abb8c 178 if (tui_current_layout () == SRC_DISASSEM_COMMAND)
84b1e7c7
SC
179 {
180 find_line_pc (s, line, &pc);
13274fc3 181 tui_show_disassem (gdbarch, pc);
84b1e7c7 182 }
c906108c
SS
183 break;
184 }
f80bda8e 185}
c906108c 186
c906108c 187void
e25d2004 188tui_source_window_base::do_erase_source_content (const char *str)
c906108c 189{
6ba8e26f 190 int x_pos;
e25d2004 191 int half_width = (width - 2) / 2;
c906108c 192
c398c3d0 193 content.clear ();
e25d2004 194 if (handle != NULL)
c906108c 195 {
7523da63 196 werase (handle.get ());
e25d2004 197 check_and_display_highlight_if_needed ();
caf0bc4e 198
e25d2004 199 if (strlen (str) >= half_width)
caf0bc4e
TT
200 x_pos = 1;
201 else
e25d2004 202 x_pos = half_width - strlen (str);
7523da63 203 mvwaddstr (handle.get (),
e25d2004 204 (height / 2),
caf0bc4e 205 x_pos,
e25d2004 206 (char *) str);
93858ad3 207
e25d2004 208 refresh_window ();
c906108c 209 }
6ba8e26f 210}
c906108c
SS
211
212
bc712bbf
SC
213/* Redraw the complete line of a source or disassembly window. */
214static void
53e7cdba 215tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
bc712bbf 216{
53e7cdba 217 struct tui_source_element *line;
798e1c30 218 int x;
bc712bbf 219
53e7cdba
TT
220 line = &win_info->content[lineno - 1];
221 if (line->is_exec_point)
7523da63 222 tui_set_reverse_mode (win_info->handle.get (), true);
bc712bbf 223
7523da63 224 wmove (win_info->handle.get (), lineno, TUI_EXECINFO_SIZE);
5d051055 225 tui_puts (line->line.c_str (), win_info->handle.get ());
53e7cdba 226 if (line->is_exec_point)
7523da63 227 tui_set_reverse_mode (win_info->handle.get (), false);
bc712bbf
SC
228
229 /* Clear to end of line but stop before the border. */
7523da63 230 x = getcurx (win_info->handle.get ());
cb2ce893 231 while (x + 1 < win_info->width)
798e1c30 232 {
7523da63
TT
233 waddch (win_info->handle.get (), ' ');
234 x = getcurx (win_info->handle.get ());
798e1c30 235 }
bc712bbf
SC
236}
237
c906108c 238void
0bd27e07 239tui_source_window_base::show_source_content ()
c906108c 240{
2ad52f6f 241 gdb_assert (!content.empty ());
bc712bbf 242
2ad52f6f
TT
243 for (int lineno = 1; lineno <= content.size (); lineno++)
244 tui_show_source_line (this, lineno);
bc712bbf 245
0bd27e07
TT
246 check_and_display_highlight_if_needed ();
247 refresh_window ();
bc712bbf 248}
c906108c 249
5104fe36 250tui_source_window_base::tui_source_window_base (enum tui_win_type type)
398fdd60 251 : tui_win_info (type)
5104fe36
TT
252{
253 gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);
254 start_line_or_addr.loa = LOA_ADDRESS;
255 start_line_or_addr.u.addr = 0;
256}
257
258
5104fe36
TT
259/* See tui-data.h. */
260
5104fe36
TT
261void
262tui_source_window_base::update_tab_width ()
263{
7523da63 264 werase (handle.get ());
3df505f6 265 rerender ();
5104fe36
TT
266}
267
5104fe36 268void
3df505f6 269tui_source_window_base::rerender ()
5104fe36 270{
5104fe36
TT
271 if (!content.empty ())
272 {
273 struct tui_line_or_address line_or_addr;
274 struct symtab_and_line cursal
275 = get_current_source_symtab_and_line ();
276
277 line_or_addr = start_line_or_addr;
017f9828 278 update_source_window (gdbarch, cursal.symtab, line_or_addr);
5104fe36
TT
279 }
280 else if (deprecated_safe_get_selected_frame () != NULL)
281 {
282 struct tui_line_or_address line;
283 struct symtab_and_line cursal
284 = get_current_source_symtab_and_line ();
285 struct frame_info *frame = deprecated_safe_get_selected_frame ();
286 struct gdbarch *gdbarch = get_frame_arch (frame);
287
288 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
289 if (type == SRC_WIN)
290 {
291 line.loa = LOA_LINE;
292 line.u.line_no = cursal.line;
293 }
294 else
295 {
296 line.loa = LOA_ADDRESS;
297 find_line_pc (s, cursal.line, &line.u.addr);
298 }
017f9828 299 update_source_window (gdbarch, s, line);
5104fe36 300 }
3df505f6
TT
301 else
302 erase_source_content ();
5104fe36
TT
303}
304
305/* See tui-data.h. */
306
6f11e682 307void
ad54d15b 308tui_source_window_base::refill ()
6f11e682
TT
309{
310 symtab *s = nullptr;
311
cb2ce893 312 if (type == SRC_WIN)
6f11e682
TT
313 {
314 symtab_and_line cursal = get_current_source_symtab_and_line ();
315 s = (cursal.symtab == NULL
316 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
317 : cursal.symtab);
318 }
319
ed8358e9 320 update_source_window_as_is (gdbarch, s, content[0].line_or_addr);
6f11e682 321}
c906108c 322
f80bda8e 323/* Scroll the source forward or backward horizontally. */
6f11e682 324
c906108c 325void
c3bd716f 326tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 327{
53e7cdba 328 if (!content.empty ())
c906108c 329 {
c3bd716f
TT
330 int offset = horizontal_offset + num_to_scroll;
331 if (offset < 0)
332 offset = 0;
e6e41501 333 horizontal_offset = offset;
ad54d15b 334 refill ();
c906108c 335 }
6ba8e26f 336}
c906108c
SS
337
338
0598af48 339/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
340 line_no. */
341
c906108c 342void
ad54d15b 343tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 344{
02c28df0 345 bool changed = false;
c906108c 346 int i;
c906108c
SS
347
348 i = 0;
53e7cdba 349 while (i < content.size ())
c906108c 350 {
02c28df0 351 bool new_state;
362c05fe 352 struct tui_line_or_address content_loa =
53e7cdba 353 content[i].line_or_addr;
362c05fe
AS
354
355 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
356 gdb_assert (content_loa.loa == LOA_LINE
357 || content_loa.loa == LOA_ADDRESS);
358 if (content_loa.loa == l.loa
359 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
f7952c57 360 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
02c28df0 361 new_state = true;
c906108c 362 else
02c28df0 363 new_state = false;
53e7cdba 364 if (new_state != content[i].is_exec_point)
00b90ae2 365 {
02c28df0 366 changed = true;
53e7cdba 367 content[i].is_exec_point = new_state;
ad54d15b 368 tui_show_source_line (this, i + 1);
00b90ae2 369 }
c906108c
SS
370 i++;
371 }
00b90ae2 372 if (changed)
ad54d15b 373 refill ();
00b90ae2 374}
c906108c 375
0807ab7b
TT
376/* See tui-winsource.h. */
377
c906108c 378void
0807ab7b 379tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 380{
ad54d15b 381 for (tui_source_window_base *win : tui_source_windows ())
c906108c 382 {
2ddaf614
TT
383 if (win->update_breakpoint_info (being_deleted, false))
384 win->update_exec_info ();
c906108c 385 }
00b2bad4 386}
c906108c
SS
387
388
0807ab7b 389/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
390 information for each line.
391
0807ab7b 392 Returns true if something changed and the execution window must be
1cc6d956
MS
393 refreshed. */
394
0807ab7b 395bool
2ddaf614
TT
396tui_source_window_base::update_breakpoint_info
397 (struct breakpoint *being_deleted, bool current_only)
c906108c
SS
398{
399 int i;
0807ab7b 400 bool need_refresh = false;
c906108c 401
2ddaf614 402 for (i = 0; i < content.size (); i++)
00b2bad4 403 {
5b6fe301 404 struct tui_source_element *line;
00b2bad4 405
2ddaf614 406 line = &content[i];
6d012f14 407 if (current_only && !line->is_exec_point)
00b2bad4
SC
408 continue;
409
410 /* Scan each breakpoint to see if the current line has something to
411 do with it. Identify enable/disabled breakpoints as well as
412 those that we already hit. */
0598af48 413 tui_bp_flags mode = 0;
81e6b8eb 414 iterate_over_breakpoints ([&] (breakpoint *bp) -> bool
00b2bad4 415 {
f8eba3c6
TT
416 struct bp_location *loc;
417
362c05fe
AS
418 gdb_assert (line->line_or_addr.loa == LOA_LINE
419 || line->line_or_addr.loa == LOA_ADDRESS);
f8eba3c6 420
0807ab7b 421 if (bp == being_deleted)
81e6b8eb 422 return false;
0807ab7b 423
f8eba3c6
TT
424 for (loc = bp->loc; loc != NULL; loc = loc->next)
425 {
2ddaf614 426 if (location_matches_p (loc, i))
f8eba3c6
TT
427 {
428 if (bp->enable_state == bp_disabled)
429 mode |= TUI_BP_DISABLED;
430 else
431 mode |= TUI_BP_ENABLED;
432 if (bp->hit_count)
433 mode |= TUI_BP_HIT;
434 if (bp->loc->cond)
435 mode |= TUI_BP_CONDITIONAL;
436 if (bp->type == bp_hardware_breakpoint)
437 mode |= TUI_BP_HARDWARE;
438 }
439 }
81e6b8eb
CB
440 return false;
441 });
0598af48 442 if (line->break_mode != mode)
00b2bad4 443 {
0598af48
TT
444 line->break_mode = mode;
445 need_refresh = true;
00b2bad4
SC
446 }
447 }
448 return need_refresh;
449}
c906108c 450
6ba8e26f
AC
451/* Function to initialize the content of the execution info window,
452 based upon the input window which is either the source or
453 disassembly window. */
73fbdc65 454void
5216580d 455tui_source_window_base::update_exec_info ()
c906108c 456{
2ddaf614 457 update_breakpoint_info (nullptr, true);
37a4a131 458 for (int i = 0; i < content.size (); i++)
098f9ed4 459 {
5216580d
TT
460 struct tui_source_element *src_element = &content[i];
461 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
462
463 /* Now update the exec info content based upon the state
464 of each line as indicated by the source content. */
5216580d 465 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
466 if (mode & TUI_BP_HIT)
467 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
468 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
469 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
470
471 if (mode & TUI_BP_ENABLED)
472 element[TUI_BP_BREAK_POS] = '+';
473 else if (mode & TUI_BP_DISABLED)
474 element[TUI_BP_BREAK_POS] = '-';
475
476 if (src_element->is_exec_point)
477 element[TUI_EXEC_POS] = '>';
c906108c 478
7523da63 479 mvwaddstr (handle.get (), i + 1, 1, element);
5216580d 480 }
398fdd60 481 refresh_window ();
f80bda8e 482}
This page took 2.09767 seconds and 4 git commands to generate.