Remove tui_clear_source_windows_detail
[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 {
e25d2004
TT
196 werase (handle);
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
TT
202 x_pos = half_width - strlen (str);
203 mvwaddstr (handle,
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)
cb2ce893 222 tui_set_reverse_mode (win_info->handle, true);
bc712bbf 223
398fdd60 224 wmove (win_info->handle, lineno, TUI_EXECINFO_SIZE);
53e7cdba 225 tui_puts (line->line,
cb2ce893 226 win_info->handle);
53e7cdba 227 if (line->is_exec_point)
cb2ce893 228 tui_set_reverse_mode (win_info->handle, false);
bc712bbf
SC
229
230 /* Clear to end of line but stop before the border. */
cb2ce893
TT
231 x = getcurx (win_info->handle);
232 while (x + 1 < win_info->width)
798e1c30 233 {
cb2ce893
TT
234 waddch (win_info->handle, ' ');
235 x = getcurx (win_info->handle);
798e1c30 236 }
bc712bbf
SC
237}
238
c906108c 239void
0bd27e07 240tui_source_window_base::show_source_content ()
c906108c 241{
0bd27e07 242 if (!content.empty ())
c906108c 243 {
bc712bbf
SC
244 int lineno;
245
0bd27e07
TT
246 for (lineno = 1; lineno <= content.size (); lineno++)
247 tui_show_source_line (this, lineno);
c906108c 248 }
bc712bbf 249 else
e25d2004 250 erase_source_content ();
bc712bbf 251
0bd27e07
TT
252 check_and_display_highlight_if_needed ();
253 refresh_window ();
bc712bbf 254}
c906108c 255
5104fe36 256tui_source_window_base::tui_source_window_base (enum tui_win_type type)
398fdd60 257 : tui_win_info (type)
5104fe36
TT
258{
259 gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);
260 start_line_or_addr.loa = LOA_ADDRESS;
261 start_line_or_addr.u.addr = 0;
262}
263
264
265tui_source_window_base::~tui_source_window_base ()
266{
267 xfree (fullname);
5104fe36
TT
268}
269
5104fe36
TT
270/* See tui-data.h. */
271
5104fe36
TT
272void
273tui_source_window_base::update_tab_width ()
274{
3df505f6
TT
275 werase (handle);
276 rerender ();
5104fe36
TT
277}
278
5104fe36 279void
3df505f6 280tui_source_window_base::rerender ()
5104fe36 281{
5104fe36
TT
282 if (!content.empty ())
283 {
284 struct tui_line_or_address line_or_addr;
285 struct symtab_and_line cursal
286 = get_current_source_symtab_and_line ();
287
288 line_or_addr = start_line_or_addr;
017f9828 289 update_source_window (gdbarch, cursal.symtab, line_or_addr);
5104fe36
TT
290 }
291 else if (deprecated_safe_get_selected_frame () != NULL)
292 {
293 struct tui_line_or_address line;
294 struct symtab_and_line cursal
295 = get_current_source_symtab_and_line ();
296 struct frame_info *frame = deprecated_safe_get_selected_frame ();
297 struct gdbarch *gdbarch = get_frame_arch (frame);
298
299 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
300 if (type == SRC_WIN)
301 {
302 line.loa = LOA_LINE;
303 line.u.line_no = cursal.line;
304 }
305 else
306 {
307 line.loa = LOA_ADDRESS;
308 find_line_pc (s, cursal.line, &line.u.addr);
309 }
017f9828 310 update_source_window (gdbarch, s, line);
5104fe36 311 }
3df505f6
TT
312 else
313 erase_source_content ();
5104fe36
TT
314}
315
316/* See tui-data.h. */
317
6f11e682 318void
ad54d15b 319tui_source_window_base::refill ()
6f11e682
TT
320{
321 symtab *s = nullptr;
322
cb2ce893 323 if (type == SRC_WIN)
6f11e682
TT
324 {
325 symtab_and_line cursal = get_current_source_symtab_and_line ();
326 s = (cursal.symtab == NULL
327 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
328 : cursal.symtab);
329 }
330
ed8358e9 331 update_source_window_as_is (gdbarch, s, content[0].line_or_addr);
6f11e682 332}
c906108c 333
f80bda8e 334/* Scroll the source forward or backward horizontally. */
6f11e682 335
c906108c 336void
c3bd716f 337tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 338{
53e7cdba 339 if (!content.empty ())
c906108c 340 {
c3bd716f
TT
341 int offset = horizontal_offset + num_to_scroll;
342 if (offset < 0)
343 offset = 0;
e6e41501 344 horizontal_offset = offset;
ad54d15b 345 refill ();
c906108c 346 }
6ba8e26f 347}
c906108c
SS
348
349
0598af48 350/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
351 line_no. */
352
c906108c 353void
ad54d15b 354tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 355{
02c28df0 356 bool changed = false;
c906108c 357 int i;
c906108c
SS
358
359 i = 0;
53e7cdba 360 while (i < content.size ())
c906108c 361 {
02c28df0 362 bool new_state;
362c05fe 363 struct tui_line_or_address content_loa =
53e7cdba 364 content[i].line_or_addr;
362c05fe
AS
365
366 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
367 gdb_assert (content_loa.loa == LOA_LINE
368 || content_loa.loa == LOA_ADDRESS);
369 if (content_loa.loa == l.loa
370 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
f7952c57 371 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
02c28df0 372 new_state = true;
c906108c 373 else
02c28df0 374 new_state = false;
53e7cdba 375 if (new_state != content[i].is_exec_point)
00b90ae2 376 {
02c28df0 377 changed = true;
53e7cdba 378 content[i].is_exec_point = new_state;
ad54d15b 379 tui_show_source_line (this, i + 1);
00b90ae2 380 }
c906108c
SS
381 i++;
382 }
00b90ae2 383 if (changed)
ad54d15b 384 refill ();
00b90ae2 385}
c906108c 386
0807ab7b
TT
387/* See tui-winsource.h. */
388
c906108c 389void
0807ab7b 390tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 391{
ad54d15b 392 for (tui_source_window_base *win : tui_source_windows ())
c906108c 393 {
2ddaf614
TT
394 if (win->update_breakpoint_info (being_deleted, false))
395 win->update_exec_info ();
c906108c 396 }
00b2bad4 397}
c906108c
SS
398
399
0807ab7b 400/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
401 information for each line.
402
0807ab7b 403 Returns true if something changed and the execution window must be
1cc6d956
MS
404 refreshed. */
405
0807ab7b 406bool
2ddaf614
TT
407tui_source_window_base::update_breakpoint_info
408 (struct breakpoint *being_deleted, bool current_only)
c906108c
SS
409{
410 int i;
0807ab7b 411 bool need_refresh = false;
c906108c 412
2ddaf614 413 for (i = 0; i < content.size (); i++)
00b2bad4
SC
414 {
415 struct breakpoint *bp;
416 extern struct breakpoint *breakpoint_chain;
5b6fe301 417 struct tui_source_element *line;
00b2bad4 418
2ddaf614 419 line = &content[i];
6d012f14 420 if (current_only && !line->is_exec_point)
00b2bad4
SC
421 continue;
422
423 /* Scan each breakpoint to see if the current line has something to
424 do with it. Identify enable/disabled breakpoints as well as
425 those that we already hit. */
0598af48 426 tui_bp_flags mode = 0;
00b2bad4 427 for (bp = breakpoint_chain;
cafb3438 428 bp != NULL;
00b2bad4
SC
429 bp = bp->next)
430 {
f8eba3c6
TT
431 struct bp_location *loc;
432
362c05fe
AS
433 gdb_assert (line->line_or_addr.loa == LOA_LINE
434 || line->line_or_addr.loa == LOA_ADDRESS);
f8eba3c6 435
0807ab7b
TT
436 if (bp == being_deleted)
437 continue;
438
f8eba3c6
TT
439 for (loc = bp->loc; loc != NULL; loc = loc->next)
440 {
2ddaf614 441 if (location_matches_p (loc, i))
f8eba3c6
TT
442 {
443 if (bp->enable_state == bp_disabled)
444 mode |= TUI_BP_DISABLED;
445 else
446 mode |= TUI_BP_ENABLED;
447 if (bp->hit_count)
448 mode |= TUI_BP_HIT;
449 if (bp->loc->cond)
450 mode |= TUI_BP_CONDITIONAL;
451 if (bp->type == bp_hardware_breakpoint)
452 mode |= TUI_BP_HARDWARE;
453 }
454 }
00b2bad4 455 }
0598af48 456 if (line->break_mode != mode)
00b2bad4 457 {
0598af48
TT
458 line->break_mode = mode;
459 need_refresh = true;
00b2bad4
SC
460 }
461 }
462 return need_refresh;
463}
c906108c 464
6ba8e26f
AC
465/* Function to initialize the content of the execution info window,
466 based upon the input window which is either the source or
467 disassembly window. */
73fbdc65 468void
5216580d 469tui_source_window_base::update_exec_info ()
c906108c 470{
2ddaf614 471 update_breakpoint_info (nullptr, true);
37a4a131 472 for (int i = 0; i < content.size (); i++)
098f9ed4 473 {
5216580d
TT
474 struct tui_source_element *src_element = &content[i];
475 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
476
477 /* Now update the exec info content based upon the state
478 of each line as indicated by the source content. */
5216580d 479 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
480 if (mode & TUI_BP_HIT)
481 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
482 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
483 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
484
485 if (mode & TUI_BP_ENABLED)
486 element[TUI_BP_BREAK_POS] = '+';
487 else if (mode & TUI_BP_DISABLED)
488 element[TUI_BP_BREAK_POS] = '-';
489
490 if (src_element->is_exec_point)
491 element[TUI_EXEC_POS] = '>';
c906108c 492
398fdd60 493 mvwaddstr (handle, i + 1, 1, element);
5216580d 494 }
398fdd60 495 refresh_window ();
f80bda8e 496}
This page took 1.952067 seconds and 4 git commands to generate.