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