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