1 /* TUI display registers in window.
3 Copyright (C) 1998-2015 Free Software Foundation, Inc.
5 Contributed by Hewlett-Packard Company.
7 This file is part of GDB.
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.
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.
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/>. */
23 #include "arch-utils.h"
25 #include "tui/tui-data.h"
33 #include "tui/tui-layout.h"
34 #include "tui/tui-win.h"
35 #include "tui/tui-windata.h"
36 #include "tui/tui-wingeneral.h"
37 #include "tui/tui-file.h"
38 #include "tui/tui-regs.h"
39 #include "tui/tui-io.h"
40 #include "reggroups.h"
42 #include "completer.h"
44 #include "gdb_curses.h"
47 /*****************************************
48 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
49 ******************************************/
51 tui_display_register (struct tui_data_element
*data
,
52 struct tui_gen_win_info
*win_info
);
54 static enum tui_status
tui_show_register_group (struct reggroup
*group
,
55 struct frame_info
*frame
,
56 int refresh_values_only
);
58 static enum tui_status
tui_get_register (struct frame_info
*frame
,
59 struct tui_data_element
*data
,
60 int regnum
, int *changedp
);
64 /*****************************************
65 ** PUBLIC FUNCTIONS **
66 ******************************************/
68 /* Answer the number of the last line in the regs display. If there
69 are no registers (-1) is returned. */
71 tui_last_regs_line_no (void)
75 if (TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
> 0)
77 num_lines
= (TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
/
78 TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
);
79 if (TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
%
80 TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
)
87 /* Answer the line number that the register element at element_no is
88 on. If element_no is greater than the number of register elements
89 there are, -1 is returned. */
91 tui_line_from_reg_element_no (int element_no
)
93 if (element_no
< TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
)
101 (TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
* i
))
114 /* Answer the index of the first element in line_no. If line_no is
115 past the register area (-1) is returned. */
117 tui_first_reg_element_no_inline (int line_no
)
119 if ((line_no
* TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
)
120 <= TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
)
121 return ((line_no
+ 1) *
122 TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
) -
123 TUI_DATA_WIN
->detail
.data_display_info
.regs_column_count
;
129 /* Show the registers of the given group in the data window
130 and refresh the window. */
132 tui_show_registers (struct reggroup
*group
)
134 enum tui_status ret
= TUI_FAILURE
;
135 struct tui_data_info
*display_info
;
137 /* Make sure the curses mode is enabled. */
140 /* Make sure the register window is visible. If not, select an
141 appropriate layout. */
142 if (TUI_DATA_WIN
== NULL
|| !TUI_DATA_WIN
->generic
.is_visible
)
143 tui_set_layout_by_name (DATA_NAME
);
145 display_info
= &TUI_DATA_WIN
->detail
.data_display_info
;
147 group
= general_reggroup
;
149 /* Say that registers should be displayed, even if there is a
151 display_info
->display_regs
= TRUE
;
153 if (target_has_registers
&& target_has_stack
&& target_has_memory
)
155 ret
= tui_show_register_group (group
, get_selected_frame (NULL
),
156 group
== display_info
->current_group
);
158 if (ret
== TUI_FAILURE
)
160 display_info
->current_group
= 0;
161 tui_erase_data_content (NO_REGS_STRING
);
167 /* Clear all notation of changed values. */
168 for (i
= 0; i
< display_info
->regs_content_count
; i
++)
170 struct tui_gen_win_info
*data_item_win
;
171 struct tui_win_element
*win
;
173 data_item_win
= &display_info
->regs_content
[i
]
174 ->which_element
.data_window
;
175 win
= data_item_win
->content
[0];
176 win
->which_element
.data
.highlight
= FALSE
;
178 display_info
->current_group
= group
;
179 tui_display_all_data ();
184 /* Set the data window to display the registers of the register group
185 using the given frame. Values are refreshed only when
186 refresh_values_only is TRUE. */
188 static enum tui_status
189 tui_show_register_group (struct reggroup
*group
,
190 struct frame_info
*frame
,
191 int refresh_values_only
)
193 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
194 enum tui_status ret
= TUI_FAILURE
;
196 int allocated_here
= FALSE
;
199 struct tui_data_info
*display_info
= &TUI_DATA_WIN
->detail
.data_display_info
;
201 /* Make a new title showing which group we display. */
202 snprintf (title
, sizeof (title
) - 1, "Register group: %s",
203 reggroup_name (group
));
204 xfree (TUI_DATA_WIN
->generic
.title
);
205 TUI_DATA_WIN
->generic
.title
= xstrdup (title
);
207 /* See how many registers must be displayed. */
210 regnum
< gdbarch_num_regs (gdbarch
)
211 + gdbarch_num_pseudo_regs (gdbarch
);
216 /* Must be in the group. */
217 if (!gdbarch_register_reggroup_p (gdbarch
, regnum
, group
))
220 /* If the register name is empty, it is undefined for this
221 processor, so don't display anything. */
222 name
= gdbarch_register_name (gdbarch
, regnum
);
223 if (name
== 0 || *name
== '\0')
229 if (display_info
->regs_content_count
> 0 && !refresh_values_only
)
231 tui_free_data_content (display_info
->regs_content
,
232 display_info
->regs_content_count
);
233 display_info
->regs_content_count
= 0;
236 if (display_info
->regs_content_count
<= 0)
238 display_info
->regs_content
= tui_alloc_content (nr_regs
, DATA_WIN
);
239 allocated_here
= TRUE
;
240 refresh_values_only
= FALSE
;
243 if (display_info
->regs_content
!= (tui_win_content
) NULL
)
245 if (!refresh_values_only
|| allocated_here
)
247 TUI_DATA_WIN
->generic
.content
= NULL
;
248 TUI_DATA_WIN
->generic
.content_size
= 0;
249 tui_add_content_elements (&TUI_DATA_WIN
->generic
, nr_regs
);
250 display_info
->regs_content
251 = (tui_win_content
) TUI_DATA_WIN
->generic
.content
;
252 display_info
->regs_content_count
= nr_regs
;
255 /* Now set the register names and values. */
258 regnum
< gdbarch_num_regs (gdbarch
)
259 + gdbarch_num_pseudo_regs (gdbarch
);
262 struct tui_gen_win_info
*data_item_win
;
263 struct tui_data_element
*data
;
266 /* Must be in the group. */
267 if (!gdbarch_register_reggroup_p (gdbarch
, regnum
, group
))
270 /* If the register name is empty, it is undefined for this
271 processor, so don't display anything. */
272 name
= gdbarch_register_name (gdbarch
, regnum
);
273 if (name
== 0 || *name
== '\0')
277 &display_info
->regs_content
[pos
]->which_element
.data_window
;
278 data
= &data_item_win
->content
[0]->which_element
.data
;
281 if (!refresh_values_only
)
283 data
->item_no
= regnum
;
285 data
->highlight
= FALSE
;
287 tui_get_register (frame
, data
, regnum
, 0);
292 TUI_DATA_WIN
->generic
.content_size
=
293 display_info
->regs_content_count
+ display_info
->data_content_count
;
300 /* Function to display the registers in the content from
301 'start_element_no' until the end of the register content or the end
302 of the display height. No checking for displaying past the end of
303 the registers is done here. */
305 tui_display_registers_from (int start_element_no
)
307 struct tui_data_info
*display_info
= &TUI_DATA_WIN
->detail
.data_display_info
;
309 if (display_info
->regs_content
!= (tui_win_content
) NULL
310 && display_info
->regs_content_count
> 0)
312 int i
= start_element_no
;
313 int j
, item_win_width
, cur_y
;
316 for (i
= 0; i
< display_info
->regs_content_count
; i
++)
318 struct tui_data_element
*data
;
319 struct tui_gen_win_info
*data_item_win
;
324 = &display_info
->regs_content
[i
]->which_element
.data_window
;
325 data
= &data_item_win
->content
[0]->which_element
.data
;
332 len
= 8 * ((len
/ 8) + 1);
340 item_win_width
= max_len
+ 1;
341 i
= start_element_no
;
343 display_info
->regs_column_count
=
344 (TUI_DATA_WIN
->generic
.width
- 2) / item_win_width
;
345 if (display_info
->regs_column_count
== 0)
346 display_info
->regs_column_count
= 1;
348 (TUI_DATA_WIN
->generic
.width
- 2) / display_info
->regs_column_count
;
350 /* Now create each data "sub" window, and write the display into
353 while (i
< display_info
->regs_content_count
354 && cur_y
<= TUI_DATA_WIN
->generic
.viewport_height
)
357 j
< display_info
->regs_column_count
358 && i
< display_info
->regs_content_count
;
361 struct tui_gen_win_info
*data_item_win
;
362 struct tui_data_element
*data_element_ptr
;
364 /* Create the window if necessary. */
365 data_item_win
= &display_info
->regs_content
[i
]
366 ->which_element
.data_window
;
367 data_element_ptr
= &data_item_win
->content
[0]->which_element
.data
;
368 if (data_item_win
->handle
!= (WINDOW
*) NULL
369 && (data_item_win
->height
!= 1
370 || data_item_win
->width
!= item_win_width
371 || data_item_win
->origin
.x
!= (item_win_width
* j
) + 1
372 || data_item_win
->origin
.y
!= cur_y
))
374 tui_delete_win (data_item_win
->handle
);
375 data_item_win
->handle
= 0;
378 if (data_item_win
->handle
== (WINDOW
*) NULL
)
380 data_item_win
->height
= 1;
381 data_item_win
->width
= item_win_width
;
382 data_item_win
->origin
.x
= (item_win_width
* j
) + 1;
383 data_item_win
->origin
.y
= cur_y
;
384 tui_make_window (data_item_win
, DONT_BOX_WINDOW
);
385 scrollok (data_item_win
->handle
, FALSE
);
387 touchwin (data_item_win
->handle
);
389 /* Get the printable representation of the register
391 tui_display_register (data_element_ptr
, data_item_win
);
392 i
++; /* Next register. */
394 cur_y
++; /* Next row. */
400 /* Function to display the registers in the content from
401 'start_element_no' on 'start_line_no' until the end of the register
402 content or the end of the display height. This function checks
403 that we won't display off the end of the register display. */
405 tui_display_reg_element_at_line (int start_element_no
,
408 if (TUI_DATA_WIN
->detail
.data_display_info
.regs_content
409 != (tui_win_content
) NULL
410 && TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
> 0)
412 int element_no
= start_element_no
;
414 if (start_element_no
!= 0 && start_line_no
!= 0)
416 int last_line_no
, first_line_on_last_page
;
418 last_line_no
= tui_last_regs_line_no ();
419 first_line_on_last_page
420 = last_line_no
- (TUI_DATA_WIN
->generic
.height
- 2);
421 if (first_line_on_last_page
< 0)
422 first_line_on_last_page
= 0;
424 /* If there is no other data displayed except registers, and
425 the element_no causes us to scroll past the end of the
426 registers, adjust what element to really start the
428 if (TUI_DATA_WIN
->detail
.data_display_info
.data_content_count
<= 0
429 && start_line_no
> first_line_on_last_page
)
431 = tui_first_reg_element_no_inline (first_line_on_last_page
);
433 tui_display_registers_from (element_no
);
439 /* Function to display the registers starting at line line_no in the
440 data window. Answers the line number that the display actually
441 started from. If nothing is displayed (-1) is returned. */
443 tui_display_registers_from_line (int line_no
,
446 if (TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
> 0)
448 int line
, element_no
;
452 else if (force_display
)
453 { /* If we must display regs (force_display is true), then
454 make sure that we don't display off the end of the
456 if (line_no
>= tui_last_regs_line_no ())
458 if ((line
= tui_line_from_reg_element_no (
459 TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
- 1)) < 0)
468 element_no
= tui_first_reg_element_no_inline (line
);
470 < TUI_DATA_WIN
->detail
.data_display_info
.regs_content_count
)
471 tui_display_reg_element_at_line (element_no
, line
);
478 return (-1); /* Nothing was displayed. */
482 /* This function check all displayed registers for changes in values,
483 given a particular frame. If the values have changed, they are
484 updated with the new value and highlighted. */
486 tui_check_register_values (struct frame_info
*frame
)
488 if (TUI_DATA_WIN
!= NULL
489 && TUI_DATA_WIN
->generic
.is_visible
)
491 struct tui_data_info
*display_info
492 = &TUI_DATA_WIN
->detail
.data_display_info
;
494 if (display_info
->regs_content_count
<= 0
495 && display_info
->display_regs
)
496 tui_show_registers (display_info
->current_group
);
501 for (i
= 0; (i
< display_info
->regs_content_count
); i
++)
503 struct tui_data_element
*data
;
504 struct tui_gen_win_info
*data_item_win_ptr
;
507 data_item_win_ptr
= &display_info
->regs_content
[i
]->
508 which_element
.data_window
;
509 data
= &data_item_win_ptr
->content
[0]->which_element
.data
;
510 was_hilighted
= data
->highlight
;
512 tui_get_register (frame
, data
,
513 data
->item_no
, &data
->highlight
);
515 if (data
->highlight
|| was_hilighted
)
517 tui_display_register (data
, data_item_win_ptr
);
524 /* Display a register in a window. If hilite is TRUE, then the value
525 will be displayed in reverse video. */
527 tui_display_register (struct tui_data_element
*data
,
528 struct tui_gen_win_info
*win_info
)
530 if (win_info
->handle
!= (WINDOW
*) NULL
)
535 /* We ignore the return value, casting it to void in order to avoid
536 a compiler warning. The warning itself was introduced by a patch
537 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
538 to code that causes the compiler to generate an unused-value
540 (void) wstandout (win_info
->handle
);
542 wmove (win_info
->handle
, 0, 0);
543 for (i
= 1; i
< win_info
->width
; i
++)
544 waddch (win_info
->handle
, ' ');
545 wmove (win_info
->handle
, 0, 0);
547 waddstr (win_info
->handle
, data
->content
);
550 /* We ignore the return value, casting it to void in order to avoid
551 a compiler warning. The warning itself was introduced by a patch
552 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
553 to code that causes the compiler to generate an unused-value
555 (void) wstandend (win_info
->handle
);
556 tui_refresh_win (win_info
);
560 /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
561 around behaviour. Returns the next register group, or NULL if the
562 register window is not currently being displayed. */
564 static struct reggroup
*
565 tui_reg_next (struct gdbarch
*gdbarch
)
567 struct reggroup
*group
= NULL
;
569 if (TUI_DATA_WIN
!= NULL
)
571 group
= TUI_DATA_WIN
->detail
.data_display_info
.current_group
;
572 group
= reggroup_next (gdbarch
, group
);
574 group
= reggroup_next (gdbarch
, NULL
);
579 /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
580 around behaviour. Returns the previous register group, or NULL if the
581 register window is not currently being displayed. */
583 static struct reggroup
*
584 tui_reg_prev (struct gdbarch
*gdbarch
)
586 struct reggroup
*group
= NULL
;
588 if (TUI_DATA_WIN
!= NULL
)
590 group
= TUI_DATA_WIN
->detail
.data_display_info
.current_group
;
591 group
= reggroup_prev (gdbarch
, group
);
593 group
= reggroup_prev (gdbarch
, NULL
);
598 /* Implement the 'tui reg' command. Changes the register group displayed
599 in the tui register window. Displays the tui register window if it is
600 not already on display. */
603 tui_reg_command (char *args
, int from_tty
)
605 struct gdbarch
*gdbarch
= get_current_arch ();
609 struct reggroup
*group
, *match
= NULL
;
610 size_t len
= strlen (args
);
612 /* Make sure the curses mode is enabled. */
615 /* Make sure the register window is visible. If not, select an
616 appropriate layout. We need to do this before trying to run the
617 'next' or 'prev' commands. */
618 if (TUI_DATA_WIN
== NULL
|| !TUI_DATA_WIN
->generic
.is_visible
)
619 tui_set_layout_by_name (DATA_NAME
);
621 if (strncmp (args
, "next", len
) == 0)
622 match
= tui_reg_next (gdbarch
);
623 else if (strncmp (args
, "prev", len
) == 0)
624 match
= tui_reg_prev (gdbarch
);
626 /* This loop matches on the initial part of a register group
627 name. If this initial part in ARGS matches only one register
628 group then the switch is made. */
629 for (group
= reggroup_next (gdbarch
, NULL
);
631 group
= reggroup_next (gdbarch
, group
))
633 if (strncmp (reggroup_name (group
), args
, len
) == 0)
636 error (_("ambiguous register group name '%s'"), args
);
642 error (_("unknown register group '%s'"), args
);
644 tui_show_registers (match
);
648 struct reggroup
*group
;
651 printf_unfiltered (_("\"tui reg\" must be followed by the name of "
652 "either a register group,\nor one of 'next' "
653 "or 'prev'. Known register groups are:\n"));
655 for (first
= 1, group
= reggroup_next (gdbarch
, NULL
);
657 first
= 0, group
= reggroup_next (gdbarch
, group
))
660 printf_unfiltered (", ");
661 printf_unfiltered ("%s", reggroup_name (group
));
664 printf_unfiltered ("\n");
668 /* Complete names of register groups, and add the special "prev" and "next"
671 static VEC (char_ptr
) *
672 tui_reggroup_completer (struct cmd_list_element
*ignore
,
673 const char *text
, const char *word
)
675 VEC (char_ptr
) *result
= NULL
;
676 static const char *extra
[] = { "next", "prev", NULL
};
677 size_t len
= strlen (word
);
680 result
= reggroup_completer (ignore
, text
, word
);
682 for (tmp
= extra
; *tmp
!= NULL
; ++tmp
)
684 if (strncmp (word
, *tmp
, len
) == 0)
685 VEC_safe_push (char_ptr
, result
, xstrdup (*tmp
));
691 /* Provide a prototype to silence -Wmissing-prototypes. */
692 extern initialize_file_ftype _initialize_tui_regs
;
695 _initialize_tui_regs (void)
697 struct cmd_list_element
**tuicmd
, *cmd
;
699 tuicmd
= tui_get_cmd_list ();
701 cmd
= add_cmd ("reg", class_tui
, tui_reg_command
, _("\
702 TUI command to control the register window."), tuicmd
);
703 set_cmd_completer (cmd
, tui_reggroup_completer
);
707 /*****************************************
708 ** STATIC LOCAL FUNCTIONS **
709 ******************************************/
712 tui_restore_gdbout (void *ui
)
714 ui_file_delete (gdb_stdout
);
715 gdb_stdout
= (struct ui_file
*) ui
;
716 pagination_enabled
= 1;
719 /* Get the register from the frame and return a printable
720 representation of it. */
723 tui_register_format (struct frame_info
*frame
, int regnum
)
725 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
726 struct ui_file
*stream
;
727 struct ui_file
*old_stdout
;
728 struct cleanup
*cleanups
;
732 pagination_enabled
= 0;
733 old_stdout
= gdb_stdout
;
734 stream
= tui_sfileopen (256);
736 cleanups
= make_cleanup (tui_restore_gdbout
, (void*) old_stdout
);
737 gdbarch_print_registers_info (gdbarch
, stream
, frame
, regnum
, 1);
739 /* Save formatted output in the buffer. */
740 p
= tui_file_get_strbuf (stream
);
742 /* Remove the possible \n. */
743 s
= strrchr (p
, '\n');
747 /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
748 ret
= tui_expand_tabs (p
, 0);
750 do_cleanups (cleanups
);
755 /* Get the register value from the given frame and format it for the
756 display. When changep is set, check if the new register value has
757 changed with respect to the previous call. */
758 static enum tui_status
759 tui_get_register (struct frame_info
*frame
,
760 struct tui_data_element
*data
,
761 int regnum
, int *changedp
)
763 enum tui_status ret
= TUI_FAILURE
;
767 if (target_has_registers
)
769 char *prev_content
= data
->content
;
771 data
->content
= tui_register_format (frame
, regnum
);
774 && strcmp (prev_content
, data
->content
) != 0)
777 xfree (prev_content
);