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