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