Home | History | Annotate | Line # | Download | only in tui
tui-regs.c revision 1.5
      1  1.1  christos /* TUI display registers in window.
      2  1.1  christos 
      3  1.3  christos    Copyright (C) 1998-2015 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    Contributed by Hewlett-Packard Company.
      6  1.1  christos 
      7  1.1  christos    This file is part of GDB.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     21  1.1  christos 
     22  1.1  christos #include "defs.h"
     23  1.1  christos #include "arch-utils.h"
     24  1.1  christos #include "tui/tui.h"
     25  1.1  christos #include "tui/tui-data.h"
     26  1.1  christos #include "symtab.h"
     27  1.1  christos #include "gdbtypes.h"
     28  1.1  christos #include "gdbcmd.h"
     29  1.1  christos #include "frame.h"
     30  1.1  christos #include "regcache.h"
     31  1.1  christos #include "inferior.h"
     32  1.1  christos #include "target.h"
     33  1.1  christos #include "tui/tui-layout.h"
     34  1.1  christos #include "tui/tui-win.h"
     35  1.1  christos #include "tui/tui-windata.h"
     36  1.1  christos #include "tui/tui-wingeneral.h"
     37  1.1  christos #include "tui/tui-file.h"
     38  1.1  christos #include "tui/tui-regs.h"
     39  1.3  christos #include "tui/tui-io.h"
     40  1.1  christos #include "reggroups.h"
     41  1.1  christos #include "valprint.h"
     42  1.5  christos #include "completer.h"
     43  1.1  christos 
     44  1.1  christos #include "gdb_curses.h"
     45  1.1  christos 
     46  1.1  christos 
     47  1.1  christos /*****************************************
     48  1.1  christos ** STATIC LOCAL FUNCTIONS FORWARD DECLS    **
     49  1.1  christos ******************************************/
     50  1.1  christos static void
     51  1.1  christos tui_display_register (struct tui_data_element *data,
     52  1.1  christos                       struct tui_gen_win_info *win_info);
     53  1.1  christos 
     54  1.1  christos static enum tui_status tui_show_register_group (struct reggroup *group,
     55  1.1  christos 						struct frame_info *frame,
     56  1.1  christos 						int refresh_values_only);
     57  1.1  christos 
     58  1.1  christos static enum tui_status tui_get_register (struct frame_info *frame,
     59  1.1  christos 					 struct tui_data_element *data,
     60  1.1  christos 					 int regnum, int *changedp);
     61  1.1  christos 
     62  1.1  christos 
     63  1.1  christos 
     64  1.1  christos /*****************************************
     65  1.1  christos ** PUBLIC FUNCTIONS                     **
     66  1.1  christos ******************************************/
     67  1.1  christos 
     68  1.1  christos /* Answer the number of the last line in the regs display.  If there
     69  1.1  christos    are no registers (-1) is returned.  */
     70  1.1  christos int
     71  1.1  christos tui_last_regs_line_no (void)
     72  1.1  christos {
     73  1.1  christos   int num_lines = (-1);
     74  1.1  christos 
     75  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
     76  1.1  christos     {
     77  1.1  christos       num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
     78  1.1  christos 		  TUI_DATA_WIN->detail.data_display_info.regs_column_count);
     79  1.1  christos       if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
     80  1.1  christos 	  TUI_DATA_WIN->detail.data_display_info.regs_column_count)
     81  1.1  christos 	num_lines++;
     82  1.1  christos     }
     83  1.1  christos   return num_lines;
     84  1.1  christos }
     85  1.1  christos 
     86  1.1  christos 
     87  1.1  christos /* Answer the line number that the register element at element_no is
     88  1.1  christos    on.  If element_no is greater than the number of register elements
     89  1.1  christos    there are, -1 is returned.  */
     90  1.1  christos int
     91  1.1  christos tui_line_from_reg_element_no (int element_no)
     92  1.1  christos {
     93  1.1  christos   if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
     94  1.1  christos     {
     95  1.1  christos       int i, line = (-1);
     96  1.1  christos 
     97  1.1  christos       i = 1;
     98  1.1  christos       while (line == (-1))
     99  1.1  christos 	{
    100  1.1  christos 	  if (element_no <
    101  1.1  christos 	      (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
    102  1.1  christos 	    line = i - 1;
    103  1.1  christos 	  else
    104  1.1  christos 	    i++;
    105  1.1  christos 	}
    106  1.1  christos 
    107  1.1  christos       return line;
    108  1.1  christos     }
    109  1.1  christos   else
    110  1.1  christos     return (-1);
    111  1.1  christos }
    112  1.1  christos 
    113  1.1  christos 
    114  1.1  christos /* Answer the index of the first element in line_no.  If line_no is
    115  1.1  christos    past the register area (-1) is returned.  */
    116  1.1  christos int
    117  1.1  christos tui_first_reg_element_no_inline (int line_no)
    118  1.1  christos {
    119  1.1  christos   if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
    120  1.1  christos       <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
    121  1.1  christos     return ((line_no + 1) *
    122  1.1  christos 	    TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
    123  1.1  christos       TUI_DATA_WIN->detail.data_display_info.regs_column_count;
    124  1.1  christos   else
    125  1.1  christos     return (-1);
    126  1.1  christos }
    127  1.1  christos 
    128  1.1  christos 
    129  1.1  christos /* Show the registers of the given group in the data window
    130  1.1  christos    and refresh the window.  */
    131  1.1  christos void
    132  1.1  christos tui_show_registers (struct reggroup *group)
    133  1.1  christos {
    134  1.1  christos   enum tui_status ret = TUI_FAILURE;
    135  1.1  christos   struct tui_data_info *display_info;
    136  1.1  christos 
    137  1.1  christos   /* Make sure the curses mode is enabled.  */
    138  1.1  christos   tui_enable ();
    139  1.1  christos 
    140  1.1  christos   /* Make sure the register window is visible.  If not, select an
    141  1.1  christos      appropriate layout.  */
    142  1.1  christos   if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
    143  1.5  christos     tui_set_layout_by_name (DATA_NAME);
    144  1.1  christos 
    145  1.1  christos   display_info = &TUI_DATA_WIN->detail.data_display_info;
    146  1.1  christos   if (group == 0)
    147  1.1  christos     group = general_reggroup;
    148  1.1  christos 
    149  1.1  christos   /* Say that registers should be displayed, even if there is a
    150  1.1  christos      problem.  */
    151  1.1  christos   display_info->display_regs = TRUE;
    152  1.1  christos 
    153  1.1  christos   if (target_has_registers && target_has_stack && target_has_memory)
    154  1.1  christos     {
    155  1.1  christos       ret = tui_show_register_group (group, get_selected_frame (NULL),
    156  1.1  christos                                      group == display_info->current_group);
    157  1.1  christos     }
    158  1.1  christos   if (ret == TUI_FAILURE)
    159  1.1  christos     {
    160  1.1  christos       display_info->current_group = 0;
    161  1.1  christos       tui_erase_data_content (NO_REGS_STRING);
    162  1.1  christos     }
    163  1.1  christos   else
    164  1.1  christos     {
    165  1.1  christos       int i;
    166  1.1  christos 
    167  1.1  christos       /* Clear all notation of changed values.  */
    168  1.1  christos       for (i = 0; i < display_info->regs_content_count; i++)
    169  1.1  christos 	{
    170  1.1  christos 	  struct tui_gen_win_info *data_item_win;
    171  1.1  christos           struct tui_win_element *win;
    172  1.1  christos 
    173  1.1  christos 	  data_item_win = &display_info->regs_content[i]
    174  1.1  christos             ->which_element.data_window;
    175  1.5  christos           win = data_item_win->content[0];
    176  1.1  christos           win->which_element.data.highlight = FALSE;
    177  1.1  christos 	}
    178  1.1  christos       display_info->current_group = group;
    179  1.1  christos       tui_display_all_data ();
    180  1.1  christos     }
    181  1.1  christos }
    182  1.1  christos 
    183  1.1  christos 
    184  1.1  christos /* Set the data window to display the registers of the register group
    185  1.1  christos    using the given frame.  Values are refreshed only when
    186  1.1  christos    refresh_values_only is TRUE.  */
    187  1.1  christos 
    188  1.1  christos static enum tui_status
    189  1.1  christos tui_show_register_group (struct reggroup *group,
    190  1.1  christos                          struct frame_info *frame,
    191  1.1  christos 			 int refresh_values_only)
    192  1.1  christos {
    193  1.1  christos   struct gdbarch *gdbarch = get_frame_arch (frame);
    194  1.1  christos   enum tui_status ret = TUI_FAILURE;
    195  1.1  christos   int nr_regs;
    196  1.1  christos   int allocated_here = FALSE;
    197  1.1  christos   int regnum, pos;
    198  1.1  christos   char title[80];
    199  1.1  christos   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
    200  1.1  christos 
    201  1.1  christos   /* Make a new title showing which group we display.  */
    202  1.1  christos   snprintf (title, sizeof (title) - 1, "Register group: %s",
    203  1.1  christos             reggroup_name (group));
    204  1.1  christos   xfree (TUI_DATA_WIN->generic.title);
    205  1.1  christos   TUI_DATA_WIN->generic.title = xstrdup (title);
    206  1.1  christos 
    207  1.1  christos   /* See how many registers must be displayed.  */
    208  1.1  christos   nr_regs = 0;
    209  1.1  christos   for (regnum = 0;
    210  1.1  christos        regnum < gdbarch_num_regs (gdbarch)
    211  1.1  christos 		+ gdbarch_num_pseudo_regs (gdbarch);
    212  1.1  christos        regnum++)
    213  1.1  christos     {
    214  1.1  christos       const char *name;
    215  1.1  christos 
    216  1.1  christos       /* Must be in the group.  */
    217  1.1  christos       if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
    218  1.1  christos 	continue;
    219  1.1  christos 
    220  1.1  christos       /* If the register name is empty, it is undefined for this
    221  1.1  christos 	 processor, so don't display anything.  */
    222  1.1  christos       name = gdbarch_register_name (gdbarch, regnum);
    223  1.1  christos       if (name == 0 || *name == '\0')
    224  1.1  christos 	continue;
    225  1.1  christos 
    226  1.1  christos       nr_regs++;
    227  1.1  christos     }
    228  1.1  christos 
    229  1.1  christos   if (display_info->regs_content_count > 0 && !refresh_values_only)
    230  1.1  christos     {
    231  1.1  christos       tui_free_data_content (display_info->regs_content,
    232  1.1  christos                              display_info->regs_content_count);
    233  1.1  christos       display_info->regs_content_count = 0;
    234  1.1  christos     }
    235  1.1  christos 
    236  1.1  christos   if (display_info->regs_content_count <= 0)
    237  1.1  christos     {
    238  1.1  christos       display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
    239  1.1  christos       allocated_here = TRUE;
    240  1.1  christos       refresh_values_only = FALSE;
    241  1.1  christos     }
    242  1.1  christos 
    243  1.1  christos   if (display_info->regs_content != (tui_win_content) NULL)
    244  1.1  christos     {
    245  1.1  christos       if (!refresh_values_only || allocated_here)
    246  1.1  christos 	{
    247  1.1  christos 	  TUI_DATA_WIN->generic.content = (void*) NULL;
    248  1.1  christos 	  TUI_DATA_WIN->generic.content_size = 0;
    249  1.1  christos 	  tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
    250  1.1  christos 	  display_info->regs_content
    251  1.1  christos             = (tui_win_content) TUI_DATA_WIN->generic.content;
    252  1.1  christos 	  display_info->regs_content_count = nr_regs;
    253  1.1  christos 	}
    254  1.1  christos 
    255  1.1  christos       /* Now set the register names and values.  */
    256  1.1  christos       pos = 0;
    257  1.1  christos       for (regnum = 0;
    258  1.1  christos 	   regnum < gdbarch_num_regs (gdbarch)
    259  1.1  christos 		    + gdbarch_num_pseudo_regs (gdbarch);
    260  1.1  christos 	   regnum++)
    261  1.1  christos         {
    262  1.1  christos 	  struct tui_gen_win_info *data_item_win;
    263  1.1  christos           struct tui_data_element *data;
    264  1.1  christos           const char *name;
    265  1.1  christos 
    266  1.1  christos           /* Must be in the group.  */
    267  1.1  christos           if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
    268  1.1  christos             continue;
    269  1.1  christos 
    270  1.1  christos 	  /* If the register name is empty, it is undefined for this
    271  1.1  christos 	     processor, so don't display anything.  */
    272  1.1  christos 	  name = gdbarch_register_name (gdbarch, regnum);
    273  1.1  christos 	  if (name == 0 || *name == '\0')
    274  1.1  christos 	    continue;
    275  1.1  christos 
    276  1.1  christos 	  data_item_win =
    277  1.1  christos             &display_info->regs_content[pos]->which_element.data_window;
    278  1.5  christos           data = &data_item_win->content[0]->which_element.data;
    279  1.1  christos           if (data)
    280  1.1  christos             {
    281  1.1  christos               if (!refresh_values_only)
    282  1.1  christos                 {
    283  1.1  christos                   data->item_no = regnum;
    284  1.1  christos                   data->name = name;
    285  1.1  christos                   data->highlight = FALSE;
    286  1.1  christos                 }
    287  1.1  christos               tui_get_register (frame, data, regnum, 0);
    288  1.1  christos             }
    289  1.1  christos           pos++;
    290  1.1  christos 	}
    291  1.1  christos 
    292  1.1  christos       TUI_DATA_WIN->generic.content_size =
    293  1.1  christos 	display_info->regs_content_count + display_info->data_content_count;
    294  1.1  christos       ret = TUI_SUCCESS;
    295  1.1  christos     }
    296  1.1  christos 
    297  1.1  christos   return ret;
    298  1.1  christos }
    299  1.1  christos 
    300  1.1  christos /* Function to display the registers in the content from
    301  1.1  christos    'start_element_no' until the end of the register content or the end
    302  1.1  christos    of the display height.  No checking for displaying past the end of
    303  1.1  christos    the registers is done here.  */
    304  1.1  christos void
    305  1.1  christos tui_display_registers_from (int start_element_no)
    306  1.1  christos {
    307  1.1  christos   struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
    308  1.1  christos 
    309  1.1  christos   if (display_info->regs_content != (tui_win_content) NULL
    310  1.1  christos       && display_info->regs_content_count > 0)
    311  1.1  christos     {
    312  1.1  christos       int i = start_element_no;
    313  1.1  christos       int j, item_win_width, cur_y;
    314  1.1  christos 
    315  1.1  christos       int max_len = 0;
    316  1.1  christos       for (i = 0; i < display_info->regs_content_count; i++)
    317  1.1  christos         {
    318  1.1  christos           struct tui_data_element *data;
    319  1.1  christos           struct tui_gen_win_info *data_item_win;
    320  1.1  christos           char *p;
    321  1.1  christos           int len;
    322  1.1  christos 
    323  1.1  christos           data_item_win
    324  1.1  christos 	    = &display_info->regs_content[i]->which_element.data_window;
    325  1.5  christos           data = &data_item_win->content[0]->which_element.data;
    326  1.1  christos           len = 0;
    327  1.1  christos           p = data->content;
    328  1.1  christos           if (p != 0)
    329  1.1  christos             while (*p)
    330  1.1  christos               {
    331  1.1  christos                 if (*p++ == '\t')
    332  1.1  christos                   len = 8 * ((len / 8) + 1);
    333  1.1  christos                 else
    334  1.1  christos                   len++;
    335  1.1  christos               }
    336  1.1  christos 
    337  1.1  christos           if (len > max_len)
    338  1.1  christos             max_len = len;
    339  1.1  christos         }
    340  1.1  christos       item_win_width = max_len + 1;
    341  1.1  christos       i = start_element_no;
    342  1.1  christos 
    343  1.1  christos       display_info->regs_column_count =
    344  1.1  christos         (TUI_DATA_WIN->generic.width - 2) / item_win_width;
    345  1.1  christos       if (display_info->regs_column_count == 0)
    346  1.1  christos         display_info->regs_column_count = 1;
    347  1.1  christos       item_win_width =
    348  1.1  christos         (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
    349  1.1  christos 
    350  1.1  christos       /* Now create each data "sub" window, and write the display into
    351  1.1  christos 	 it.  */
    352  1.1  christos       cur_y = 1;
    353  1.1  christos       while (i < display_info->regs_content_count
    354  1.1  christos 	     && cur_y <= TUI_DATA_WIN->generic.viewport_height)
    355  1.1  christos 	{
    356  1.1  christos 	  for (j = 0;
    357  1.1  christos 	       j < display_info->regs_column_count
    358  1.1  christos 		 && i < display_info->regs_content_count;
    359  1.1  christos 	       j++)
    360  1.1  christos 	    {
    361  1.1  christos 	      struct tui_gen_win_info *data_item_win;
    362  1.1  christos 	      struct tui_data_element *data_element_ptr;
    363  1.1  christos 
    364  1.1  christos 	      /* Create the window if necessary.  */
    365  1.1  christos 	      data_item_win = &display_info->regs_content[i]
    366  1.1  christos                 ->which_element.data_window;
    367  1.5  christos 	      data_element_ptr = &data_item_win->content[0]->which_element.data;
    368  1.1  christos               if (data_item_win->handle != (WINDOW*) NULL
    369  1.1  christos                   && (data_item_win->height != 1
    370  1.1  christos                       || data_item_win->width != item_win_width
    371  1.1  christos                       || data_item_win->origin.x != (item_win_width * j) + 1
    372  1.1  christos                       || data_item_win->origin.y != cur_y))
    373  1.1  christos                 {
    374  1.1  christos                   tui_delete_win (data_item_win->handle);
    375  1.1  christos                   data_item_win->handle = 0;
    376  1.1  christos                 }
    377  1.1  christos 
    378  1.1  christos 	      if (data_item_win->handle == (WINDOW *) NULL)
    379  1.1  christos 		{
    380  1.1  christos 		  data_item_win->height = 1;
    381  1.1  christos 		  data_item_win->width = item_win_width;
    382  1.1  christos 		  data_item_win->origin.x = (item_win_width * j) + 1;
    383  1.1  christos 		  data_item_win->origin.y = cur_y;
    384  1.1  christos 		  tui_make_window (data_item_win, DONT_BOX_WINDOW);
    385  1.1  christos                   scrollok (data_item_win->handle, FALSE);
    386  1.1  christos 		}
    387  1.1  christos               touchwin (data_item_win->handle);
    388  1.1  christos 
    389  1.1  christos 	      /* Get the printable representation of the register
    390  1.1  christos                  and display it.  */
    391  1.1  christos               tui_display_register (data_element_ptr, data_item_win);
    392  1.1  christos 	      i++;		/* Next register.  */
    393  1.1  christos 	    }
    394  1.1  christos 	  cur_y++;		/* Next row.  */
    395  1.1  christos 	}
    396  1.1  christos     }
    397  1.1  christos }
    398  1.1  christos 
    399  1.1  christos 
    400  1.1  christos /* Function to display the registers in the content from
    401  1.1  christos    'start_element_no' on 'start_line_no' until the end of the register
    402  1.1  christos    content or the end of the display height.  This function checks
    403  1.1  christos    that we won't display off the end of the register display.  */
    404  1.1  christos static void
    405  1.1  christos tui_display_reg_element_at_line (int start_element_no,
    406  1.1  christos 				 int start_line_no)
    407  1.1  christos {
    408  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content
    409  1.1  christos       != (tui_win_content) NULL
    410  1.1  christos       && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
    411  1.1  christos     {
    412  1.1  christos       int element_no = start_element_no;
    413  1.1  christos 
    414  1.1  christos       if (start_element_no != 0 && start_line_no != 0)
    415  1.1  christos 	{
    416  1.1  christos 	  int last_line_no, first_line_on_last_page;
    417  1.1  christos 
    418  1.1  christos 	  last_line_no = tui_last_regs_line_no ();
    419  1.1  christos 	  first_line_on_last_page
    420  1.1  christos 	    = last_line_no - (TUI_DATA_WIN->generic.height - 2);
    421  1.1  christos 	  if (first_line_on_last_page < 0)
    422  1.1  christos 	    first_line_on_last_page = 0;
    423  1.1  christos 
    424  1.1  christos 	  /* If there is no other data displayed except registers, and
    425  1.1  christos 	     the element_no causes us to scroll past the end of the
    426  1.1  christos 	     registers, adjust what element to really start the
    427  1.1  christos 	     display at.  */
    428  1.1  christos 	  if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
    429  1.1  christos 	      && start_line_no > first_line_on_last_page)
    430  1.1  christos 	    element_no
    431  1.1  christos 	      = tui_first_reg_element_no_inline (first_line_on_last_page);
    432  1.1  christos 	}
    433  1.1  christos       tui_display_registers_from (element_no);
    434  1.1  christos     }
    435  1.1  christos }
    436  1.1  christos 
    437  1.1  christos 
    438  1.1  christos 
    439  1.1  christos /* Function to display the registers starting at line line_no in the
    440  1.1  christos    data window.  Answers the line number that the display actually
    441  1.1  christos    started from.  If nothing is displayed (-1) is returned.  */
    442  1.1  christos int
    443  1.1  christos tui_display_registers_from_line (int line_no,
    444  1.1  christos 				 int force_display)
    445  1.1  christos {
    446  1.1  christos   if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
    447  1.1  christos     {
    448  1.1  christos       int line, element_no;
    449  1.1  christos 
    450  1.1  christos       if (line_no < 0)
    451  1.1  christos 	line = 0;
    452  1.1  christos       else if (force_display)
    453  1.1  christos 	{ /* If we must display regs (force_display is true), then
    454  1.1  christos 	     make sure that we don't display off the end of the
    455  1.1  christos 	     registers.  */
    456  1.1  christos 	  if (line_no >= tui_last_regs_line_no ())
    457  1.1  christos 	    {
    458  1.1  christos 	      if ((line = tui_line_from_reg_element_no (
    459  1.1  christos 		 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
    460  1.1  christos 		line = 0;
    461  1.1  christos 	    }
    462  1.1  christos 	  else
    463  1.1  christos 	    line = line_no;
    464  1.1  christos 	}
    465  1.1  christos       else
    466  1.1  christos 	line = line_no;
    467  1.1  christos 
    468  1.1  christos       element_no = tui_first_reg_element_no_inline (line);
    469  1.1  christos       if (element_no
    470  1.1  christos 	  < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
    471  1.1  christos 	tui_display_reg_element_at_line (element_no, line);
    472  1.1  christos       else
    473  1.1  christos 	line = (-1);
    474  1.1  christos 
    475  1.1  christos       return line;
    476  1.1  christos     }
    477  1.1  christos 
    478  1.1  christos   return (-1);			/* Nothing was displayed.  */
    479  1.1  christos }
    480  1.1  christos 
    481  1.1  christos 
    482  1.1  christos /* This function check all displayed registers for changes in values,
    483  1.1  christos    given a particular frame.  If the values have changed, they are
    484  1.1  christos    updated with the new value and highlighted.  */
    485  1.1  christos void
    486  1.1  christos tui_check_register_values (struct frame_info *frame)
    487  1.1  christos {
    488  1.1  christos   if (TUI_DATA_WIN != NULL
    489  1.1  christos       && TUI_DATA_WIN->generic.is_visible)
    490  1.1  christos     {
    491  1.1  christos       struct tui_data_info *display_info
    492  1.1  christos         = &TUI_DATA_WIN->detail.data_display_info;
    493  1.1  christos 
    494  1.1  christos       if (display_info->regs_content_count <= 0
    495  1.1  christos 	  && display_info->display_regs)
    496  1.1  christos 	tui_show_registers (display_info->current_group);
    497  1.1  christos       else
    498  1.1  christos 	{
    499  1.1  christos 	  int i;
    500  1.1  christos 
    501  1.1  christos 	  for (i = 0; (i < display_info->regs_content_count); i++)
    502  1.1  christos 	    {
    503  1.1  christos 	      struct tui_data_element *data;
    504  1.1  christos 	      struct tui_gen_win_info *data_item_win_ptr;
    505  1.1  christos 	      int was_hilighted;
    506  1.1  christos 
    507  1.1  christos 	      data_item_win_ptr = &display_info->regs_content[i]->
    508  1.1  christos                 which_element.data_window;
    509  1.5  christos 	      data = &data_item_win_ptr->content[0]->which_element.data;
    510  1.1  christos 	      was_hilighted = data->highlight;
    511  1.1  christos 
    512  1.1  christos               tui_get_register (frame, data,
    513  1.1  christos                                 data->item_no, &data->highlight);
    514  1.1  christos 
    515  1.1  christos 	      if (data->highlight || was_hilighted)
    516  1.1  christos 		{
    517  1.1  christos                   tui_display_register (data, data_item_win_ptr);
    518  1.1  christos 		}
    519  1.1  christos 	    }
    520  1.1  christos 	}
    521  1.1  christos     }
    522  1.1  christos }
    523  1.1  christos 
    524  1.1  christos /* Display a register in a window.  If hilite is TRUE, then the value
    525  1.1  christos    will be displayed in reverse video.  */
    526  1.1  christos static void
    527  1.1  christos tui_display_register (struct tui_data_element *data,
    528  1.1  christos                       struct tui_gen_win_info *win_info)
    529  1.1  christos {
    530  1.1  christos   if (win_info->handle != (WINDOW *) NULL)
    531  1.1  christos     {
    532  1.1  christos       int i;
    533  1.1  christos 
    534  1.1  christos       if (data->highlight)
    535  1.1  christos 	/* We ignore the return value, casting it to void in order to avoid
    536  1.1  christos 	   a compiler warning.  The warning itself was introduced by a patch
    537  1.1  christos 	   to ncurses 5.7 dated 2009-08-29, changing this macro to expand
    538  1.1  christos 	   to code that causes the compiler to generate an unused-value
    539  1.1  christos 	   warning.  */
    540  1.1  christos 	(void) wstandout (win_info->handle);
    541  1.1  christos 
    542  1.1  christos       wmove (win_info->handle, 0, 0);
    543  1.1  christos       for (i = 1; i < win_info->width; i++)
    544  1.1  christos         waddch (win_info->handle, ' ');
    545  1.1  christos       wmove (win_info->handle, 0, 0);
    546  1.1  christos       if (data->content)
    547  1.1  christos         waddstr (win_info->handle, data->content);
    548  1.1  christos 
    549  1.1  christos       if (data->highlight)
    550  1.1  christos 	/* We ignore the return value, casting it to void in order to avoid
    551  1.1  christos 	   a compiler warning.  The warning itself was introduced by a patch
    552  1.1  christos 	   to ncurses 5.7 dated 2009-08-29, changing this macro to expand
    553  1.1  christos 	   to code that causes the compiler to generate an unused-value
    554  1.1  christos 	   warning.  */
    555  1.1  christos 	(void) wstandend (win_info->handle);
    556  1.1  christos       tui_refresh_win (win_info);
    557  1.1  christos     }
    558  1.1  christos }
    559  1.1  christos 
    560  1.5  christos /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
    561  1.5  christos    around behaviour.  Returns the next register group, or NULL if the
    562  1.5  christos    register window is not currently being displayed.  */
    563  1.5  christos 
    564  1.5  christos static struct reggroup *
    565  1.5  christos tui_reg_next (struct gdbarch *gdbarch)
    566  1.1  christos {
    567  1.5  christos   struct reggroup *group = NULL;
    568  1.1  christos 
    569  1.5  christos   if (TUI_DATA_WIN != NULL)
    570  1.1  christos     {
    571  1.5  christos       group = TUI_DATA_WIN->detail.data_display_info.current_group;
    572  1.1  christos       group = reggroup_next (gdbarch, group);
    573  1.5  christos       if (group == NULL)
    574  1.5  christos         group = reggroup_next (gdbarch, NULL);
    575  1.1  christos     }
    576  1.5  christos   return group;
    577  1.1  christos }
    578  1.1  christos 
    579  1.5  christos /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
    580  1.5  christos    around behaviour.  Returns the previous register group, or NULL if the
    581  1.5  christos    register window is not currently being displayed.  */
    582  1.5  christos 
    583  1.5  christos static struct reggroup *
    584  1.5  christos tui_reg_prev (struct gdbarch *gdbarch)
    585  1.1  christos {
    586  1.5  christos   struct reggroup *group = NULL;
    587  1.5  christos 
    588  1.5  christos   if (TUI_DATA_WIN != NULL)
    589  1.5  christos     {
    590  1.5  christos       group = TUI_DATA_WIN->detail.data_display_info.current_group;
    591  1.5  christos       group = reggroup_prev (gdbarch, group);
    592  1.5  christos       if (group == NULL)
    593  1.5  christos 	group = reggroup_prev (gdbarch, NULL);
    594  1.5  christos     }
    595  1.5  christos   return group;
    596  1.1  christos }
    597  1.1  christos 
    598  1.5  christos /* Implement the 'tui reg' command.  Changes the register group displayed
    599  1.5  christos    in the tui register window.  Displays the tui register window if it is
    600  1.5  christos    not already on display.  */
    601  1.5  christos 
    602  1.1  christos static void
    603  1.5  christos tui_reg_command (char *args, int from_tty)
    604  1.1  christos {
    605  1.5  christos   struct gdbarch *gdbarch = get_current_arch ();
    606  1.5  christos 
    607  1.5  christos   if (args != NULL)
    608  1.5  christos     {
    609  1.5  christos       struct reggroup *group, *match = NULL;
    610  1.5  christos       size_t len = strlen (args);
    611  1.5  christos 
    612  1.5  christos       /* Make sure the curses mode is enabled.  */
    613  1.5  christos       tui_enable ();
    614  1.5  christos 
    615  1.5  christos       /* Make sure the register window is visible.  If not, select an
    616  1.5  christos 	 appropriate layout.  We need to do this before trying to run the
    617  1.5  christos 	 'next' or 'prev' commands.  */
    618  1.5  christos       if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
    619  1.5  christos 	tui_set_layout_by_name (DATA_NAME);
    620  1.5  christos 
    621  1.5  christos       if (strncmp (args, "next", len) == 0)
    622  1.5  christos 	match = tui_reg_next (gdbarch);
    623  1.5  christos       else if (strncmp (args, "prev", len) == 0)
    624  1.5  christos 	match = tui_reg_prev (gdbarch);
    625  1.5  christos 
    626  1.5  christos       /* This loop matches on the initial part of a register group
    627  1.5  christos 	 name.  If this initial part in ARGS matches only one register
    628  1.5  christos 	 group then the switch is made.  */
    629  1.5  christos       for (group = reggroup_next (gdbarch, NULL);
    630  1.5  christos 	   group != NULL;
    631  1.5  christos 	   group = reggroup_next (gdbarch, group))
    632  1.5  christos 	{
    633  1.5  christos 	  if (strncmp (reggroup_name (group), args, len) == 0)
    634  1.5  christos 	    {
    635  1.5  christos 	      if (match != NULL)
    636  1.5  christos 		error (_("ambiguous register group name '%s'"), args);
    637  1.5  christos 	      match = group;
    638  1.5  christos 	    }
    639  1.5  christos 	}
    640  1.5  christos 
    641  1.5  christos       if (match == NULL)
    642  1.5  christos 	error (_("unknown register group '%s'"), args);
    643  1.5  christos 
    644  1.5  christos       tui_show_registers (match);
    645  1.5  christos     }
    646  1.5  christos   else
    647  1.5  christos     {
    648  1.5  christos       struct reggroup *group;
    649  1.5  christos       int first;
    650  1.5  christos 
    651  1.5  christos       printf_unfiltered (_("\"tui reg\" must be followed by the name of "
    652  1.5  christos 			   "either a register group,\nor one of 'next' "
    653  1.5  christos 			   "or 'prev'.  Known register groups are:\n"));
    654  1.5  christos 
    655  1.5  christos       for (first = 1, group = reggroup_next (gdbarch, NULL);
    656  1.5  christos 	   group != NULL;
    657  1.5  christos 	   first = 0, group = reggroup_next (gdbarch, group))
    658  1.5  christos 	{
    659  1.5  christos 	  if (!first)
    660  1.5  christos 	    printf_unfiltered (", ");
    661  1.5  christos 	  printf_unfiltered ("%s", reggroup_name (group));
    662  1.5  christos 	}
    663  1.5  christos 
    664  1.5  christos       printf_unfiltered ("\n");
    665  1.5  christos     }
    666  1.1  christos }
    667  1.1  christos 
    668  1.5  christos /* Complete names of register groups, and add the special "prev" and "next"
    669  1.5  christos    names.  */
    670  1.5  christos 
    671  1.5  christos static VEC (char_ptr) *
    672  1.5  christos tui_reggroup_completer (struct cmd_list_element *ignore,
    673  1.5  christos 			const char *text, const char *word)
    674  1.1  christos {
    675  1.5  christos   VEC (char_ptr) *result = NULL;
    676  1.5  christos   static const char *extra[] = { "next", "prev", NULL };
    677  1.5  christos   size_t len = strlen (word);
    678  1.5  christos   const char **tmp;
    679  1.5  christos 
    680  1.5  christos   result = reggroup_completer (ignore, text, word);
    681  1.1  christos 
    682  1.5  christos   for (tmp = extra; *tmp != NULL; ++tmp)
    683  1.5  christos     {
    684  1.5  christos       if (strncmp (word, *tmp, len) == 0)
    685  1.5  christos 	VEC_safe_push (char_ptr, result, xstrdup (*tmp));
    686  1.5  christos     }
    687  1.1  christos 
    688  1.5  christos   return result;
    689  1.1  christos }
    690  1.1  christos 
    691  1.1  christos /* Provide a prototype to silence -Wmissing-prototypes.  */
    692  1.1  christos extern initialize_file_ftype _initialize_tui_regs;
    693  1.1  christos 
    694  1.1  christos void
    695  1.1  christos _initialize_tui_regs (void)
    696  1.1  christos {
    697  1.5  christos   struct cmd_list_element **tuicmd, *cmd;
    698  1.1  christos 
    699  1.1  christos   tuicmd = tui_get_cmd_list ();
    700  1.1  christos 
    701  1.5  christos   cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
    702  1.5  christos TUI command to control the register window."), tuicmd);
    703  1.5  christos   set_cmd_completer (cmd, tui_reggroup_completer);
    704  1.1  christos }
    705  1.1  christos 
    706  1.1  christos 
    707  1.1  christos /*****************************************
    708  1.1  christos ** STATIC LOCAL FUNCTIONS                 **
    709  1.1  christos ******************************************/
    710  1.1  christos 
    711  1.1  christos static void
    712  1.1  christos tui_restore_gdbout (void *ui)
    713  1.1  christos {
    714  1.1  christos   ui_file_delete (gdb_stdout);
    715  1.1  christos   gdb_stdout = (struct ui_file*) ui;
    716  1.1  christos   pagination_enabled = 1;
    717  1.1  christos }
    718  1.1  christos 
    719  1.1  christos /* Get the register from the frame and return a printable
    720  1.1  christos    representation of it.  */
    721  1.1  christos 
    722  1.1  christos static char *
    723  1.1  christos tui_register_format (struct frame_info *frame, int regnum)
    724  1.1  christos {
    725  1.1  christos   struct gdbarch *gdbarch = get_frame_arch (frame);
    726  1.1  christos   struct ui_file *stream;
    727  1.1  christos   struct ui_file *old_stdout;
    728  1.1  christos   struct cleanup *cleanups;
    729  1.1  christos   char *p, *s;
    730  1.1  christos   char *ret;
    731  1.1  christos 
    732  1.1  christos   pagination_enabled = 0;
    733  1.1  christos   old_stdout = gdb_stdout;
    734  1.1  christos   stream = tui_sfileopen (256);
    735  1.1  christos   gdb_stdout = stream;
    736  1.1  christos   cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
    737  1.1  christos   gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
    738  1.1  christos 
    739  1.1  christos   /* Save formatted output in the buffer.  */
    740  1.1  christos   p = tui_file_get_strbuf (stream);
    741  1.1  christos 
    742  1.1  christos   /* Remove the possible \n.  */
    743  1.1  christos   s = strrchr (p, '\n');
    744  1.1  christos   if (s && s[1] == 0)
    745  1.1  christos     *s = 0;
    746  1.1  christos 
    747  1.3  christos   /* Expand tabs into spaces, since ncurses on MS-Windows doesn't.  */
    748  1.3  christos   ret = tui_expand_tabs (p, 0);
    749  1.3  christos 
    750  1.1  christos   do_cleanups (cleanups);
    751  1.1  christos 
    752  1.1  christos   return ret;
    753  1.1  christos }
    754  1.1  christos 
    755  1.1  christos /* Get the register value from the given frame and format it for the
    756  1.1  christos    display.  When changep is set, check if the new register value has
    757  1.1  christos    changed with respect to the previous call.  */
    758  1.1  christos static enum tui_status
    759  1.1  christos tui_get_register (struct frame_info *frame,
    760  1.1  christos                   struct tui_data_element *data,
    761  1.1  christos 		  int regnum, int *changedp)
    762  1.1  christos {
    763  1.1  christos   enum tui_status ret = TUI_FAILURE;
    764  1.1  christos 
    765  1.1  christos   if (changedp)
    766  1.1  christos     *changedp = FALSE;
    767  1.1  christos   if (target_has_registers)
    768  1.1  christos     {
    769  1.1  christos       char *prev_content = data->content;
    770  1.1  christos 
    771  1.1  christos       data->content = tui_register_format (frame, regnum);
    772  1.1  christos 
    773  1.1  christos       if (changedp != NULL
    774  1.1  christos 	  && strcmp (prev_content, data->content) != 0)
    775  1.1  christos 	*changedp = 1;
    776  1.1  christos 
    777  1.1  christos       xfree (prev_content);
    778  1.1  christos 
    779  1.1  christos       ret = TUI_SUCCESS;
    780  1.1  christos     }
    781  1.1  christos   return ret;
    782  1.1  christos }
    783