gdb: remove iterate_over_breakpoints function
[deliverable/binutils-gdb.git] / gdb / tui / tui-winsource.c
CommitLineData
f377b406 1/* TUI display source/assembly window.
f33c6cbf 2
3666a048 3 Copyright (C) 1998-2021 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"
35a98237 31#include "safe-ctype.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-win.h"
38#include "tui/tui-wingeneral.h"
39#include "tui/tui-winsource.h"
40#include "tui/tui-source.h"
41#include "tui/tui-disasm.h"
f237f998 42#include "tui/tui-location.h"
6a83354a 43#include "gdb_curses.h"
c906108c 44
1f393769 45/* Function to display the "main" routine. */
c906108c 46void
b4eb2452 47tui_display_main ()
c906108c 48{
3891b65e
TT
49 auto adapter = tui_source_windows ();
50 if (adapter.begin () != adapter.end ())
c906108c 51 {
13274fc3 52 struct gdbarch *gdbarch;
c906108c
SS
53 CORE_ADDR addr;
54
13274fc3 55 tui_get_begin_asm_address (&gdbarch, &addr);
c774cec6 56 if (addr != (CORE_ADDR) 0)
c906108c 57 {
34248c3a 58 struct symtab *s;
c906108c 59
13274fc3 60 tui_update_source_windows_with_addr (gdbarch, addr);
34248c3a 61 s = find_pc_line_symtab (addr);
f237f998 62 tui_location.set_location (s);
c906108c
SS
63 }
64 }
2e17b763 65}
c906108c 66
1df2f9ef 67/* See tui-winsource.h. */
c906108c 68
1df2f9ef 69std::string
9e820dec 70tui_copy_source_line (const char **ptr, int *length)
1df2f9ef
TT
71{
72 const char *lineptr = *ptr;
73
74 /* Init the line with the line number. */
75 std::string result;
76
1df2f9ef
TT
77 int column = 0;
78 char c;
79 do
80 {
81 int skip_bytes;
82
83 c = *lineptr;
84 if (c == '\033' && skip_ansi_escape (lineptr, &skip_bytes))
85 {
86 /* We always have to preserve escapes. */
87 result.append (lineptr, lineptr + skip_bytes);
88 lineptr += skip_bytes;
89 continue;
90 }
517d261d
TT
91 if (c == '\0')
92 break;
1df2f9ef
TT
93
94 ++lineptr;
95 ++column;
96
97 auto process_tab = [&] ()
98 {
99 int max_tab_len = tui_tab_width;
100
101 --column;
102 for (int j = column % max_tab_len;
9e820dec 103 j < max_tab_len;
1df2f9ef 104 column++, j++)
9e820dec 105 result.push_back (' ');
1df2f9ef
TT
106 };
107
1df2f9ef
TT
108 if (c == '\n' || c == '\r' || c == '\0')
109 {
110 /* Nothing. */
111 }
35a98237
TT
112 else if (c == '\t')
113 process_tab ();
114 else if (ISCNTRL (c))
1df2f9ef
TT
115 {
116 result.push_back ('^');
117 result.push_back (c + 0100);
9e820dec 118 ++column;
1df2f9ef
TT
119 }
120 else if (c == 0177)
121 {
122 result.push_back ('^');
123 result.push_back ('?');
9e820dec 124 ++column;
1df2f9ef 125 }
1df2f9ef
TT
126 else
127 result.push_back (c);
128 }
129 while (c != '\0' && c != '\n' && c != '\r');
130
131 if (c == '\r' && *lineptr == '\n')
132 ++lineptr;
133 *ptr = lineptr;
134
9e820dec
TT
135 if (length != nullptr)
136 *length = column;
137
1df2f9ef
TT
138 return result;
139}
140
141void
142tui_source_window_base::style_changed ()
143{
144 if (tui_active && is_visible ())
145 refill ();
146}
c906108c 147
f80bda8e
AC
148/* Function to display source in the source window. This function
149 initializes the horizontal scroll to 0. */
c906108c 150void
017f9828
TT
151tui_source_window_base::update_source_window
152 (struct gdbarch *gdbarch,
9f7540a5 153 const struct symtab_and_line &sal)
c906108c 154{
432b5c40 155 m_horizontal_offset = 0;
9f7540a5 156 update_source_window_as_is (gdbarch, sal);
f80bda8e 157}
c906108c
SS
158
159
f80bda8e
AC
160/* Function to display source in the source/asm window. This function
161 shows the source as specified by the horizontal offset. */
c906108c 162void
ed8358e9
TT
163tui_source_window_base::update_source_window_as_is
164 (struct gdbarch *gdbarch,
9f7540a5 165 const struct symtab_and_line &sal)
c906108c 166{
9f7540a5 167 bool ret = set_contents (gdbarch, sal);
c906108c 168
61c33f10 169 if (!ret)
ed8358e9 170 erase_source_content ();
c906108c
SS
171 else
172 {
2ddaf614 173 update_breakpoint_info (nullptr, false);
ed8358e9
TT
174 show_source_content ();
175 update_exec_info ();
c906108c 176 }
f80bda8e 177}
c906108c
SS
178
179
f80bda8e
AC
180/* Function to ensure that the source and/or disassemly windows
181 reflect the input address. */
c906108c 182void
13274fc3 183tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
c906108c 184{
88180c08 185 struct symtab_and_line sal {};
c774cec6 186 if (addr != 0)
88180c08 187 sal = find_pc_line (addr, 0);
8acfefcc 188
88180c08
TT
189 for (struct tui_source_window_base *win_info : tui_source_windows ())
190 win_info->update_source_window (gdbarch, sal);
6ba8e26f 191}
c906108c 192
5d49bf1b
TT
193/* Function to ensure that the source and/or disassembly windows
194 reflect the symtab and line. */
c906108c 195void
5d49bf1b 196tui_update_source_windows_with_line (struct symtab_and_line sal)
c906108c 197{
4f13c1c0
TT
198 struct gdbarch *gdbarch = nullptr;
199 if (sal.symtab != nullptr)
200 {
201 find_line_pc (sal.symtab, sal.line, &sal.pc);
08feed99 202 gdbarch = SYMTAB_OBJFILE (sal.symtab)->arch ();
4f13c1c0 203 }
13274fc3 204
5d49bf1b
TT
205 for (struct tui_source_window_base *win_info : tui_source_windows ())
206 win_info->update_source_window (gdbarch, sal);
f80bda8e 207}
c906108c 208
c906108c 209void
e25d2004 210tui_source_window_base::do_erase_source_content (const char *str)
c906108c 211{
6ba8e26f 212 int x_pos;
e25d2004 213 int half_width = (width - 2) / 2;
c906108c 214
432b5c40 215 m_content.clear ();
e25d2004 216 if (handle != NULL)
c906108c 217 {
7523da63 218 werase (handle.get ());
e25d2004 219 check_and_display_highlight_if_needed ();
caf0bc4e 220
e25d2004 221 if (strlen (str) >= half_width)
caf0bc4e
TT
222 x_pos = 1;
223 else
e25d2004 224 x_pos = half_width - strlen (str);
7523da63 225 mvwaddstr (handle.get (),
e25d2004 226 (height / 2),
caf0bc4e 227 x_pos,
e25d2004 228 (char *) str);
93858ad3 229
e25d2004 230 refresh_window ();
c906108c 231 }
6ba8e26f 232}
c906108c
SS
233
234
bc712bbf 235/* Redraw the complete line of a source or disassembly window. */
432b5c40
TT
236void
237tui_source_window_base::show_source_line (int lineno)
bc712bbf 238{
53e7cdba 239 struct tui_source_element *line;
bc712bbf 240
9e820dec 241 line = &m_content[lineno];
53e7cdba 242 if (line->is_exec_point)
9e820dec 243 tui_set_reverse_mode (m_pad.get (), true);
bc712bbf 244
9e820dec
TT
245 wmove (m_pad.get (), lineno, 0);
246 tui_puts (line->line.c_str (), m_pad.get ());
53e7cdba 247 if (line->is_exec_point)
9e820dec
TT
248 tui_set_reverse_mode (m_pad.get (), false);
249}
bc712bbf 250
9e820dec
TT
251/* See tui-winsource.h. */
252
253void
22cc388e 254tui_source_window_base::refresh_window ()
9e820dec 255{
55195361
HD
256 /* tui_win_info::refresh_window would draw the empty background window to
257 the screen, potentially creating a flicker. */
258 wnoutrefresh (handle.get ());
22cc388e 259
9e820dec
TT
260 int pad_width = std::max (m_max_length, width);
261 int left_margin = 1 + TUI_EXECINFO_SIZE + extra_margin ();
262 int view_width = width - left_margin - 1;
263 int pad_x = std::min (pad_width - view_width, m_horizontal_offset);
264 /* Ensure that an equal number of scrolls will work if the user
265 scrolled beyond where we clip. */
266 m_horizontal_offset = pad_x;
267 prefresh (m_pad.get (), 0, pad_x, y + 1, x + left_margin,
b5ff370e 268 y + m_content.size (), x + left_margin + view_width - 1);
bc712bbf
SC
269}
270
c906108c 271void
0bd27e07 272tui_source_window_base::show_source_content ()
c906108c 273{
432b5c40 274 gdb_assert (!m_content.empty ());
bc712bbf 275
9e820dec
TT
276 check_and_display_highlight_if_needed ();
277
278 int pad_width = std::max (m_max_length, width);
b5ff370e
HD
279 if (m_pad == nullptr || pad_width > getmaxx (m_pad.get ())
280 || m_content.size () > getmaxy (m_pad.get ()))
9e820dec
TT
281 m_pad.reset (newpad (m_content.size (), pad_width));
282
283 werase (m_pad.get ());
284 for (int lineno = 0; lineno < m_content.size (); lineno++)
432b5c40 285 show_source_line (lineno);
bc712bbf 286
0bd27e07 287 refresh_window ();
bc712bbf 288}
c906108c 289
fdb01f0c 290tui_source_window_base::tui_source_window_base ()
5104fe36 291{
432b5c40
TT
292 m_start_line_or_addr.loa = LOA_ADDRESS;
293 m_start_line_or_addr.u.addr = 0;
1df2f9ef
TT
294
295 gdb::observers::source_styling_changed.attach
296 (std::bind (&tui_source_window::style_changed, this),
c90e7d63 297 m_observable, "tui-winsource");
5104fe36
TT
298}
299
1df2f9ef
TT
300tui_source_window_base::~tui_source_window_base ()
301{
302 gdb::observers::source_styling_changed.detach (m_observable);
303}
5104fe36 304
5104fe36
TT
305/* See tui-data.h. */
306
5104fe36
TT
307void
308tui_source_window_base::update_tab_width ()
309{
7523da63 310 werase (handle.get ());
3df505f6 311 rerender ();
5104fe36
TT
312}
313
5104fe36 314void
3df505f6 315tui_source_window_base::rerender ()
5104fe36 316{
432b5c40 317 if (!m_content.empty ())
5104fe36 318 {
5104fe36
TT
319 struct symtab_and_line cursal
320 = get_current_source_symtab_and_line ();
321
432b5c40
TT
322 if (m_start_line_or_addr.loa == LOA_LINE)
323 cursal.line = m_start_line_or_addr.u.line_no;
9f7540a5 324 else
432b5c40
TT
325 cursal.pc = m_start_line_or_addr.u.addr;
326 update_source_window (m_gdbarch, cursal);
5104fe36
TT
327 }
328 else if (deprecated_safe_get_selected_frame () != NULL)
329 {
5104fe36
TT
330 struct symtab_and_line cursal
331 = get_current_source_symtab_and_line ();
332 struct frame_info *frame = deprecated_safe_get_selected_frame ();
333 struct gdbarch *gdbarch = get_frame_arch (frame);
334
335 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
fdb01f0c 336 if (this != TUI_SRC_WIN)
9f7540a5
TT
337 find_line_pc (s, cursal.line, &cursal.pc);
338 update_source_window (gdbarch, cursal);
5104fe36 339 }
3df505f6
TT
340 else
341 erase_source_content ();
5104fe36
TT
342}
343
344/* See tui-data.h. */
345
6f11e682 346void
ad54d15b 347tui_source_window_base::refill ()
6f11e682 348{
9f7540a5 349 symtab_and_line sal {};
6f11e682 350
fdb01f0c 351 if (this == TUI_SRC_WIN)
6f11e682 352 {
9f7540a5
TT
353 sal = get_current_source_symtab_and_line ();
354 if (sal.symtab == NULL)
7c392d1d
TT
355 {
356 struct frame_info *fi = deprecated_safe_get_selected_frame ();
357 if (fi != nullptr)
358 sal = find_pc_line (get_frame_pc (fi), 0);
359 }
6f11e682
TT
360 }
361
9f7540a5
TT
362 if (sal.pspace == nullptr)
363 sal.pspace = current_program_space;
364
432b5c40
TT
365 if (m_start_line_or_addr.loa == LOA_LINE)
366 sal.line = m_start_line_or_addr.u.line_no;
9f7540a5 367 else
432b5c40 368 sal.pc = m_start_line_or_addr.u.addr;
9f7540a5 369
432b5c40 370 update_source_window_as_is (m_gdbarch, sal);
6f11e682 371}
c906108c 372
f80bda8e 373/* Scroll the source forward or backward horizontally. */
6f11e682 374
c906108c 375void
c3bd716f 376tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 377{
432b5c40 378 if (!m_content.empty ())
c906108c 379 {
432b5c40 380 int offset = m_horizontal_offset + num_to_scroll;
c3bd716f
TT
381 if (offset < 0)
382 offset = 0;
432b5c40 383 m_horizontal_offset = offset;
22cc388e 384 refresh_window ();
c906108c 385 }
6ba8e26f 386}
c906108c
SS
387
388
0598af48 389/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
390 line_no. */
391
c906108c 392void
ad54d15b 393tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 394{
02c28df0 395 bool changed = false;
c906108c 396 int i;
c906108c
SS
397
398 i = 0;
432b5c40 399 while (i < m_content.size ())
c906108c 400 {
02c28df0 401 bool new_state;
362c05fe 402 struct tui_line_or_address content_loa =
432b5c40 403 m_content[i].line_or_addr;
362c05fe 404
362c05fe
AS
405 if (content_loa.loa == l.loa
406 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
dda83cd7
SM
407 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
408 new_state = true;
c906108c 409 else
02c28df0 410 new_state = false;
432b5c40 411 if (new_state != m_content[i].is_exec_point)
dda83cd7
SM
412 {
413 changed = true;
414 m_content[i].is_exec_point = new_state;
415 }
c906108c
SS
416 i++;
417 }
00b90ae2 418 if (changed)
ad54d15b 419 refill ();
00b90ae2 420}
c906108c 421
0807ab7b
TT
422/* See tui-winsource.h. */
423
c906108c 424void
0807ab7b 425tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 426{
ad54d15b 427 for (tui_source_window_base *win : tui_source_windows ())
c906108c 428 {
2ddaf614
TT
429 if (win->update_breakpoint_info (being_deleted, false))
430 win->update_exec_info ();
c906108c 431 }
00b2bad4 432}
c906108c
SS
433
434
0807ab7b 435/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
436 information for each line.
437
0807ab7b 438 Returns true if something changed and the execution window must be
1cc6d956
MS
439 refreshed. */
440
0807ab7b 441bool
2ddaf614
TT
442tui_source_window_base::update_breakpoint_info
443 (struct breakpoint *being_deleted, bool current_only)
c906108c
SS
444{
445 int i;
0807ab7b 446 bool need_refresh = false;
c906108c 447
432b5c40 448 for (i = 0; i < m_content.size (); i++)
00b2bad4 449 {
5b6fe301 450 struct tui_source_element *line;
00b2bad4 451
432b5c40 452 line = &m_content[i];
6d012f14 453 if (current_only && !line->is_exec_point)
dda83cd7 454 continue;
00b2bad4
SC
455
456 /* Scan each breakpoint to see if the current line has something to
dda83cd7
SM
457 do with it. Identify enable/disabled breakpoints as well as
458 those that we already hit. */
0598af48 459 tui_bp_flags mode = 0;
240edef6 460 for (breakpoint *bp : all_breakpoints ())
dda83cd7 461 {
0807ab7b 462 if (bp == being_deleted)
81e6b8eb 463 return false;
0807ab7b 464
40cb8ca5 465 for (bp_location *loc : bp->locations ())
f8eba3c6 466 {
2ddaf614 467 if (location_matches_p (loc, i))
f8eba3c6
TT
468 {
469 if (bp->enable_state == bp_disabled)
470 mode |= TUI_BP_DISABLED;
471 else
472 mode |= TUI_BP_ENABLED;
473 if (bp->hit_count)
474 mode |= TUI_BP_HIT;
475 if (bp->loc->cond)
476 mode |= TUI_BP_CONDITIONAL;
477 if (bp->type == bp_hardware_breakpoint)
478 mode |= TUI_BP_HARDWARE;
479 }
480 }
81e6b8eb 481 return false;
240edef6
SM
482 }
483
0598af48 484 if (line->break_mode != mode)
dda83cd7
SM
485 {
486 line->break_mode = mode;
487 need_refresh = true;
488 }
00b2bad4
SC
489 }
490 return need_refresh;
491}
c906108c 492
6ba8e26f
AC
493/* Function to initialize the content of the execution info window,
494 based upon the input window which is either the source or
495 disassembly window. */
73fbdc65 496void
5216580d 497tui_source_window_base::update_exec_info ()
c906108c 498{
2ddaf614 499 update_breakpoint_info (nullptr, true);
432b5c40 500 for (int i = 0; i < m_content.size (); i++)
098f9ed4 501 {
432b5c40 502 struct tui_source_element *src_element = &m_content[i];
5216580d 503 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
504
505 /* Now update the exec info content based upon the state
506 of each line as indicated by the source content. */
5216580d 507 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
508 if (mode & TUI_BP_HIT)
509 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
510 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
511 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
512
513 if (mode & TUI_BP_ENABLED)
514 element[TUI_BP_BREAK_POS] = '+';
515 else if (mode & TUI_BP_DISABLED)
516 element[TUI_BP_BREAK_POS] = '-';
517
518 if (src_element->is_exec_point)
519 element[TUI_EXEC_POS] = '>';
c906108c 520
7523da63 521 mvwaddstr (handle.get (), i + 1, 1, element);
9e820dec
TT
522
523 show_line_number (i);
5216580d 524 }
398fdd60 525 refresh_window ();
f80bda8e 526}
This page took 2.813542 seconds and 4 git commands to generate.