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