Remove unused parameter from two TUI functions
[deliverable/binutils-gdb.git] / gdb / tui / tui-winsource.c
1 /* TUI display source/assembly window.
2
3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
4
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
11 the Free Software Foundation; either version 3 of the License, or
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
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 #include "defs.h"
23 #include <ctype.h>
24 #include "symtab.h"
25 #include "frame.h"
26 #include "breakpoint.h"
27 #include "value.h"
28 #include "source.h"
29 #include "objfiles.h"
30 #include "filenames.h"
31
32 #include "tui/tui.h"
33 #include "tui/tui-data.h"
34 #include "tui/tui-io.h"
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"
41 #include "gdb_curses.h"
42
43 /* Function to display the "main" routine. */
44 void
45 tui_display_main ()
46 {
47 if (!tui_source_windows ().empty ())
48 {
49 struct gdbarch *gdbarch;
50 CORE_ADDR addr;
51
52 tui_get_begin_asm_address (&gdbarch, &addr);
53 if (addr != (CORE_ADDR) 0)
54 {
55 struct symtab *s;
56
57 tui_update_source_windows_with_addr (gdbarch, addr);
58 s = find_pc_line_symtab (addr);
59 if (s != NULL)
60 tui_update_locator_fullname (symtab_to_fullname (s));
61 else
62 tui_update_locator_fullname ("??");
63 }
64 }
65 }
66
67
68
69 /* Function to display source in the source window. This function
70 initializes the horizontal scroll to 0. */
71 void
72 tui_update_source_window (struct tui_source_window_base *win_info,
73 struct gdbarch *gdbarch,
74 struct symtab *s,
75 struct tui_line_or_address line_or_addr,
76 int noerror)
77 {
78 win_info->horizontal_offset = 0;
79 tui_update_source_window_as_is (win_info, gdbarch, s, line_or_addr, noerror);
80
81 return;
82 }
83
84
85 /* Function to display source in the source/asm window. This function
86 shows the source as specified by the horizontal offset. */
87 void
88 tui_update_source_window_as_is (struct tui_source_window_base *win_info,
89 struct gdbarch *gdbarch,
90 struct symtab *s,
91 struct tui_line_or_address line_or_addr,
92 int noerror)
93 {
94 enum tui_status ret;
95
96 if (win_info->type == SRC_WIN)
97 ret = tui_set_source_content (win_info, s, line_or_addr.u.line_no,
98 noerror);
99 else
100 ret = tui_set_disassem_content (win_info, gdbarch, line_or_addr.u.addr);
101
102 if (ret == TUI_FAILURE)
103 {
104 tui_clear_source_content (win_info);
105 tui_clear_exec_info_content (win_info);
106 }
107 else
108 {
109 tui_update_breakpoint_info (win_info, nullptr, false);
110 tui_show_source_content (win_info);
111 tui_update_exec_info (win_info);
112 if (win_info->type == SRC_WIN)
113 {
114 symtab_and_line sal;
115
116 sal.line = line_or_addr.u.line_no +
117 (win_info->content.size () - 2);
118 sal.symtab = s;
119 sal.pspace = SYMTAB_PSPACE (s);
120 set_current_source_symtab_and_line (sal);
121 /* If the focus was in the asm win, put it in the src win if
122 we don't have a split layout. */
123 if (tui_win_with_focus () == TUI_DISASM_WIN
124 && tui_current_layout () != SRC_DISASSEM_COMMAND)
125 tui_set_win_focus_to (win_info);
126 }
127 }
128
129
130 return;
131 }
132
133
134 /* Function to ensure that the source and/or disassemly windows
135 reflect the input address. */
136 void
137 tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
138 {
139 if (addr != 0)
140 {
141 struct symtab_and_line sal;
142 struct tui_line_or_address l;
143
144 switch (tui_current_layout ())
145 {
146 case DISASSEM_COMMAND:
147 case DISASSEM_DATA_COMMAND:
148 tui_show_disassem (gdbarch, addr);
149 break;
150 case SRC_DISASSEM_COMMAND:
151 tui_show_disassem_and_update_source (gdbarch, addr);
152 break;
153 default:
154 sal = find_pc_line (addr, 0);
155 l.loa = LOA_LINE;
156 l.u.line_no = sal.line;
157 tui_show_symtab_source (TUI_SRC_WIN, gdbarch, sal.symtab, l, FALSE);
158 break;
159 }
160 }
161 else
162 {
163 for (struct tui_source_window_base *win_info : tui_source_windows ())
164 {
165 tui_clear_source_content (win_info);
166 tui_clear_exec_info_content (win_info);
167 }
168 }
169 }
170
171 /* Function to ensure that the source and/or disassemly windows
172 reflect the input address. */
173 void
174 tui_update_source_windows_with_line (struct symtab *s, int line)
175 {
176 struct gdbarch *gdbarch;
177 CORE_ADDR pc;
178 struct tui_line_or_address l;
179
180 if (!s)
181 return;
182
183 gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
184
185 switch (tui_current_layout ())
186 {
187 case DISASSEM_COMMAND:
188 case DISASSEM_DATA_COMMAND:
189 find_line_pc (s, line, &pc);
190 tui_update_source_windows_with_addr (gdbarch, pc);
191 break;
192 default:
193 l.loa = LOA_LINE;
194 l.u.line_no = line;
195 tui_show_symtab_source (TUI_SRC_WIN, gdbarch, s, l, FALSE);
196 if (tui_current_layout () == SRC_DISASSEM_COMMAND)
197 {
198 find_line_pc (s, line, &pc);
199 tui_show_disassem (gdbarch, pc);
200 }
201 break;
202 }
203
204 return;
205 }
206
207 void
208 tui_clear_source_content (struct tui_source_window_base *win_info)
209 {
210 if (win_info != NULL)
211 {
212 int i;
213
214 win_info->content_in_use = false;
215 tui_erase_source_content (win_info);
216 for (i = 0; i < win_info->content.size (); i++)
217 {
218 struct tui_source_element *element = &win_info->content[i];
219
220 element->break_mode = 0;
221 element->is_exec_point = false;
222 }
223 }
224 }
225
226
227 void
228 tui_erase_source_content (struct tui_source_window_base *win_info)
229 {
230 int x_pos;
231 int half_width = (win_info->width - 2) / 2;
232
233 if (win_info->handle != NULL)
234 {
235 werase (win_info->handle);
236 tui_check_and_display_highlight_if_needed (win_info);
237
238 const char *no_src_str;
239
240 if (win_info->type == SRC_WIN)
241 no_src_str = NO_SRC_STRING;
242 else
243 no_src_str = NO_DISASSEM_STRING;
244 if (strlen (no_src_str) >= half_width)
245 x_pos = 1;
246 else
247 x_pos = half_width - strlen (no_src_str);
248 mvwaddstr (win_info->handle,
249 (win_info->height / 2),
250 x_pos,
251 (char *) no_src_str);
252
253 /* elz: Added this function call to set the real contents of
254 the window to what is on the screen, so that later calls
255 to refresh, do display the correct stuff, and not the old
256 image. */
257
258 tui_set_source_content_nil (win_info, no_src_str);
259
260 win_info->refresh_window ();
261 }
262 }
263
264
265 /* Redraw the complete line of a source or disassembly window. */
266 static void
267 tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
268 {
269 struct tui_source_element *line;
270 int x;
271
272 line = &win_info->content[lineno - 1];
273 if (line->is_exec_point)
274 tui_set_reverse_mode (win_info->handle, true);
275
276 wmove (win_info->handle, lineno, 1);
277 tui_puts (line->line,
278 win_info->handle);
279 if (line->is_exec_point)
280 tui_set_reverse_mode (win_info->handle, false);
281
282 /* Clear to end of line but stop before the border. */
283 x = getcurx (win_info->handle);
284 while (x + 1 < win_info->width)
285 {
286 waddch (win_info->handle, ' ');
287 x = getcurx (win_info->handle);
288 }
289 }
290
291 void
292 tui_show_source_content (struct tui_source_window_base *win_info)
293 {
294 if (!win_info->content.empty ())
295 {
296 int lineno;
297
298 for (lineno = 1; lineno <= win_info->content.size (); lineno++)
299 tui_show_source_line (win_info, lineno);
300 }
301 else
302 tui_erase_source_content (win_info);
303
304 tui_check_and_display_highlight_if_needed (win_info);
305 win_info->refresh_window ();
306 win_info->content_in_use = true;
307 }
308
309 /* See tui-data.h. */
310
311 void
312 tui_source_window_base::refill ()
313 {
314 symtab *s = nullptr;
315
316 if (type == SRC_WIN)
317 {
318 symtab_and_line cursal = get_current_source_symtab_and_line ();
319 s = (cursal.symtab == NULL
320 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
321 : cursal.symtab);
322 }
323
324 tui_update_source_window_as_is (this, gdbarch, s,
325 content[0].line_or_addr,
326 FALSE);
327 }
328
329 /* Scroll the source forward or backward horizontally. */
330
331 void
332 tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
333 {
334 if (!content.empty ())
335 {
336 int offset = horizontal_offset + num_to_scroll;
337 if (offset < 0)
338 offset = 0;
339 horizontal_offset = offset;
340 refill ();
341 }
342 }
343
344
345 /* Set or clear the is_exec_point flag in the line whose line is
346 line_no. */
347
348 void
349 tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
350 {
351 bool changed = false;
352 int i;
353
354 i = 0;
355 while (i < content.size ())
356 {
357 bool new_state;
358 struct tui_line_or_address content_loa =
359 content[i].line_or_addr;
360
361 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
362 gdb_assert (content_loa.loa == LOA_LINE
363 || content_loa.loa == LOA_ADDRESS);
364 if (content_loa.loa == l.loa
365 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
366 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
367 new_state = true;
368 else
369 new_state = false;
370 if (new_state != content[i].is_exec_point)
371 {
372 changed = true;
373 content[i].is_exec_point = new_state;
374 tui_show_source_line (this, i + 1);
375 }
376 i++;
377 }
378 if (changed)
379 refill ();
380 }
381
382 /* See tui-winsource.h. */
383
384 void
385 tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
386 {
387 for (tui_source_window_base *win : tui_source_windows ())
388 {
389 if (tui_update_breakpoint_info (win, being_deleted, false))
390 {
391 tui_update_exec_info (win);
392 }
393 }
394 }
395
396
397 /* Scan the source window and the breakpoints to update the break_mode
398 information for each line.
399
400 Returns true if something changed and the execution window must be
401 refreshed. */
402
403 bool
404 tui_update_breakpoint_info (struct tui_source_window_base *win,
405 struct breakpoint *being_deleted,
406 bool current_only)
407 {
408 int i;
409 bool need_refresh = false;
410
411 for (i = 0; i < win->content.size (); i++)
412 {
413 struct breakpoint *bp;
414 extern struct breakpoint *breakpoint_chain;
415 struct tui_source_element *line;
416
417 line = &win->content[i];
418 if (current_only && !line->is_exec_point)
419 continue;
420
421 /* Scan each breakpoint to see if the current line has something to
422 do with it. Identify enable/disabled breakpoints as well as
423 those that we already hit. */
424 tui_bp_flags mode = 0;
425 for (bp = breakpoint_chain;
426 bp != NULL;
427 bp = bp->next)
428 {
429 struct bp_location *loc;
430
431 gdb_assert (line->line_or_addr.loa == LOA_LINE
432 || line->line_or_addr.loa == LOA_ADDRESS);
433
434 if (bp == being_deleted)
435 continue;
436
437 for (loc = bp->loc; loc != NULL; loc = loc->next)
438 {
439 if (win->location_matches_p (loc, i))
440 {
441 if (bp->enable_state == bp_disabled)
442 mode |= TUI_BP_DISABLED;
443 else
444 mode |= TUI_BP_ENABLED;
445 if (bp->hit_count)
446 mode |= TUI_BP_HIT;
447 if (bp->loc->cond)
448 mode |= TUI_BP_CONDITIONAL;
449 if (bp->type == bp_hardware_breakpoint)
450 mode |= TUI_BP_HARDWARE;
451 }
452 }
453 }
454 if (line->break_mode != mode)
455 {
456 line->break_mode = mode;
457 need_refresh = true;
458 }
459 }
460 return need_refresh;
461 }
462
463 /* See tui-data.h. */
464
465 tui_exec_info_content *
466 tui_exec_info_window::maybe_allocate_content (int n_elements)
467 {
468 if (m_content == nullptr)
469 m_content = XNEWVEC (tui_exec_info_content, n_elements);
470 return m_content;
471 }
472
473
474 /* Function to initialize the content of the execution info window,
475 based upon the input window which is either the source or
476 disassembly window. */
477 void
478 tui_set_exec_info_content (struct tui_source_window_base *win_info)
479 {
480 if (win_info->execution_info != NULL)
481 {
482 tui_exec_info_content *content
483 = win_info->execution_info->maybe_allocate_content (win_info->height);
484
485 tui_update_breakpoint_info (win_info, nullptr, true);
486 for (int i = 0; i < win_info->content.size (); i++)
487 {
488 tui_exec_info_content &element = content[i];
489 struct tui_source_element *src_element;
490 tui_bp_flags mode;
491
492 src_element = &win_info->content[i];
493
494 memset (element, ' ', sizeof (tui_exec_info_content));
495 element[TUI_EXECINFO_SIZE - 1] = 0;
496
497 /* Now update the exec info content based upon the state
498 of each line as indicated by the source content. */
499 mode = src_element->break_mode;
500 if (mode & TUI_BP_HIT)
501 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
502 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
503 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
504
505 if (mode & TUI_BP_ENABLED)
506 element[TUI_BP_BREAK_POS] = '+';
507 else if (mode & TUI_BP_DISABLED)
508 element[TUI_BP_BREAK_POS] = '-';
509
510 if (src_element->is_exec_point)
511 element[TUI_EXEC_POS] = '>';
512 }
513 }
514 }
515
516
517 void
518 tui_show_exec_info_content (struct tui_source_window_base *win_info)
519 {
520 struct tui_exec_info_window *exec_info = win_info->execution_info;
521 const tui_exec_info_content *content = exec_info->get_content ();
522
523 werase (exec_info->handle);
524 exec_info->refresh_window ();
525 for (int cur_line = 1; cur_line <= win_info->content.size (); cur_line++)
526 mvwaddstr (exec_info->handle,
527 cur_line,
528 0,
529 content[cur_line - 1]);
530 exec_info->refresh_window ();
531 }
532
533
534 void
535 tui_erase_exec_info_content (struct tui_source_window_base *win_info)
536 {
537 struct tui_gen_win_info *exec_info = win_info->execution_info;
538
539 werase (exec_info->handle);
540 exec_info->refresh_window ();
541 }
542
543 void
544 tui_clear_exec_info_content (struct tui_source_window_base *win_info)
545 {
546 tui_erase_exec_info_content (win_info);
547 }
548
549 /* Function to update the execution info window. */
550 void
551 tui_update_exec_info (struct tui_source_window_base *win_info)
552 {
553 tui_set_exec_info_content (win_info);
554 tui_show_exec_info_content (win_info);
555 }
556
557 void
558 tui_alloc_source_buffer (struct tui_source_window_base *win_info)
559 {
560 int i, line_width, max_lines;
561
562 /* The window width/height includes the highlight box. Determine actual
563 content dimensions, including string null-terminators. */
564 max_lines = win_info->height - 2;
565 line_width = win_info->width - 2 + 1;
566
567 /* Allocate the buffer for the source lines. */
568 win_info->content.resize (max_lines);
569 for (i = 0; i < max_lines; i++)
570 {
571 if (win_info->content[i].line == nullptr)
572 win_info->content[i].line = (char *) xmalloc (line_width);
573 }
574 }
575
576
577 /* Answer whether a particular line number or address is displayed
578 in the current source window. */
579 int
580 tui_line_is_displayed (int line,
581 struct tui_source_window_base *win_info,
582 int check_threshold)
583 {
584 int is_displayed = FALSE;
585 int i, threshold;
586
587 if (check_threshold)
588 threshold = SCROLL_THRESHOLD;
589 else
590 threshold = 0;
591 i = 0;
592 while (i < win_info->content.size () - threshold
593 && !is_displayed)
594 {
595 is_displayed
596 = win_info->content[i].line_or_addr.loa == LOA_LINE
597 && win_info->content[i].line_or_addr.u.line_no == line;
598 i++;
599 }
600
601 return is_displayed;
602 }
603
604
605 /* Answer whether a particular line number or address is displayed
606 in the current source window. */
607 int
608 tui_addr_is_displayed (CORE_ADDR addr,
609 struct tui_source_window_base *win_info,
610 int check_threshold)
611 {
612 int is_displayed = FALSE;
613 int i, threshold;
614
615 if (check_threshold)
616 threshold = SCROLL_THRESHOLD;
617 else
618 threshold = 0;
619 i = 0;
620 while (i < win_info->content.size () - threshold
621 && !is_displayed)
622 {
623 is_displayed
624 = win_info->content[i].line_or_addr.loa == LOA_ADDRESS
625 && win_info->content[i].line_or_addr.u.addr == addr;
626 i++;
627 }
628
629 return is_displayed;
630 }
631
632
633 /*****************************************
634 ** STATIC LOCAL FUNCTIONS **
635 ******************************************/
This page took 0.056016 seconds and 4 git commands to generate.