Do not increment of decrement enums
[deliverable/binutils-gdb.git] / gdb / tui / tui-regs.c
1 /* TUI display registers in window.
2
3 Copyright (C) 1998-2015 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
43 #include "gdb_curses.h"
44
45
46 /*****************************************
47 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
48 ******************************************/
49 static void
50 tui_display_register (struct tui_data_element *data,
51 struct tui_gen_win_info *win_info);
52
53 static enum tui_status tui_show_register_group (struct reggroup *group,
54 struct frame_info *frame,
55 int refresh_values_only);
56
57 static enum tui_status tui_get_register (struct frame_info *frame,
58 struct tui_data_element *data,
59 int regnum, int *changedp);
60
61 static void tui_scroll_regs_forward_command (char *, int);
62 static void tui_scroll_regs_backward_command (char *, int);
63
64
65
66 /*****************************************
67 ** PUBLIC FUNCTIONS **
68 ******************************************/
69
70 /* Answer the number of the last line in the regs display. If there
71 are no registers (-1) is returned. */
72 int
73 tui_last_regs_line_no (void)
74 {
75 int num_lines = (-1);
76
77 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
78 {
79 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
80 TUI_DATA_WIN->detail.data_display_info.regs_column_count);
81 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
82 TUI_DATA_WIN->detail.data_display_info.regs_column_count)
83 num_lines++;
84 }
85 return num_lines;
86 }
87
88
89 /* Answer the line number that the register element at element_no is
90 on. If element_no is greater than the number of register elements
91 there are, -1 is returned. */
92 int
93 tui_line_from_reg_element_no (int element_no)
94 {
95 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
96 {
97 int i, line = (-1);
98
99 i = 1;
100 while (line == (-1))
101 {
102 if (element_no <
103 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
104 line = i - 1;
105 else
106 i++;
107 }
108
109 return line;
110 }
111 else
112 return (-1);
113 }
114
115
116 /* Answer the index of the first element in line_no. If line_no is
117 past the register area (-1) is returned. */
118 int
119 tui_first_reg_element_no_inline (int line_no)
120 {
121 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
122 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
123 return ((line_no + 1) *
124 TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
125 TUI_DATA_WIN->detail.data_display_info.regs_column_count;
126 else
127 return (-1);
128 }
129
130
131 /* Show the registers of the given group in the data window
132 and refresh the window. */
133 void
134 tui_show_registers (struct reggroup *group)
135 {
136 enum tui_status ret = TUI_FAILURE;
137 struct tui_data_info *display_info;
138
139 /* Make sure the curses mode is enabled. */
140 tui_enable ();
141
142 /* Make sure the register window is visible. If not, select an
143 appropriate layout. */
144 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
145 tui_set_layout_for_display_command (DATA_NAME);
146
147 display_info = &TUI_DATA_WIN->detail.data_display_info;
148 if (group == 0)
149 group = general_reggroup;
150
151 /* Say that registers should be displayed, even if there is a
152 problem. */
153 display_info->display_regs = TRUE;
154
155 if (target_has_registers && target_has_stack && target_has_memory)
156 {
157 ret = tui_show_register_group (group, get_selected_frame (NULL),
158 group == display_info->current_group);
159 }
160 if (ret == TUI_FAILURE)
161 {
162 display_info->current_group = 0;
163 tui_erase_data_content (NO_REGS_STRING);
164 }
165 else
166 {
167 int i;
168
169 /* Clear all notation of changed values. */
170 for (i = 0; i < display_info->regs_content_count; i++)
171 {
172 struct tui_gen_win_info *data_item_win;
173 struct tui_win_element *win;
174
175 data_item_win = &display_info->regs_content[i]
176 ->which_element.data_window;
177 win = (struct tui_win_element *) data_item_win->content[0];
178 win->which_element.data.highlight = FALSE;
179 }
180 display_info->current_group = group;
181 tui_display_all_data ();
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 enum tui_status
191 tui_show_register_group (struct reggroup *group,
192 struct frame_info *frame,
193 int refresh_values_only)
194 {
195 struct gdbarch *gdbarch = get_frame_arch (frame);
196 enum tui_status ret = TUI_FAILURE;
197 int nr_regs;
198 int allocated_here = FALSE;
199 int regnum, pos;
200 char title[80];
201 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
202
203 /* Make a new title showing which group we display. */
204 snprintf (title, sizeof (title) - 1, "Register group: %s",
205 reggroup_name (group));
206 xfree (TUI_DATA_WIN->generic.title);
207 TUI_DATA_WIN->generic.title = xstrdup (title);
208
209 /* See how many registers must be displayed. */
210 nr_regs = 0;
211 for (regnum = 0;
212 regnum < gdbarch_num_regs (gdbarch)
213 + gdbarch_num_pseudo_regs (gdbarch);
214 regnum++)
215 {
216 const char *name;
217
218 /* Must be in the group. */
219 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
220 continue;
221
222 /* If the register name is empty, it is undefined for this
223 processor, so don't display anything. */
224 name = gdbarch_register_name (gdbarch, regnum);
225 if (name == 0 || *name == '\0')
226 continue;
227
228 nr_regs++;
229 }
230
231 if (display_info->regs_content_count > 0 && !refresh_values_only)
232 {
233 tui_free_data_content (display_info->regs_content,
234 display_info->regs_content_count);
235 display_info->regs_content_count = 0;
236 }
237
238 if (display_info->regs_content_count <= 0)
239 {
240 display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
241 allocated_here = TRUE;
242 refresh_values_only = FALSE;
243 }
244
245 if (display_info->regs_content != (tui_win_content) NULL)
246 {
247 if (!refresh_values_only || allocated_here)
248 {
249 TUI_DATA_WIN->generic.content = (void*) NULL;
250 TUI_DATA_WIN->generic.content_size = 0;
251 tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
252 display_info->regs_content
253 = (tui_win_content) TUI_DATA_WIN->generic.content;
254 display_info->regs_content_count = nr_regs;
255 }
256
257 /* Now set the register names and values. */
258 pos = 0;
259 for (regnum = 0;
260 regnum < gdbarch_num_regs (gdbarch)
261 + gdbarch_num_pseudo_regs (gdbarch);
262 regnum++)
263 {
264 struct tui_gen_win_info *data_item_win;
265 struct tui_data_element *data;
266 const char *name;
267
268 /* Must be in the group. */
269 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
270 continue;
271
272 /* If the register name is empty, it is undefined for this
273 processor, so don't display anything. */
274 name = gdbarch_register_name (gdbarch, regnum);
275 if (name == 0 || *name == '\0')
276 continue;
277
278 data_item_win =
279 &display_info->regs_content[pos]->which_element.data_window;
280 data = &((struct tui_win_element *)
281 data_item_win->content[0])->which_element.data;
282 if (data)
283 {
284 if (!refresh_values_only)
285 {
286 data->item_no = regnum;
287 data->name = name;
288 data->highlight = FALSE;
289 }
290 tui_get_register (frame, data, regnum, 0);
291 }
292 pos++;
293 }
294
295 TUI_DATA_WIN->generic.content_size =
296 display_info->regs_content_count + display_info->data_content_count;
297 ret = TUI_SUCCESS;
298 }
299
300 return ret;
301 }
302
303 /* Function to display the registers in the content from
304 'start_element_no' until the end of the register content or the end
305 of the display height. No checking for displaying past the end of
306 the registers is done here. */
307 void
308 tui_display_registers_from (int start_element_no)
309 {
310 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
311
312 if (display_info->regs_content != (tui_win_content) NULL
313 && display_info->regs_content_count > 0)
314 {
315 int i = start_element_no;
316 int j, item_win_width, cur_y;
317
318 int max_len = 0;
319 for (i = 0; i < display_info->regs_content_count; i++)
320 {
321 struct tui_data_element *data;
322 struct tui_gen_win_info *data_item_win;
323 char *p;
324 int len;
325
326 data_item_win
327 = &display_info->regs_content[i]->which_element.data_window;
328 data = &((struct tui_win_element *)
329 data_item_win->content[0])->which_element.data;
330 len = 0;
331 p = data->content;
332 if (p != 0)
333 while (*p)
334 {
335 if (*p++ == '\t')
336 len = 8 * ((len / 8) + 1);
337 else
338 len++;
339 }
340
341 if (len > max_len)
342 max_len = len;
343 }
344 item_win_width = max_len + 1;
345 i = start_element_no;
346
347 display_info->regs_column_count =
348 (TUI_DATA_WIN->generic.width - 2) / item_win_width;
349 if (display_info->regs_column_count == 0)
350 display_info->regs_column_count = 1;
351 item_win_width =
352 (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
353
354 /* Now create each data "sub" window, and write the display into
355 it. */
356 cur_y = 1;
357 while (i < display_info->regs_content_count
358 && cur_y <= TUI_DATA_WIN->generic.viewport_height)
359 {
360 for (j = 0;
361 j < display_info->regs_column_count
362 && i < display_info->regs_content_count;
363 j++)
364 {
365 struct tui_gen_win_info *data_item_win;
366 struct tui_data_element *data_element_ptr;
367
368 /* Create the window if necessary. */
369 data_item_win = &display_info->regs_content[i]
370 ->which_element.data_window;
371 data_element_ptr = &((struct tui_win_element *)
372 data_item_win->content[0])->which_element.data;
373 if (data_item_win->handle != (WINDOW*) NULL
374 && (data_item_win->height != 1
375 || data_item_win->width != item_win_width
376 || data_item_win->origin.x != (item_win_width * j) + 1
377 || data_item_win->origin.y != cur_y))
378 {
379 tui_delete_win (data_item_win->handle);
380 data_item_win->handle = 0;
381 }
382
383 if (data_item_win->handle == (WINDOW *) NULL)
384 {
385 data_item_win->height = 1;
386 data_item_win->width = item_win_width;
387 data_item_win->origin.x = (item_win_width * j) + 1;
388 data_item_win->origin.y = cur_y;
389 tui_make_window (data_item_win, DONT_BOX_WINDOW);
390 scrollok (data_item_win->handle, FALSE);
391 }
392 touchwin (data_item_win->handle);
393
394 /* Get the printable representation of the register
395 and display it. */
396 tui_display_register (data_element_ptr, data_item_win);
397 i++; /* Next register. */
398 }
399 cur_y++; /* Next row. */
400 }
401 }
402 }
403
404
405 /* Function to display the registers in the content from
406 'start_element_no' on 'start_line_no' until the end of the register
407 content or the end of the display height. This function checks
408 that we won't display off the end of the register display. */
409 static void
410 tui_display_reg_element_at_line (int start_element_no,
411 int start_line_no)
412 {
413 if (TUI_DATA_WIN->detail.data_display_info.regs_content
414 != (tui_win_content) NULL
415 && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
416 {
417 int element_no = start_element_no;
418
419 if (start_element_no != 0 && start_line_no != 0)
420 {
421 int last_line_no, first_line_on_last_page;
422
423 last_line_no = tui_last_regs_line_no ();
424 first_line_on_last_page
425 = last_line_no - (TUI_DATA_WIN->generic.height - 2);
426 if (first_line_on_last_page < 0)
427 first_line_on_last_page = 0;
428
429 /* If there is no other data displayed except registers, and
430 the element_no causes us to scroll past the end of the
431 registers, adjust what element to really start the
432 display at. */
433 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
434 && start_line_no > first_line_on_last_page)
435 element_no
436 = tui_first_reg_element_no_inline (first_line_on_last_page);
437 }
438 tui_display_registers_from (element_no);
439 }
440 }
441
442
443
444 /* Function to display the registers starting at line line_no in the
445 data window. Answers the line number that the display actually
446 started from. If nothing is displayed (-1) is returned. */
447 int
448 tui_display_registers_from_line (int line_no,
449 int force_display)
450 {
451 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
452 {
453 int line, element_no;
454
455 if (line_no < 0)
456 line = 0;
457 else if (force_display)
458 { /* If we must display regs (force_display is true), then
459 make sure that we don't display off the end of the
460 registers. */
461 if (line_no >= tui_last_regs_line_no ())
462 {
463 if ((line = tui_line_from_reg_element_no (
464 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
465 line = 0;
466 }
467 else
468 line = line_no;
469 }
470 else
471 line = line_no;
472
473 element_no = tui_first_reg_element_no_inline (line);
474 if (element_no
475 < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
476 tui_display_reg_element_at_line (element_no, line);
477 else
478 line = (-1);
479
480 return line;
481 }
482
483 return (-1); /* Nothing was displayed. */
484 }
485
486
487 /* This function check all displayed registers for changes in values,
488 given a particular frame. If the values have changed, they are
489 updated with the new value and highlighted. */
490 void
491 tui_check_register_values (struct frame_info *frame)
492 {
493 if (TUI_DATA_WIN != NULL
494 && TUI_DATA_WIN->generic.is_visible)
495 {
496 struct tui_data_info *display_info
497 = &TUI_DATA_WIN->detail.data_display_info;
498
499 if (display_info->regs_content_count <= 0
500 && display_info->display_regs)
501 tui_show_registers (display_info->current_group);
502 else
503 {
504 int i;
505
506 for (i = 0; (i < display_info->regs_content_count); i++)
507 {
508 struct tui_data_element *data;
509 struct tui_gen_win_info *data_item_win_ptr;
510 int was_hilighted;
511
512 data_item_win_ptr = &display_info->regs_content[i]->
513 which_element.data_window;
514 data = &((struct tui_win_element *)
515 data_item_win_ptr->content[0])->which_element.data;
516 was_hilighted = data->highlight;
517
518 tui_get_register (frame, data,
519 data->item_no, &data->highlight);
520
521 if (data->highlight || was_hilighted)
522 {
523 tui_display_register (data, data_item_win_ptr);
524 }
525 }
526 }
527 }
528 }
529
530 /* Display a register in a window. If hilite is TRUE, then the value
531 will be displayed in reverse video. */
532 static void
533 tui_display_register (struct tui_data_element *data,
534 struct tui_gen_win_info *win_info)
535 {
536 if (win_info->handle != (WINDOW *) NULL)
537 {
538 int i;
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) wstandout (win_info->handle);
547
548 wmove (win_info->handle, 0, 0);
549 for (i = 1; i < win_info->width; i++)
550 waddch (win_info->handle, ' ');
551 wmove (win_info->handle, 0, 0);
552 if (data->content)
553 waddstr (win_info->handle, data->content);
554
555 if (data->highlight)
556 /* We ignore the return value, casting it to void in order to avoid
557 a compiler warning. The warning itself was introduced by a patch
558 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
559 to code that causes the compiler to generate an unused-value
560 warning. */
561 (void) wstandend (win_info->handle);
562 tui_refresh_win (win_info);
563 }
564 }
565
566 static void
567 tui_reg_next_command (char *arg, int from_tty)
568 {
569 struct gdbarch *gdbarch = get_current_arch ();
570
571 if (TUI_DATA_WIN != 0)
572 {
573 struct reggroup *group
574 = TUI_DATA_WIN->detail.data_display_info.current_group;
575
576 group = reggroup_next (gdbarch, group);
577 if (group == 0)
578 group = reggroup_next (gdbarch, 0);
579
580 if (group)
581 tui_show_registers (group);
582 }
583 }
584
585 static void
586 tui_reg_float_command (char *arg, int from_tty)
587 {
588 tui_show_registers (float_reggroup);
589 }
590
591 static void
592 tui_reg_general_command (char *arg, int from_tty)
593 {
594 tui_show_registers (general_reggroup);
595 }
596
597 static void
598 tui_reg_system_command (char *arg, int from_tty)
599 {
600 tui_show_registers (system_reggroup);
601 }
602
603 static struct cmd_list_element *tuireglist;
604
605 static void
606 tui_reg_command (char *args, int from_tty)
607 {
608 printf_unfiltered (_("\"tui reg\" must be followed by the name of a "
609 "tui reg command.\n"));
610 help_list (tuireglist, "tui reg ", all_commands, gdb_stdout);
611 }
612
613 /* Provide a prototype to silence -Wmissing-prototypes. */
614 extern initialize_file_ftype _initialize_tui_regs;
615
616 void
617 _initialize_tui_regs (void)
618 {
619 struct cmd_list_element **tuicmd;
620
621 tuicmd = tui_get_cmd_list ();
622
623 add_prefix_cmd ("reg", class_tui, tui_reg_command,
624 _("TUI commands to control the register window."),
625 &tuireglist, "tui reg ", 0,
626 tuicmd);
627
628 add_cmd ("float", class_tui, tui_reg_float_command,
629 _("Display only floating point registers."),
630 &tuireglist);
631 add_cmd ("general", class_tui, tui_reg_general_command,
632 _("Display only general registers."),
633 &tuireglist);
634 add_cmd ("system", class_tui, tui_reg_system_command,
635 _("Display only system registers."),
636 &tuireglist);
637 add_cmd ("next", class_tui, tui_reg_next_command,
638 _("Display next register group."),
639 &tuireglist);
640
641 if (xdb_commands)
642 {
643 add_com ("fr", class_tui, tui_reg_float_command,
644 _("Display only floating point registers\n"));
645 add_com ("gr", class_tui, tui_reg_general_command,
646 _("Display only general registers\n"));
647 add_com ("sr", class_tui, tui_reg_system_command,
648 _("Display only special registers\n"));
649 add_com ("+r", class_tui, tui_scroll_regs_forward_command,
650 _("Scroll the registers window forward\n"));
651 add_com ("-r", class_tui, tui_scroll_regs_backward_command,
652 _("Scroll the register window backward\n"));
653 }
654 }
655
656
657 /*****************************************
658 ** STATIC LOCAL FUNCTIONS **
659 ******************************************/
660
661 static void
662 tui_restore_gdbout (void *ui)
663 {
664 ui_file_delete (gdb_stdout);
665 gdb_stdout = (struct ui_file*) ui;
666 pagination_enabled = 1;
667 }
668
669 /* Get the register from the frame and return a printable
670 representation of it. */
671
672 static char *
673 tui_register_format (struct frame_info *frame, int regnum)
674 {
675 struct gdbarch *gdbarch = get_frame_arch (frame);
676 struct ui_file *stream;
677 struct ui_file *old_stdout;
678 struct cleanup *cleanups;
679 char *p, *s;
680 char *ret;
681
682 pagination_enabled = 0;
683 old_stdout = gdb_stdout;
684 stream = tui_sfileopen (256);
685 gdb_stdout = stream;
686 cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
687 gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
688
689 /* Save formatted output in the buffer. */
690 p = tui_file_get_strbuf (stream);
691
692 /* Remove the possible \n. */
693 s = strrchr (p, '\n');
694 if (s && s[1] == 0)
695 *s = 0;
696
697 /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
698 ret = tui_expand_tabs (p, 0);
699
700 do_cleanups (cleanups);
701
702 return ret;
703 }
704
705 /* Get the register value from the given frame and format it for the
706 display. When changep is set, check if the new register value has
707 changed with respect to the previous call. */
708 static enum tui_status
709 tui_get_register (struct frame_info *frame,
710 struct tui_data_element *data,
711 int regnum, int *changedp)
712 {
713 enum tui_status ret = TUI_FAILURE;
714
715 if (changedp)
716 *changedp = FALSE;
717 if (target_has_registers)
718 {
719 char *prev_content = data->content;
720
721 data->content = tui_register_format (frame, regnum);
722
723 if (changedp != NULL
724 && strcmp (prev_content, data->content) != 0)
725 *changedp = 1;
726
727 xfree (prev_content);
728
729 ret = TUI_SUCCESS;
730 }
731 return ret;
732 }
733
734 static void
735 tui_scroll_regs_forward_command (char *arg, int from_tty)
736 {
737 tui_scroll (FORWARD_SCROLL, TUI_DATA_WIN, 1);
738 }
739
740
741 static void
742 tui_scroll_regs_backward_command (char *arg, int from_tty)
743 {
744 tui_scroll (BACKWARD_SCROLL, TUI_DATA_WIN, 1);
745 }
This page took 0.062065 seconds and 4 git commands to generate.