1 /* TUI display registers in window.
3 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
4 2010, 2011 Free Software Foundation, Inc.
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "arch-utils.h"
26 #include "tui/tui-data.h"
34 #include "gdb_string.h"
35 #include "tui/tui-layout.h"
36 #include "tui/tui-win.h"
37 #include "tui/tui-windata.h"
38 #include "tui/tui-wingeneral.h"
39 #include "tui/tui-file.h"
40 #include "tui/tui-regs.h"
41 #include "reggroups.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);
62 static void tui_register_format (struct frame_info *,
63 struct tui_data_element*, int);
65 static void tui_scroll_regs_forward_command (char *, int);
66 static void tui_scroll_regs_backward_command (char *, int);
70 /*****************************************
71 ** PUBLIC FUNCTIONS **
72 ******************************************/
74 /* Answer the number of the last line in the regs display. If there
75 are no registers (-1) is returned. */
77 tui_last_regs_line_no (void)
81 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
83 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
84 TUI_DATA_WIN->detail.data_display_info.regs_column_count);
85 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
86 TUI_DATA_WIN->detail.data_display_info.regs_column_count)
93 /* Answer the line number that the register element at element_no is
94 on. If element_no is greater than the number of register elements
95 there are, -1 is returned. */
97 tui_line_from_reg_element_no (int element_no)
99 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
107 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
120 /* Answer the index of the first element in line_no. If line_no is
121 past the register area (-1) is returned. */
123 tui_first_reg_element_no_inline (int line_no)
125 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
126 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
127 return ((line_no + 1) *
128 TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
129 TUI_DATA_WIN->detail.data_display_info.regs_column_count;
135 /* Answer the index of the last element in line_no. If line_no is
136 past the register area (-1) is returned. */
138 tui_last_reg_element_no_in_line (int line_no)
140 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <=
141 TUI_DATA_WIN->detail.data_display_info.regs_content_count)
142 return ((line_no + 1) *
143 TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1;
148 /* Show the registers of the given group in the data window
149 and refresh the window. */
151 tui_show_registers (struct reggroup *group)
153 enum tui_status ret = TUI_FAILURE;
154 struct tui_data_info *display_info;
156 /* Make sure the curses mode is enabled. */
159 /* Make sure the register window is visible. If not, select an
160 appropriate layout. */
161 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
162 tui_set_layout_for_display_command (DATA_NAME);
164 display_info = &TUI_DATA_WIN->detail.data_display_info;
166 group = general_reggroup;
168 /* Say that registers should be displayed, even if there is a
170 display_info->display_regs = TRUE;
172 if (target_has_registers && target_has_stack && target_has_memory)
174 ret = tui_show_register_group (group, get_current_frame (),
175 group == display_info->current_group);
177 if (ret == TUI_FAILURE)
179 display_info->current_group = 0;
180 tui_erase_data_content (NO_REGS_STRING);
186 /* Clear all notation of changed values. */
187 for (i = 0; i < display_info->regs_content_count; i++)
189 struct tui_gen_win_info *data_item_win;
190 struct tui_win_element *win;
192 data_item_win = &display_info->regs_content[i]
193 ->which_element.data_window;
194 win = (struct tui_win_element *) data_item_win->content[0];
195 win->which_element.data.highlight = FALSE;
197 display_info->current_group = group;
198 tui_display_all_data ();
203 /* Set the data window to display the registers of the register group
204 using the given frame. Values are refreshed only when
205 refresh_values_only is TRUE. */
207 static enum tui_status
208 tui_show_register_group (struct reggroup *group,
209 struct frame_info *frame,
210 int refresh_values_only)
212 struct gdbarch *gdbarch = get_frame_arch (frame);
213 enum tui_status ret = TUI_FAILURE;
215 int allocated_here = FALSE;
218 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
220 /* Make a new title showing which group we display. */
221 snprintf (title, sizeof (title) - 1, "Register group: %s",
222 reggroup_name (group));
223 xfree (TUI_DATA_WIN->generic.title);
224 TUI_DATA_WIN->generic.title = xstrdup (title);
226 /* See how many registers must be displayed. */
229 regnum < gdbarch_num_regs (gdbarch)
230 + gdbarch_num_pseudo_regs (gdbarch);
235 /* Must be in the group. */
236 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
239 /* If the register name is empty, it is undefined for this
240 processor, so don't display anything. */
241 name = gdbarch_register_name (gdbarch, regnum);
242 if (name == 0 || *name == '\0')
248 if (display_info->regs_content_count > 0 && !refresh_values_only)
250 tui_free_data_content (display_info->regs_content,
251 display_info->regs_content_count);
252 display_info->regs_content_count = 0;
255 if (display_info->regs_content_count <= 0)
257 display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
258 allocated_here = TRUE;
259 refresh_values_only = FALSE;
262 if (display_info->regs_content != (tui_win_content) NULL)
264 if (!refresh_values_only || allocated_here)
266 TUI_DATA_WIN->generic.content = (void*) NULL;
267 TUI_DATA_WIN->generic.content_size = 0;
268 tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
269 display_info->regs_content
270 = (tui_win_content) TUI_DATA_WIN->generic.content;
271 display_info->regs_content_count = nr_regs;
274 /* Now set the register names and values. */
277 regnum < gdbarch_num_regs (gdbarch)
278 + gdbarch_num_pseudo_regs (gdbarch);
281 struct tui_gen_win_info *data_item_win;
282 struct tui_data_element *data;
285 /* Must be in the group. */
286 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
289 /* If the register name is empty, it is undefined for this
290 processor, so don't display anything. */
291 name = gdbarch_register_name (gdbarch, regnum);
292 if (name == 0 || *name == '\0')
296 &display_info->regs_content[pos]->which_element.data_window;
297 data = &((struct tui_win_element *)
298 data_item_win->content[0])->which_element.data;
301 if (!refresh_values_only)
303 data->item_no = regnum;
305 data->highlight = FALSE;
307 tui_get_register (frame, data, regnum, 0);
312 TUI_DATA_WIN->generic.content_size =
313 display_info->regs_content_count + display_info->data_content_count;
320 /* Function to display the registers in the content from
321 'start_element_no' until the end of the register content or the end
322 of the display height. No checking for displaying past the end of
323 the registers is done here. */
325 tui_display_registers_from (int start_element_no)
327 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
329 if (display_info->regs_content != (tui_win_content) NULL
330 && display_info->regs_content_count > 0)
332 int i = start_element_no;
333 int j, item_win_width, cur_y;
336 for (i = 0; i < display_info->regs_content_count; i++)
338 struct tui_data_element *data;
339 struct tui_gen_win_info *data_item_win;
344 = &display_info->regs_content[i]->which_element.data_window;
345 data = &((struct tui_win_element *)
346 data_item_win->content[0])->which_element.data;
353 len = 8 * ((len / 8) + 1);
361 item_win_width = max_len + 1;
362 i = start_element_no;
364 display_info->regs_column_count =
365 (TUI_DATA_WIN->generic.width - 2) / item_win_width;
366 if (display_info->regs_column_count == 0)
367 display_info->regs_column_count = 1;
369 (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
371 /* Now create each data "sub" window, and write the display into
374 while (i < display_info->regs_content_count
375 && cur_y <= TUI_DATA_WIN->generic.viewport_height)
378 j < display_info->regs_column_count
379 && i < display_info->regs_content_count;
382 struct tui_gen_win_info *data_item_win;
383 struct tui_data_element *data_element_ptr;
385 /* Create the window if necessary. */
386 data_item_win = &display_info->regs_content[i]
387 ->which_element.data_window;
388 data_element_ptr = &((struct tui_win_element *)
389 data_item_win->content[0])->which_element.data;
390 if (data_item_win->handle != (WINDOW*) NULL
391 && (data_item_win->height != 1
392 || data_item_win->width != item_win_width
393 || data_item_win->origin.x != (item_win_width * j) + 1
394 || data_item_win->origin.y != cur_y))
396 tui_delete_win (data_item_win->handle);
397 data_item_win->handle = 0;
400 if (data_item_win->handle == (WINDOW *) NULL)
402 data_item_win->height = 1;
403 data_item_win->width = item_win_width;
404 data_item_win->origin.x = (item_win_width * j) + 1;
405 data_item_win->origin.y = cur_y;
406 tui_make_window (data_item_win, DONT_BOX_WINDOW);
407 scrollok (data_item_win->handle, FALSE);
409 touchwin (data_item_win->handle);
411 /* Get the printable representation of the register
413 tui_display_register (data_element_ptr, data_item_win);
414 i++; /* Next register. */
416 cur_y++; /* Next row. */
422 /* Function to display the registers in the content from
423 'start_element_no' on 'start_line_no' until the end of the register
424 content or the end of the display height. This function checks
425 that we won't display off the end of the register display. */
427 tui_display_reg_element_at_line (int start_element_no,
430 if (TUI_DATA_WIN->detail.data_display_info.regs_content
431 != (tui_win_content) NULL
432 && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
434 int element_no = start_element_no;
436 if (start_element_no != 0 && start_line_no != 0)
438 int last_line_no, first_line_on_last_page;
440 last_line_no = tui_last_regs_line_no ();
441 first_line_on_last_page
442 = last_line_no - (TUI_DATA_WIN->generic.height - 2);
443 if (first_line_on_last_page < 0)
444 first_line_on_last_page = 0;
446 /* If there is no other data displayed except registers, and
447 the element_no causes us to scroll past the end of the
448 registers, adjust what element to really start the
450 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
451 && start_line_no > first_line_on_last_page)
453 = tui_first_reg_element_no_inline (first_line_on_last_page);
455 tui_display_registers_from (element_no);
461 /* Function to display the registers starting at line line_no in the
462 data window. Answers the line number that the display actually
463 started from. If nothing is displayed (-1) is returned. */
465 tui_display_registers_from_line (int line_no,
468 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
470 int line, element_no;
474 else if (force_display)
475 { /* If we must display regs (force_display is true), then
476 make sure that we don't display off the end of the
478 if (line_no >= tui_last_regs_line_no ())
480 if ((line = tui_line_from_reg_element_no (
481 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
490 element_no = tui_first_reg_element_no_inline (line);
492 < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
493 tui_display_reg_element_at_line (element_no, line);
500 return (-1); /* Nothing was displayed. */
504 /* This function check all displayed registers for changes in values,
505 given a particular frame. If the values have changed, they are
506 updated with the new value and highlighted. */
508 tui_check_register_values (struct frame_info *frame)
510 if (TUI_DATA_WIN != NULL
511 && TUI_DATA_WIN->generic.is_visible)
513 struct tui_data_info *display_info
514 = &TUI_DATA_WIN->detail.data_display_info;
516 if (display_info->regs_content_count <= 0
517 && display_info->display_regs)
518 tui_show_registers (display_info->current_group);
523 for (i = 0; (i < display_info->regs_content_count); i++)
525 struct tui_data_element *data;
526 struct tui_gen_win_info *data_item_win_ptr;
529 data_item_win_ptr = &display_info->regs_content[i]->
530 which_element.data_window;
531 data = &((struct tui_win_element *)
532 data_item_win_ptr->content[0])->which_element.data;
533 was_hilighted = data->highlight;
535 tui_get_register (frame, data,
536 data->item_no, &data->highlight);
538 if (data->highlight || was_hilighted)
540 tui_display_register (data, data_item_win_ptr);
547 /* Display a register in a window. If hilite is TRUE, then the value
548 will be displayed in reverse video. */
550 tui_display_register (struct tui_data_element *data,
551 struct tui_gen_win_info *win_info)
553 if (win_info->handle != (WINDOW *) NULL)
558 /* We ignore the return value, casting it to void in order to avoid
559 a compiler warning. The warning itself was introduced by a patch
560 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
561 to code that causes the compiler to generate an unused-value
563 (void) wstandout (win_info->handle);
565 wmove (win_info->handle, 0, 0);
566 for (i = 1; i < win_info->width; i++)
567 waddch (win_info->handle, ' ');
568 wmove (win_info->handle, 0, 0);
570 waddstr (win_info->handle, data->content);
573 /* We ignore the return value, casting it to void in order to avoid
574 a compiler warning. The warning itself was introduced by a patch
575 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
576 to code that causes the compiler to generate an unused-value
578 (void) wstandend (win_info->handle);
579 tui_refresh_win (win_info);
584 tui_reg_next_command (char *arg, int from_tty)
586 struct gdbarch *gdbarch = get_current_arch ();
588 if (TUI_DATA_WIN != 0)
590 struct reggroup *group
591 = TUI_DATA_WIN->detail.data_display_info.current_group;
593 group = reggroup_next (gdbarch, group);
595 group = reggroup_next (gdbarch, 0);
598 tui_show_registers (group);
603 tui_reg_float_command (char *arg, int from_tty)
605 tui_show_registers (float_reggroup);
609 tui_reg_general_command (char *arg, int from_tty)
611 tui_show_registers (general_reggroup);
615 tui_reg_system_command (char *arg, int from_tty)
617 tui_show_registers (system_reggroup);
620 static struct cmd_list_element *tuireglist;
623 tui_reg_command (char *args, int from_tty)
625 printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
626 "tui reg command.\n"));
627 help_list (tuireglist, "tui reg ", -1, gdb_stdout);
630 /* Provide a prototype to silence -Wmissing-prototypes. */
631 extern initialize_file_ftype _initialize_tui_regs;
634 _initialize_tui_regs (void)
636 struct cmd_list_element **tuicmd;
638 tuicmd = tui_get_cmd_list ();
640 add_prefix_cmd ("reg", class_tui, tui_reg_command,
641 _("TUI commands to control the register window."),
642 &tuireglist, "tui reg ", 0,
645 add_cmd ("float", class_tui, tui_reg_float_command,
646 _("Display only floating point registers."),
648 add_cmd ("general", class_tui, tui_reg_general_command,
649 _("Display only general registers."),
651 add_cmd ("system", class_tui, tui_reg_system_command,
652 _("Display only system registers."),
654 add_cmd ("next", class_tui, tui_reg_next_command,
655 _("Display next register group."),
660 add_com ("fr", class_tui, tui_reg_float_command,
661 _("Display only floating point registers\n"));
662 add_com ("gr", class_tui, tui_reg_general_command,
663 _("Display only general registers\n"));
664 add_com ("sr", class_tui, tui_reg_system_command,
665 _("Display only special registers\n"));
666 add_com ("+r", class_tui, tui_scroll_regs_forward_command,
667 _("Scroll the registers window forward\n"));
668 add_com ("-r", class_tui, tui_scroll_regs_backward_command,
669 _("Scroll the register window backward\n"));
674 /*****************************************
675 ** STATIC LOCAL FUNCTIONS **
676 ******************************************/
678 extern int pagination_enabled;
681 tui_restore_gdbout (void *ui)
683 ui_file_delete (gdb_stdout);
684 gdb_stdout = (struct ui_file*) ui;
685 pagination_enabled = 1;
688 /* Get the register from the frame and make a printable representation
689 of it in the data element. */
691 tui_register_format (struct frame_info *frame,
692 struct tui_data_element *data_element,
695 struct gdbarch *gdbarch = get_frame_arch (frame);
696 struct ui_file *stream;
697 struct ui_file *old_stdout;
699 struct cleanup *cleanups;
702 name = gdbarch_register_name (gdbarch, regnum);
703 if (name == 0 || *name == '\0')
706 pagination_enabled = 0;
707 old_stdout = gdb_stdout;
708 stream = tui_sfileopen (256);
710 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
711 gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
713 /* Save formatted output in the buffer. */
714 p = tui_file_get_strbuf (stream);
716 /* Remove the possible \n. */
717 s = strrchr (p, '\n');
721 xfree (data_element->content);
722 data_element->content = xstrdup (p);
723 do_cleanups (cleanups);
726 /* Get the register value from the given frame and format it for the
727 display. When changep is set, check if the new register value has
728 changed with respect to the previous call. */
729 static enum tui_status
730 tui_get_register (struct frame_info *frame,
731 struct tui_data_element *data,
732 int regnum, int *changedp)
734 enum tui_status ret = TUI_FAILURE;
738 if (target_has_registers)
740 struct value *old_val = data->value;
742 data->value = get_frame_register_value (frame, regnum);
743 release_value (data->value);
746 struct gdbarch *gdbarch = get_frame_arch (frame);
747 int size = register_size (gdbarch, regnum);
749 if (value_optimized_out (data->value) != value_optimized_out (old_val)
750 || !value_available_contents_eq (data->value, 0,
755 value_free (old_val);
757 /* Reformat the data content if the value changed. */
758 if (changedp == 0 || *changedp == TRUE)
759 tui_register_format (frame, data, regnum);
767 tui_scroll_regs_forward_command (char *arg, int from_tty)
769 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
774 tui_scroll_regs_backward_command (char *arg, int from_tty)
776 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);