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