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