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