📄 tui-regs.c
字号:
/* TUI display registers in window. Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by Hewlett-Packard Company. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "defs.h"#include "tui/tui.h"#include "tui/tui-data.h"#include "symtab.h"#include "gdbtypes.h"#include "gdbcmd.h"#include "frame.h"#include "regcache.h"#include "inferior.h"#include "target.h"#include "gdb_string.h"#include "tui/tui-layout.h"#include "tui/tui-win.h"#include "tui/tui-windata.h"#include "tui/tui-wingeneral.h"#include "tui/tui-file.h"#include "reggroups.h"#include "gdb_curses.h"/******************************************* STATIC LOCAL FUNCTIONS FORWARD DECLS ********************************************/static voidtui_display_register (struct tui_data_element *data, struct tui_gen_win_info *win_info);static enum tui_statustui_show_register_group (struct gdbarch *gdbarch, struct reggroup *group, struct frame_info *frame, int refresh_values_only);static enum tui_statustui_get_register (struct gdbarch *gdbarch, struct frame_info *frame, struct tui_data_element *data, int regnum, int *changedp);static void tui_register_format (struct gdbarch *, struct frame_info *, struct tui_data_element*, int);static void tui_scroll_regs_forward_command (char *, int);static void tui_scroll_regs_backward_command (char *, int);/******************************************* PUBLIC FUNCTIONS ********************************************//* Answer the number of the last line in the regs display. If there are no registers (-1) is returned. */inttui_last_regs_line_no (void){ int num_lines = (-1); if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) { num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count / TUI_DATA_WIN->detail.data_display_info.regs_column_count); if (TUI_DATA_WIN->detail.data_display_info.regs_content_count % TUI_DATA_WIN->detail.data_display_info.regs_column_count) num_lines++; } return num_lines;}/* Answer the line number that the register element at element_no is on. If element_no is greater than the number of register elements there are, -1 is returned. */inttui_line_from_reg_element_no (int element_no){ if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) { int i, line = (-1); i = 1; while (line == (-1)) { if (element_no < (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i)) line = i - 1; else i++; } return line; } else return (-1);}/* Answer the index of the first element in line_no. If line_no is past the register area (-1) is returned. */inttui_first_reg_element_no_inline (int line_no){ if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <= TUI_DATA_WIN->detail.data_display_info.regs_content_count) return ((line_no + 1) * TUI_DATA_WIN->detail.data_display_info.regs_column_count) - TUI_DATA_WIN->detail.data_display_info.regs_column_count; else return (-1);}/* Answer the index of the last element in line_no. If line_no is past the register area (-1) is returned. */inttui_last_reg_element_no_in_line (int line_no){ if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) <= TUI_DATA_WIN->detail.data_display_info.regs_content_count) return ((line_no + 1) * TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 1; else return (-1);}/* Show the registers of the given group in the data window and refresh the window. */voidtui_show_registers (struct reggroup *group){ enum tui_status ret = TUI_FAILURE; struct tui_data_info *display_info; /* Make sure the curses mode is enabled. */ tui_enable (); /* Make sure the register window is visible. If not, select an appropriate layout. */ if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) tui_set_layout_for_display_command (DATA_NAME); display_info = &TUI_DATA_WIN->detail.data_display_info; if (group == 0) group = general_reggroup; /* Say that registers should be displayed, even if there is a problem. */ display_info->display_regs = TRUE; if (target_has_registers && target_has_stack && target_has_memory) { ret = tui_show_register_group (current_gdbarch, group, get_current_frame (), group == display_info->current_group); } if (ret == TUI_FAILURE) { display_info->current_group = 0; tui_erase_data_content (NO_REGS_STRING); } else { int i; /* Clear all notation of changed values */ for (i = 0; i < display_info->regs_content_count; i++) { struct tui_gen_win_info *data_item_win; struct tui_win_element *win; data_item_win = &display_info->regs_content[i] ->which_element.data_window; win = (struct tui_win_element *) data_item_win->content[0]; win->which_element.data.highlight = FALSE; } display_info->current_group = group; tui_display_all_data (); }}/* Set the data window to display the registers of the register group using the given frame. Values are refreshed only when refresh_values_only is TRUE. */static enum tui_statustui_show_register_group (struct gdbarch *gdbarch, struct reggroup *group, struct frame_info *frame, int refresh_values_only){ enum tui_status ret = TUI_FAILURE; int nr_regs; int allocated_here = FALSE; int regnum, pos; char title[80]; struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; /* Make a new title showing which group we display. */ snprintf (title, sizeof (title) - 1, "Register group: %s", reggroup_name (group)); xfree (TUI_DATA_WIN->generic.title); TUI_DATA_WIN->generic.title = xstrdup (title); /* See how many registers must be displayed. */ nr_regs = 0; for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { /* Must be in the group and have a name. */ if (gdbarch_register_reggroup_p (gdbarch, regnum, group) && gdbarch_register_name (gdbarch, regnum) != 0) nr_regs++; } if (display_info->regs_content_count > 0 && !refresh_values_only) { tui_free_data_content (display_info->regs_content, display_info->regs_content_count); display_info->regs_content_count = 0; } if (display_info->regs_content_count <= 0) { display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN); allocated_here = TRUE; refresh_values_only = FALSE; } if (display_info->regs_content != (tui_win_content) NULL) { if (!refresh_values_only || allocated_here) { TUI_DATA_WIN->generic.content = (void*) NULL; TUI_DATA_WIN->generic.content_size = 0; tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs); display_info->regs_content = (tui_win_content) TUI_DATA_WIN->generic.content; display_info->regs_content_count = nr_regs; } /* Now set the register names and values */ pos = 0; for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { struct tui_gen_win_info *data_item_win; struct tui_data_element *data; const char *name; if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) continue; name = gdbarch_register_name (gdbarch, regnum); if (name == 0) continue; data_item_win = &display_info->regs_content[pos]->which_element.data_window; data = &((struct tui_win_element *) data_item_win->content[0])->which_element.data; if (data) { if (!refresh_values_only) { data->item_no = regnum; data->name = name; data->highlight = FALSE; } if (data->value == (void*) NULL) data->value = (void*) xmalloc (MAX_REGISTER_SIZE); tui_get_register (gdbarch, frame, data, regnum, 0); } pos++; } TUI_DATA_WIN->generic.content_size = display_info->regs_content_count + display_info->data_content_count; ret = TUI_SUCCESS; } return ret;}/* Function to display the registers in the content from 'start_element_no' until the end of the register content or the end of the display height. No checking for displaying past the end of the registers is done here. */voidtui_display_registers_from (int start_element_no){ struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; if (display_info->regs_content != (tui_win_content) NULL && display_info->regs_content_count > 0) { int i = start_element_no; int j, value_chars_wide, item_win_width, cur_y; int max_len = 0; for (i = 0; i < display_info->regs_content_count; i++) { struct tui_data_element *data; struct tui_gen_win_info *data_item_win; char *p; int len; data_item_win = &display_info->regs_content[i]->which_element.data_window; data = &((struct tui_win_element *) data_item_win->content[0])->which_element.data; len = 0; p = data->content; if (p != 0) while (*p) { if (*p++ == '\t') len = 8 * ((len / 8) + 1); else len++; } if (len > max_len) max_len = len; } item_win_width = max_len + 1; i = start_element_no; display_info->regs_column_count = (TUI_DATA_WIN->generic.width - 2) / item_win_width; if (display_info->regs_column_count == 0) display_info->regs_column_count = 1; item_win_width = (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count; /* ** Now create each data "sub" window, and write the display into it. */ cur_y = 1; while (i < display_info->regs_content_count && cur_y <= TUI_DATA_WIN->generic.viewport_height) { for (j = 0; (j < display_info->regs_column_count && i < display_info->regs_content_count); j++) { struct tui_gen_win_info * data_item_win; struct tui_data_element * data_element_ptr; /* create the window if necessary */ data_item_win = &display_info->regs_content[i] ->which_element.data_window; data_element_ptr = &((struct tui_win_element *) data_item_win->content[0])->which_element.data; if (data_item_win->handle != (WINDOW*) NULL && (data_item_win->height != 1 || data_item_win->width != item_win_width || data_item_win->origin.x != (item_win_width * j) + 1 || data_item_win->origin.y != cur_y)) { tui_delete_win (data_item_win->handle); data_item_win->handle = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -