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