Change tui_update_source_window_as_is to be a method
[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
be4da588 73tui_update_source_window (struct tui_source_window_base *win_info,
13274fc3 74 struct gdbarch *gdbarch,
08ef48c5 75 struct symtab *s,
20149b6b 76 struct tui_line_or_address line_or_addr)
c906108c 77{
be4da588 78 win_info->horizontal_offset = 0;
ed8358e9 79 win_info->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 {
ed8358e9
TT
102 tui_update_breakpoint_info (this, nullptr, false);
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;
328 tui_update_source_window (this, gdbarch,
20149b6b 329 cursal.symtab, line_or_addr);
5104fe36
TT
330 }
331 else if (deprecated_safe_get_selected_frame () != NULL)
332 {
333 struct tui_line_or_address line;
334 struct symtab_and_line cursal
335 = get_current_source_symtab_and_line ();
336 struct frame_info *frame = deprecated_safe_get_selected_frame ();
337 struct gdbarch *gdbarch = get_frame_arch (frame);
338
339 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
340 if (type == SRC_WIN)
341 {
342 line.loa = LOA_LINE;
343 line.u.line_no = cursal.line;
344 }
345 else
346 {
347 line.loa = LOA_ADDRESS;
348 find_line_pc (s, cursal.line, &line.u.addr);
349 }
20149b6b 350 tui_update_source_window (this, gdbarch, s, line);
5104fe36 351 }
3df505f6
TT
352 else
353 erase_source_content ();
5104fe36
TT
354}
355
356/* See tui-data.h. */
357
358void
359tui_source_window_base::make_visible (bool visible)
360{
361 execution_info->make_visible (visible);
362 tui_win_info::make_visible (visible);
363}
364
365/* See tui-data.h. */
366
367void
368tui_source_window_base::refresh_window ()
369{
370 execution_info->refresh_window ();
371 tui_win_info::refresh_window ();
372}
373
374/* See tui-data.h. */
375
6f11e682 376void
ad54d15b 377tui_source_window_base::refill ()
6f11e682
TT
378{
379 symtab *s = nullptr;
380
cb2ce893 381 if (type == SRC_WIN)
6f11e682
TT
382 {
383 symtab_and_line cursal = get_current_source_symtab_and_line ();
384 s = (cursal.symtab == NULL
385 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
386 : cursal.symtab);
387 }
388
ed8358e9 389 update_source_window_as_is (gdbarch, s, content[0].line_or_addr);
6f11e682 390}
c906108c 391
f80bda8e 392/* Scroll the source forward or backward horizontally. */
6f11e682 393
c906108c 394void
c3bd716f 395tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 396{
53e7cdba 397 if (!content.empty ())
c906108c 398 {
c3bd716f
TT
399 int offset = horizontal_offset + num_to_scroll;
400 if (offset < 0)
401 offset = 0;
e6e41501 402 horizontal_offset = offset;
ad54d15b 403 refill ();
c906108c 404 }
6ba8e26f 405}
c906108c
SS
406
407
0598af48 408/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
409 line_no. */
410
c906108c 411void
ad54d15b 412tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 413{
02c28df0 414 bool changed = false;
c906108c 415 int i;
c906108c
SS
416
417 i = 0;
53e7cdba 418 while (i < content.size ())
c906108c 419 {
02c28df0 420 bool new_state;
362c05fe 421 struct tui_line_or_address content_loa =
53e7cdba 422 content[i].line_or_addr;
362c05fe
AS
423
424 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
425 gdb_assert (content_loa.loa == LOA_LINE
426 || content_loa.loa == LOA_ADDRESS);
427 if (content_loa.loa == l.loa
428 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
f7952c57 429 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
02c28df0 430 new_state = true;
c906108c 431 else
02c28df0 432 new_state = false;
53e7cdba 433 if (new_state != content[i].is_exec_point)
00b90ae2 434 {
02c28df0 435 changed = true;
53e7cdba 436 content[i].is_exec_point = new_state;
ad54d15b 437 tui_show_source_line (this, i + 1);
00b90ae2 438 }
c906108c
SS
439 i++;
440 }
00b90ae2 441 if (changed)
ad54d15b 442 refill ();
00b90ae2 443}
c906108c 444
0807ab7b
TT
445/* See tui-winsource.h. */
446
c906108c 447void
0807ab7b 448tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 449{
ad54d15b 450 for (tui_source_window_base *win : tui_source_windows ())
c906108c 451 {
0807ab7b 452 if (tui_update_breakpoint_info (win, being_deleted, false))
00b2bad4 453 {
7ba913dc 454 win->update_exec_info ();
00b2bad4 455 }
c906108c 456 }
00b2bad4 457}
c906108c
SS
458
459
0807ab7b 460/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
461 information for each line.
462
0807ab7b 463 Returns true if something changed and the execution window must be
1cc6d956
MS
464 refreshed. */
465
0807ab7b
TT
466bool
467tui_update_breakpoint_info (struct tui_source_window_base *win,
468 struct breakpoint *being_deleted,
469 bool current_only)
c906108c
SS
470{
471 int i;
0807ab7b 472 bool need_refresh = false;
c906108c 473
53e7cdba 474 for (i = 0; i < win->content.size (); i++)
00b2bad4
SC
475 {
476 struct breakpoint *bp;
477 extern struct breakpoint *breakpoint_chain;
5b6fe301 478 struct tui_source_element *line;
00b2bad4 479
53e7cdba 480 line = &win->content[i];
6d012f14 481 if (current_only && !line->is_exec_point)
00b2bad4
SC
482 continue;
483
484 /* Scan each breakpoint to see if the current line has something to
485 do with it. Identify enable/disabled breakpoints as well as
486 those that we already hit. */
0598af48 487 tui_bp_flags mode = 0;
00b2bad4 488 for (bp = breakpoint_chain;
cafb3438 489 bp != NULL;
00b2bad4
SC
490 bp = bp->next)
491 {
f8eba3c6
TT
492 struct bp_location *loc;
493
362c05fe
AS
494 gdb_assert (line->line_or_addr.loa == LOA_LINE
495 || line->line_or_addr.loa == LOA_ADDRESS);
f8eba3c6 496
0807ab7b
TT
497 if (bp == being_deleted)
498 continue;
499
f8eba3c6
TT
500 for (loc = bp->loc; loc != NULL; loc = loc->next)
501 {
c2cd8994 502 if (win->location_matches_p (loc, i))
f8eba3c6
TT
503 {
504 if (bp->enable_state == bp_disabled)
505 mode |= TUI_BP_DISABLED;
506 else
507 mode |= TUI_BP_ENABLED;
508 if (bp->hit_count)
509 mode |= TUI_BP_HIT;
510 if (bp->loc->cond)
511 mode |= TUI_BP_CONDITIONAL;
512 if (bp->type == bp_hardware_breakpoint)
513 mode |= TUI_BP_HARDWARE;
514 }
515 }
00b2bad4 516 }
0598af48 517 if (line->break_mode != mode)
00b2bad4 518 {
0598af48
TT
519 line->break_mode = mode;
520 need_refresh = true;
00b2bad4
SC
521 }
522 }
523 return need_refresh;
524}
c906108c 525
6ba8e26f
AC
526/* Function to initialize the content of the execution info window,
527 based upon the input window which is either the source or
528 disassembly window. */
73fbdc65 529void
5216580d 530tui_source_window_base::update_exec_info ()
c906108c 531{
5216580d 532 werase (execution_info->handle);
37a4a131
TT
533 tui_update_breakpoint_info (this, nullptr, true);
534 for (int i = 0; i < content.size (); i++)
098f9ed4 535 {
5216580d
TT
536 struct tui_source_element *src_element = &content[i];
537 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
538
539 /* Now update the exec info content based upon the state
540 of each line as indicated by the source content. */
5216580d 541 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
542 if (mode & TUI_BP_HIT)
543 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
544 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
545 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
546
547 if (mode & TUI_BP_ENABLED)
548 element[TUI_BP_BREAK_POS] = '+';
549 else if (mode & TUI_BP_DISABLED)
550 element[TUI_BP_BREAK_POS] = '-';
551
552 if (src_element->is_exec_point)
553 element[TUI_EXEC_POS] = '>';
c906108c 554
5216580d
TT
555 mvwaddstr (execution_info->handle, i + 1, 0, element);
556 }
557 execution_info->refresh_window ();
f80bda8e 558}
This page took 3.127189 seconds and 4 git commands to generate.