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