]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-winsource.c
Change tui_update_breakpoint_info to be a method
[thirdparty/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{
22940a24 91 enum tui_status ret;
c906108c 92
ed8358e9
TT
93 if (type == SRC_WIN)
94 ret = tui_set_source_content (this, s, line_or_addr.u.line_no);
c906108c 95 else
ed8358e9 96 ret = tui_set_disassem_content (this, gdbarch, line_or_addr.u.addr);
c906108c
SS
97
98 if (ret == TUI_FAILURE)
ed8358e9 99 erase_source_content ();
c906108c
SS
100 else
101 {
2ddaf614 102 update_breakpoint_info (nullptr, false);
ed8358e9
TT
103 show_source_content ();
104 update_exec_info ();
105 if (type == SRC_WIN)
c906108c 106 {
51abb421
PA
107 symtab_and_line sal;
108
ed8358e9 109 sal.line = line_or_addr.u.line_no + (content.size () - 2);
52575520 110 sal.symtab = s;
eb822aa6 111 sal.pspace = SYMTAB_PSPACE (s);
51abb421 112 set_current_source_symtab_and_line (sal);
ef5eab5a
MS
113 /* If the focus was in the asm win, put it in the src win if
114 we don't have a split layout. */
e5908723
MS
115 if (tui_win_with_focus () == TUI_DISASM_WIN
116 && tui_current_layout () != SRC_DISASSEM_COMMAND)
ed8358e9 117 tui_set_win_focus_to (this);
c906108c
SS
118 }
119 }
f80bda8e 120}
c906108c
SS
121
122
f80bda8e
AC
123/* Function to ensure that the source and/or disassemly windows
124 reflect the input address. */
c906108c 125void
13274fc3 126tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
c906108c 127{
c774cec6 128 if (addr != 0)
c906108c
SS
129 {
130 struct symtab_and_line sal;
362c05fe 131 struct tui_line_or_address l;
a4b99e53 132
dd1abb8c 133 switch (tui_current_layout ())
c906108c
SS
134 {
135 case DISASSEM_COMMAND:
136 case DISASSEM_DATA_COMMAND:
13274fc3 137 tui_show_disassem (gdbarch, addr);
c906108c
SS
138 break;
139 case SRC_DISASSEM_COMMAND:
13274fc3 140 tui_show_disassem_and_update_source (gdbarch, addr);
c906108c
SS
141 break;
142 default:
c774cec6 143 sal = find_pc_line (addr, 0);
362c05fe
AS
144 l.loa = LOA_LINE;
145 l.u.line_no = sal.line;
20149b6b 146 tui_show_symtab_source (TUI_SRC_WIN, gdbarch, sal.symtab, l);
c906108c
SS
147 break;
148 }
149 }
150 else
151 {
ad54d15b 152 for (struct tui_source_window_base *win_info : tui_source_windows ())
c398c3d0 153 win_info->erase_source_content ();
c906108c 154 }
6ba8e26f 155}
c906108c 156
f80bda8e
AC
157/* Function to ensure that the source and/or disassemly windows
158 reflect the input address. */
c906108c 159void
f80bda8e 160tui_update_source_windows_with_line (struct symtab *s, int line)
c906108c 161{
13274fc3 162 struct gdbarch *gdbarch;
84b1e7c7 163 CORE_ADDR pc;
362c05fe 164 struct tui_line_or_address l;
13274fc3
UW
165
166 if (!s)
167 return;
168
eb822aa6 169 gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
13274fc3 170
dd1abb8c 171 switch (tui_current_layout ())
c906108c
SS
172 {
173 case DISASSEM_COMMAND:
174 case DISASSEM_DATA_COMMAND:
84b1e7c7 175 find_line_pc (s, line, &pc);
13274fc3 176 tui_update_source_windows_with_addr (gdbarch, pc);
c906108c
SS
177 break;
178 default:
362c05fe
AS
179 l.loa = LOA_LINE;
180 l.u.line_no = line;
20149b6b 181 tui_show_symtab_source (TUI_SRC_WIN, gdbarch, s, l);
dd1abb8c 182 if (tui_current_layout () == SRC_DISASSEM_COMMAND)
84b1e7c7
SC
183 {
184 find_line_pc (s, line, &pc);
13274fc3 185 tui_show_disassem (gdbarch, pc);
84b1e7c7 186 }
c906108c
SS
187 break;
188 }
f80bda8e 189}
c906108c 190
c906108c 191void
e25d2004 192tui_source_window_base::do_erase_source_content (const char *str)
c906108c 193{
6ba8e26f 194 int x_pos;
e25d2004 195 int half_width = (width - 2) / 2;
c906108c 196
c398c3d0 197 content.clear ();
e25d2004 198 if (handle != NULL)
c906108c 199 {
e25d2004
TT
200 werase (handle);
201 check_and_display_highlight_if_needed ();
caf0bc4e 202
e25d2004 203 if (strlen (str) >= half_width)
caf0bc4e
TT
204 x_pos = 1;
205 else
e25d2004
TT
206 x_pos = half_width - strlen (str);
207 mvwaddstr (handle,
208 (height / 2),
caf0bc4e 209 x_pos,
e25d2004 210 (char *) str);
93858ad3 211
e25d2004 212 refresh_window ();
93858ad3 213
e25d2004
TT
214 werase (execution_info->handle);
215 execution_info->refresh_window ();
c906108c 216 }
6ba8e26f 217}
c906108c
SS
218
219
bc712bbf
SC
220/* Redraw the complete line of a source or disassembly window. */
221static void
53e7cdba 222tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
bc712bbf 223{
53e7cdba 224 struct tui_source_element *line;
798e1c30 225 int x;
bc712bbf 226
53e7cdba
TT
227 line = &win_info->content[lineno - 1];
228 if (line->is_exec_point)
cb2ce893 229 tui_set_reverse_mode (win_info->handle, true);
bc712bbf 230
cb2ce893 231 wmove (win_info->handle, lineno, 1);
53e7cdba 232 tui_puts (line->line,
cb2ce893 233 win_info->handle);
53e7cdba 234 if (line->is_exec_point)
cb2ce893 235 tui_set_reverse_mode (win_info->handle, false);
bc712bbf
SC
236
237 /* Clear to end of line but stop before the border. */
cb2ce893
TT
238 x = getcurx (win_info->handle);
239 while (x + 1 < win_info->width)
798e1c30 240 {
cb2ce893
TT
241 waddch (win_info->handle, ' ');
242 x = getcurx (win_info->handle);
798e1c30 243 }
bc712bbf
SC
244}
245
c906108c 246void
0bd27e07 247tui_source_window_base::show_source_content ()
c906108c 248{
0bd27e07 249 if (!content.empty ())
c906108c 250 {
bc712bbf
SC
251 int lineno;
252
0bd27e07
TT
253 for (lineno = 1; lineno <= content.size (); lineno++)
254 tui_show_source_line (this, lineno);
c906108c 255 }
bc712bbf 256 else
e25d2004 257 erase_source_content ();
bc712bbf 258
0bd27e07
TT
259 check_and_display_highlight_if_needed ();
260 refresh_window ();
bc712bbf 261}
c906108c 262
ad54d15b 263/* See tui-data.h. */
6f11e682 264
5104fe36
TT
265void
266tui_source_window_base::clear_detail ()
267{
268 gdbarch = NULL;
269 start_line_or_addr.loa = LOA_ADDRESS;
270 start_line_or_addr.u.addr = 0;
271 horizontal_offset = 0;
272}
273
274tui_source_window_base::tui_source_window_base (enum tui_win_type type)
275 : tui_win_info (type),
276 execution_info (new tui_exec_info_window ())
277{
278 gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);
279 start_line_or_addr.loa = LOA_ADDRESS;
280 start_line_or_addr.u.addr = 0;
281}
282
283
284tui_source_window_base::~tui_source_window_base ()
285{
286 xfree (fullname);
287 delete execution_info;
288}
289
290void
ee556432
TT
291tui_source_window_base::resize (int height, int width,
292 int origin_x, int origin_y)
5104fe36 293{
ee556432
TT
294 tui_gen_win_info::resize (height, width - 3,
295 origin_x + 3, origin_y);
296 execution_info->resize (height, 3, origin_x, origin_y);
5104fe36
TT
297}
298
299/* See tui-data.h. */
300
301void
302tui_source_window_base::refresh_all ()
303{
0bd27e07 304 show_source_content ();
b4ef5aeb 305 check_and_display_highlight_if_needed ();
7ba913dc 306 update_exec_info ();
5104fe36
TT
307}
308
309/* See tui-data.h. */
310
311void
312tui_source_window_base::update_tab_width ()
313{
3df505f6
TT
314 werase (handle);
315 rerender ();
5104fe36
TT
316}
317
5104fe36 318void
3df505f6 319tui_source_window_base::rerender ()
5104fe36 320{
5104fe36
TT
321 if (!content.empty ())
322 {
323 struct tui_line_or_address line_or_addr;
324 struct symtab_and_line cursal
325 = get_current_source_symtab_and_line ();
326
327 line_or_addr = start_line_or_addr;
017f9828 328 update_source_window (gdbarch, cursal.symtab, line_or_addr);
5104fe36
TT
329 }
330 else if (deprecated_safe_get_selected_frame () != NULL)
331 {
332 struct tui_line_or_address line;
333 struct symtab_and_line cursal
334 = get_current_source_symtab_and_line ();
335 struct frame_info *frame = deprecated_safe_get_selected_frame ();
336 struct gdbarch *gdbarch = get_frame_arch (frame);
337
338 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
339 if (type == SRC_WIN)
340 {
341 line.loa = LOA_LINE;
342 line.u.line_no = cursal.line;
343 }
344 else
345 {
346 line.loa = LOA_ADDRESS;
347 find_line_pc (s, cursal.line, &line.u.addr);
348 }
017f9828 349 update_source_window (gdbarch, s, line);
5104fe36 350 }
3df505f6
TT
351 else
352 erase_source_content ();
5104fe36
TT
353}
354
355/* See tui-data.h. */
356
357void
358tui_source_window_base::make_visible (bool visible)
359{
360 execution_info->make_visible (visible);
361 tui_win_info::make_visible (visible);
362}
363
364/* See tui-data.h. */
365
366void
367tui_source_window_base::refresh_window ()
368{
369 execution_info->refresh_window ();
370 tui_win_info::refresh_window ();
371}
372
373/* See tui-data.h. */
374
6f11e682 375void
ad54d15b 376tui_source_window_base::refill ()
6f11e682
TT
377{
378 symtab *s = nullptr;
379
cb2ce893 380 if (type == SRC_WIN)
6f11e682
TT
381 {
382 symtab_and_line cursal = get_current_source_symtab_and_line ();
383 s = (cursal.symtab == NULL
384 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
385 : cursal.symtab);
386 }
387
ed8358e9 388 update_source_window_as_is (gdbarch, s, content[0].line_or_addr);
6f11e682 389}
c906108c 390
f80bda8e 391/* Scroll the source forward or backward horizontally. */
6f11e682 392
c906108c 393void
c3bd716f 394tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 395{
53e7cdba 396 if (!content.empty ())
c906108c 397 {
c3bd716f
TT
398 int offset = horizontal_offset + num_to_scroll;
399 if (offset < 0)
400 offset = 0;
e6e41501 401 horizontal_offset = offset;
ad54d15b 402 refill ();
c906108c 403 }
6ba8e26f 404}
c906108c
SS
405
406
0598af48 407/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
408 line_no. */
409
c906108c 410void
ad54d15b 411tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 412{
02c28df0 413 bool changed = false;
c906108c 414 int i;
c906108c
SS
415
416 i = 0;
53e7cdba 417 while (i < content.size ())
c906108c 418 {
02c28df0 419 bool new_state;
362c05fe 420 struct tui_line_or_address content_loa =
53e7cdba 421 content[i].line_or_addr;
362c05fe
AS
422
423 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
424 gdb_assert (content_loa.loa == LOA_LINE
425 || content_loa.loa == LOA_ADDRESS);
426 if (content_loa.loa == l.loa
427 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
f7952c57 428 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
02c28df0 429 new_state = true;
c906108c 430 else
02c28df0 431 new_state = false;
53e7cdba 432 if (new_state != content[i].is_exec_point)
00b90ae2 433 {
02c28df0 434 changed = true;
53e7cdba 435 content[i].is_exec_point = new_state;
ad54d15b 436 tui_show_source_line (this, i + 1);
00b90ae2 437 }
c906108c
SS
438 i++;
439 }
00b90ae2 440 if (changed)
ad54d15b 441 refill ();
00b90ae2 442}
c906108c 443
0807ab7b
TT
444/* See tui-winsource.h. */
445
c906108c 446void
0807ab7b 447tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 448{
ad54d15b 449 for (tui_source_window_base *win : tui_source_windows ())
c906108c 450 {
2ddaf614
TT
451 if (win->update_breakpoint_info (being_deleted, false))
452 win->update_exec_info ();
c906108c 453 }
00b2bad4 454}
c906108c
SS
455
456
0807ab7b 457/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
458 information for each line.
459
0807ab7b 460 Returns true if something changed and the execution window must be
1cc6d956
MS
461 refreshed. */
462
0807ab7b 463bool
2ddaf614
TT
464tui_source_window_base::update_breakpoint_info
465 (struct breakpoint *being_deleted, bool current_only)
c906108c
SS
466{
467 int i;
0807ab7b 468 bool need_refresh = false;
c906108c 469
2ddaf614 470 for (i = 0; i < content.size (); i++)
00b2bad4
SC
471 {
472 struct breakpoint *bp;
473 extern struct breakpoint *breakpoint_chain;
5b6fe301 474 struct tui_source_element *line;
00b2bad4 475
2ddaf614 476 line = &content[i];
6d012f14 477 if (current_only && !line->is_exec_point)
00b2bad4
SC
478 continue;
479
480 /* Scan each breakpoint to see if the current line has something to
481 do with it. Identify enable/disabled breakpoints as well as
482 those that we already hit. */
0598af48 483 tui_bp_flags mode = 0;
00b2bad4 484 for (bp = breakpoint_chain;
cafb3438 485 bp != NULL;
00b2bad4
SC
486 bp = bp->next)
487 {
f8eba3c6
TT
488 struct bp_location *loc;
489
362c05fe
AS
490 gdb_assert (line->line_or_addr.loa == LOA_LINE
491 || line->line_or_addr.loa == LOA_ADDRESS);
f8eba3c6 492
0807ab7b
TT
493 if (bp == being_deleted)
494 continue;
495
f8eba3c6
TT
496 for (loc = bp->loc; loc != NULL; loc = loc->next)
497 {
2ddaf614 498 if (location_matches_p (loc, i))
f8eba3c6
TT
499 {
500 if (bp->enable_state == bp_disabled)
501 mode |= TUI_BP_DISABLED;
502 else
503 mode |= TUI_BP_ENABLED;
504 if (bp->hit_count)
505 mode |= TUI_BP_HIT;
506 if (bp->loc->cond)
507 mode |= TUI_BP_CONDITIONAL;
508 if (bp->type == bp_hardware_breakpoint)
509 mode |= TUI_BP_HARDWARE;
510 }
511 }
00b2bad4 512 }
0598af48 513 if (line->break_mode != mode)
00b2bad4 514 {
0598af48
TT
515 line->break_mode = mode;
516 need_refresh = true;
00b2bad4
SC
517 }
518 }
519 return need_refresh;
520}
c906108c 521
6ba8e26f
AC
522/* Function to initialize the content of the execution info window,
523 based upon the input window which is either the source or
524 disassembly window. */
73fbdc65 525void
5216580d 526tui_source_window_base::update_exec_info ()
c906108c 527{
5216580d 528 werase (execution_info->handle);
2ddaf614 529 update_breakpoint_info (nullptr, true);
37a4a131 530 for (int i = 0; i < content.size (); i++)
098f9ed4 531 {
5216580d
TT
532 struct tui_source_element *src_element = &content[i];
533 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
534
535 /* Now update the exec info content based upon the state
536 of each line as indicated by the source content. */
5216580d 537 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
538 if (mode & TUI_BP_HIT)
539 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
540 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
541 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
542
543 if (mode & TUI_BP_ENABLED)
544 element[TUI_BP_BREAK_POS] = '+';
545 else if (mode & TUI_BP_DISABLED)
546 element[TUI_BP_BREAK_POS] = '-';
547
548 if (src_element->is_exec_point)
549 element[TUI_EXEC_POS] = '>';
c906108c 550
5216580d
TT
551 mvwaddstr (execution_info->handle, i + 1, 0, element);
552 }
553 execution_info->refresh_window ();
f80bda8e 554}