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