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