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