Rearrange TUI data window code
[deliverable/binutils-gdb.git] / gdb / tui / tui-regs.c
CommitLineData
f377b406 1/* TUI display registers in window.
f33c6cbf 2
42a4f53d 3 Copyright (C) 1998-2019 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"
d7b2e967
AC
33#include "tui/tui-layout.h"
34#include "tui/tui-win.h"
d7b2e967
AC
35#include "tui/tui-wingeneral.h"
36#include "tui/tui-file.h"
2c0b251b 37#include "tui/tui-regs.h"
312809f8 38#include "tui/tui-io.h"
10f59415 39#include "reggroups.h"
79a45b7d 40#include "valprint.h"
51f0e40d 41#include "completer.h"
c906108c 42
6a83354a 43#include "gdb_curses.h"
96ec9981 44
41bcff7f 45static void tui_display_register (struct tui_data_item_window *data);
c906108c 46
e80cd204
TT
47static void tui_show_register_group (tui_data_window *win_info,
48 struct reggroup *group,
21e1c91e
TT
49 struct frame_info *frame,
50 int refresh_values_only);
5eccfcc2 51
2cdfa113
TT
52static void tui_get_register (struct frame_info *frame,
53 struct tui_data_item_window *data,
54 int regnum, bool *changedp);
5eccfcc2 55
18ab23af 56/* See tui-regs.h. */
0b5ec218 57
c906108c 58int
0b5ec218 59tui_data_window::last_regs_line_no () const
c906108c 60{
d02c80cd 61 int num_lines = (-1);
c906108c 62
0b5ec218 63 if (!regs_content.empty ())
c906108c 64 {
0b5ec218
TT
65 num_lines = regs_content.size () / regs_column_count;
66 if (regs_content.size () % regs_column_count)
6ba8e26f 67 num_lines++;
c906108c 68 }
6ba8e26f 69 return num_lines;
55fb0713 70}
c906108c 71
18ab23af 72/* See tui-regs.h. */
c906108c 73
c906108c 74int
3b23c5f2 75tui_data_window::line_from_reg_element_no (int element_no) const
c906108c 76{
3b23c5f2 77 if (element_no < regs_content.size ())
c906108c
SS
78 {
79 int i, line = (-1);
80
81 i = 1;
82 while (line == (-1))
83 {
3b23c5f2 84 if (element_no < regs_column_count * i)
c906108c
SS
85 line = i - 1;
86 else
87 i++;
88 }
89
90 return line;
91 }
92 else
93 return (-1);
55fb0713 94}
c906108c 95
18ab23af 96/* See tui-regs.h. */
c906108c 97
c906108c 98int
baff0c28 99tui_data_window::first_reg_element_no_inline (int line_no) const
c906108c 100{
baff0c28
TT
101 if (line_no * regs_column_count <= regs_content.size ())
102 return ((line_no + 1) * regs_column_count) - regs_column_count;
c906108c
SS
103 else
104 return (-1);
55fb0713 105}
c906108c 106
0379b883
TT
107/* A helper function to display the register window in the appropriate
108 way. */
109
110static void
111tui_reg_layout ()
112{
113 enum tui_layout_type cur_layout = tui_current_layout ();
114 enum tui_layout_type new_layout;
115 if (cur_layout == SRC_COMMAND || cur_layout == SRC_DATA_COMMAND)
116 new_layout = SRC_DATA_COMMAND;
117 else
118 new_layout = DISASSEM_DATA_COMMAND;
119 tui_set_layout (new_layout);
120}
c906108c 121
10f59415
SC
122/* Show the registers of the given group in the data window
123 and refresh the window. */
c906108c 124void
10f59415 125tui_show_registers (struct reggroup *group)
c906108c 126{
0bfbda3b
SC
127 /* Make sure the curses mode is enabled. */
128 tui_enable ();
129
130 /* Make sure the register window is visible. If not, select an
131 appropriate layout. */
cb2ce893 132 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible)
0379b883 133 tui_reg_layout ();
0bfbda3b 134
10f59415
SC
135 if (group == 0)
136 group = general_reggroup;
c906108c 137
1cc6d956
MS
138 /* Say that registers should be displayed, even if there is a
139 problem. */
ceb13a13 140 TUI_DATA_WIN->display_regs = true;
10f59415
SC
141
142 if (target_has_registers && target_has_stack && target_has_memory)
c906108c 143 {
e80cd204 144 tui_show_register_group (TUI_DATA_WIN, group, get_selected_frame (NULL),
21e1c91e 145 group == TUI_DATA_WIN->current_group);
368c1354 146
1cc6d956 147 /* Clear all notation of changed values. */
21e1c91e 148 for (auto &&data_item_win : TUI_DATA_WIN->regs_content)
c906108c 149 {
21e1c91e
TT
150 if (data_item_win != nullptr)
151 data_item_win->highlight = false;
c906108c 152 }
238eb706 153 TUI_DATA_WIN->current_group = group;
50daf268 154 TUI_DATA_WIN->display_all_data ();
c906108c 155 }
368c1354
TT
156 else
157 {
158 TUI_DATA_WIN->current_group = 0;
159 TUI_DATA_WIN->erase_data_content (NO_REGS_STRING);
160 }
55fb0713 161}
c906108c
SS
162
163
10f59415 164/* Set the data window to display the registers of the register group
1cc6d956
MS
165 using the given frame. Values are refreshed only when
166 refresh_values_only is TRUE. */
10f59415 167
21e1c91e 168static void
e80cd204
TT
169tui_show_register_group (tui_data_window *win_info,
170 struct reggroup *group,
08ef48c5
MS
171 struct frame_info *frame,
172 int refresh_values_only)
10f59415 173{
5eccfcc2 174 struct gdbarch *gdbarch = get_frame_arch (frame);
10f59415 175 int nr_regs;
10f59415
SC
176 int regnum, pos;
177 char title[80];
10f59415
SC
178
179 /* Make a new title showing which group we display. */
180 snprintf (title, sizeof (title) - 1, "Register group: %s",
181 reggroup_name (group));
e80cd204
TT
182 xfree (win_info->title);
183 win_info->title = xstrdup (title);
10f59415
SC
184
185 /* See how many registers must be displayed. */
186 nr_regs = 0;
f6efe3f8 187 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
10f59415 188 {
d20c1c3f
PA
189 const char *name;
190
191 /* Must be in the group. */
192 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
193 continue;
194
195 /* If the register name is empty, it is undefined for this
196 processor, so don't display anything. */
197 name = gdbarch_register_name (gdbarch, regnum);
198 if (name == 0 || *name == '\0')
199 continue;
200
201 nr_regs++;
10f59415
SC
202 }
203
21e1c91e 204 if (!refresh_values_only)
e80cd204 205 win_info->regs_content.clear ();
10f59415 206
e80cd204
TT
207 if (nr_regs < win_info->regs_content.size ())
208 win_info->regs_content.resize (nr_regs);
21e1c91e 209 else
10f59415 210 {
e80cd204
TT
211 for (int i = win_info->regs_content.size (); i < nr_regs; ++i)
212 win_info->regs_content.emplace_back (new tui_data_item_window ());
10f59415
SC
213 }
214
21e1c91e
TT
215 /* Now set the register names and values. */
216 pos = 0;
217 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
10f59415 218 {
21e1c91e
TT
219 struct tui_data_item_window *data_item_win;
220 const char *name;
10f59415 221
21e1c91e
TT
222 /* Must be in the group. */
223 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
224 continue;
10f59415 225
21e1c91e
TT
226 /* If the register name is empty, it is undefined for this
227 processor, so don't display anything. */
228 name = gdbarch_register_name (gdbarch, regnum);
229 if (name == 0 || *name == '\0')
230 continue;
10f59415 231
e80cd204 232 data_item_win = win_info->regs_content[pos].get ();
21e1c91e
TT
233 if (data_item_win)
234 {
235 if (!refresh_values_only)
236 {
237 data_item_win->item_no = regnum;
238 data_item_win->name = name;
239 data_item_win->highlight = false;
240 }
241 tui_get_register (frame, data_item_win, regnum, 0);
242 }
243 pos++;
244 }
10f59415
SC
245}
246
18ab23af 247/* See tui-regs.h. */
517e9505 248
c906108c 249void
517e9505 250tui_data_window::display_registers_from (int start_element_no)
c906108c 251{
517e9505 252 if (!regs_content.empty ())
c906108c 253 {
0043e6a5 254 int j, item_win_width, cur_y;
10f59415
SC
255
256 int max_len = 0;
517e9505 257 for (auto &&data_item_win : regs_content)
10f59415 258 {
10f59415
SC
259 char *p;
260 int len;
261
10f59415 262 len = 0;
41bcff7f 263 p = data_item_win->content;
10f59415
SC
264 if (p != 0)
265 while (*p)
266 {
267 if (*p++ == '\t')
268 len = 8 * ((len / 8) + 1);
269 else
270 len++;
271 }
272
273 if (len > max_len)
274 max_len = len;
275 }
276 item_win_width = max_len + 1;
21e1c91e 277 int i = start_element_no;
10f59415 278
517e9505
TT
279 regs_column_count = (width - 2) / item_win_width;
280 if (regs_column_count == 0)
281 regs_column_count = 1;
282 item_win_width = (width - 2) / regs_column_count;
10f59415 283
ef5eab5a
MS
284 /* Now create each data "sub" window, and write the display into
285 it. */
6ba8e26f 286 cur_y = 1;
517e9505
TT
287 while (i < regs_content.size ()
288 && cur_y <= viewport_height)
c906108c
SS
289 {
290 for (j = 0;
517e9505 291 j < regs_column_count && i < regs_content.size ();
e5908723 292 j++)
c906108c 293 {
41bcff7f 294 struct tui_data_item_window *data_item_win;
c906108c 295
1cc6d956 296 /* Create the window if necessary. */
517e9505 297 data_item_win = regs_content[i].get ();
cafb3438 298 if (data_item_win->handle != NULL
10f59415
SC
299 && (data_item_win->height != 1
300 || data_item_win->width != item_win_width
301 || data_item_win->origin.x != (item_win_width * j) + 1
302 || data_item_win->origin.y != cur_y))
303 {
304 tui_delete_win (data_item_win->handle);
305 data_item_win->handle = 0;
306 }
307
cafb3438 308 if (data_item_win->handle == NULL)
c906108c 309 {
6ba8e26f 310 data_item_win->height = 1;
10f59415 311 data_item_win->width = item_win_width;
6ba8e26f
AC
312 data_item_win->origin.x = (item_win_width * j) + 1;
313 data_item_win->origin.y = cur_y;
314 tui_make_window (data_item_win, DONT_BOX_WINDOW);
315 scrollok (data_item_win->handle, FALSE);
c906108c 316 }
6ba8e26f 317 touchwin (data_item_win->handle);
fea14702 318
10f59415
SC
319 /* Get the printable representation of the register
320 and display it. */
41bcff7f 321 tui_display_register (data_item_win);
1cc6d956 322 i++; /* Next register. */
c906108c 323 }
1cc6d956 324 cur_y++; /* Next row. */
c906108c
SS
325 }
326 }
55fb0713 327}
c906108c 328
18ab23af 329/* See tui-regs.h. */
c906108c 330
aca2dd16
TT
331void
332tui_data_window::display_reg_element_at_line (int start_element_no,
333 int start_line_no)
c906108c 334{
aca2dd16 335 if (!regs_content.empty ())
c906108c 336 {
d02c80cd 337 int element_no = start_element_no;
c906108c 338
6ba8e26f 339 if (start_element_no != 0 && start_line_no != 0)
c906108c 340 {
d02c80cd 341 int last_line_no, first_line_on_last_page;
c906108c 342
aca2dd16
TT
343 last_line_no = last_regs_line_no ();
344 first_line_on_last_page = last_line_no - (height - 2);
6ba8e26f
AC
345 if (first_line_on_last_page < 0)
346 first_line_on_last_page = 0;
ef5eab5a 347
115ac53b 348 /* If the element_no causes us to scroll past the end of the
ef5eab5a
MS
349 registers, adjust what element to really start the
350 display at. */
115ac53b 351 if (start_line_no > first_line_on_last_page)
aca2dd16 352 element_no = first_reg_element_no_inline (first_line_on_last_page);
c906108c 353 }
aca2dd16 354 display_registers_from (element_no);
c906108c 355 }
6ba8e26f 356}
c906108c 357
18ab23af 358/* See tui-regs.h. */
c906108c 359
c906108c 360int
517e9505 361tui_data_window::display_registers_from_line (int line_no)
c906108c 362{
517e9505
TT
363 tui_check_and_display_highlight_if_needed (this);
364 if (!regs_content.empty ())
c906108c 365 {
80cb6c27 366 int element_no;
c906108c 367
6ba8e26f 368 if (line_no < 0)
80cb6c27
TT
369 line_no = 0;
370 else
371 {
372 /* Make sure that we don't display off the end of the
ef5eab5a 373 registers. */
517e9505 374 if (line_no >= last_regs_line_no ())
c906108c 375 {
517e9505
TT
376 line_no = line_from_reg_element_no (regs_content.size () - 1);
377 if (line_no < 0)
80cb6c27 378 line_no = 0;
c906108c 379 }
c906108c 380 }
c906108c 381
517e9505
TT
382 element_no = first_reg_element_no_inline (line_no);
383 if (element_no < regs_content.size ())
aca2dd16 384 display_reg_element_at_line (element_no, line_no);
c906108c 385 else
80cb6c27 386 line_no = (-1);
c906108c 387
80cb6c27 388 return line_no;
c906108c
SS
389 }
390
1cc6d956 391 return (-1); /* Nothing was displayed. */
55fb0713 392}
c906108c
SS
393
394
18ab23af
TT
395/* Answer the index first element displayed. If none are displayed,
396 then return (-1). */
397int
398tui_data_window::first_data_item_displayed ()
399{
400 for (int i = 0; i < regs_content.size (); i++)
401 {
402 struct tui_gen_win_info *data_item_win;
403
404 data_item_win = regs_content[i].get ();
405 if (data_item_win->handle != NULL && data_item_win->is_visible)
406 return i;
407 }
408
409 return -1;
410}
411
412/* See tui-regs.h. */
413
414void
415tui_data_window::delete_data_content_windows ()
416{
417 for (auto &&win : regs_content)
418 {
419 tui_delete_win (win->handle);
420 win->handle = NULL;
421 win->is_visible = false;
422 }
423}
424
425
426void
427tui_data_window::erase_data_content (const char *prompt)
428{
429 werase (handle);
430 tui_check_and_display_highlight_if_needed (this);
431 if (prompt != NULL)
432 {
433 int half_width = (width - 2) / 2;
434 int x_pos;
435
436 if (strlen (prompt) >= half_width)
437 x_pos = 1;
438 else
439 x_pos = half_width - strlen (prompt);
440 mvwaddstr (handle, (height / 2), x_pos, (char *) prompt);
441 }
442 wrefresh (handle);
443}
444
445/* See tui-regs.h. */
446
447void
448tui_data_window::display_all_data ()
449{
450 if (regs_content.empty ())
451 erase_data_content (NO_DATA_STRING);
452 else
453 {
454 erase_data_content (NULL);
455 delete_data_content_windows ();
456 tui_check_and_display_highlight_if_needed (this);
457 display_registers_from (0);
458 }
459}
460
461
462/* Function to redisplay the contents of the data window. */
463void
464tui_data_window::refresh_all ()
465{
466 erase_data_content (NULL);
467 if (!regs_content.empty ())
468 {
469 int first_element = first_data_item_displayed ();
470
471 if (first_element >= 0) /* Re-use existing windows. */
472 {
473 int first_line = (-1);
474
475 if (first_element < regs_content.size ())
476 first_line = line_from_reg_element_no (first_element);
477
478 if (first_line >= 0)
479 {
480 erase_data_content (NULL);
481 display_registers_from_line (first_line);
482 }
483 }
484 }
485}
486
487
488/* Scroll the data window vertically forward or backward. */
489void
490tui_data_window::do_scroll_vertical (int num_to_scroll)
491{
492 int first_element_no;
493 int first_line = (-1);
494
495 first_element_no = first_data_item_displayed ();
496 if (first_element_no < regs_content.size ())
497 first_line = line_from_reg_element_no (first_element_no);
498 else
499 { /* Calculate the first line from the element number which is in
500 the general data content. */
501 }
502
503 if (first_line >= 0)
504 {
505 first_line += num_to_scroll;
506 erase_data_content (NULL);
507 delete_data_content_windows ();
508 display_registers_from_line (first_line);
509 }
510}
511
512/* See tui-regs.h. */
513
514void
515tui_data_window::clear_detail ()
516{
517 regs_content.clear ();
518 regs_column_count = 1;
519 display_regs = false;
520}
521
522/* See tui-regs.h. */
523
524void
525tui_data_window::set_new_height (int height)
526{
527 /* Delete all data item windows. */
528 for (auto &&win : regs_content)
529 {
530 tui_delete_win (win->handle);
531 win->handle = NULL;
532 }
533}
534
535/* See tui-regs.h. */
536
537void
538tui_data_window::do_make_visible_with_new_height ()
539{
540 display_all_data ();
541}
542
543/* See tui-regs.h. */
544
545void
546tui_data_window::refresh_window ()
547{
548 tui_gen_win_info::refresh_window ();
549 for (auto &&win : regs_content)
550 {
551 if (win != NULL)
552 win->refresh_window ();
553 }
554}
555
55fb0713
AC
556/* This function check all displayed registers for changes in values,
557 given a particular frame. If the values have changed, they are
558 updated with the new value and highlighted. */
c906108c 559void
55fb0713 560tui_check_register_values (struct frame_info *frame)
c906108c 561{
e5908723 562 if (TUI_DATA_WIN != NULL
cb2ce893 563 && TUI_DATA_WIN->is_visible)
c906108c 564 {
21e1c91e 565 if (TUI_DATA_WIN->regs_content.empty ()
238eb706
TT
566 && TUI_DATA_WIN->display_regs)
567 tui_show_registers (TUI_DATA_WIN->current_group);
c906108c
SS
568 else
569 {
21e1c91e 570 for (auto &&data_item_win_ptr : TUI_DATA_WIN->regs_content)
c906108c 571 {
6ba8e26f 572 int was_hilighted;
c906108c 573
41bcff7f 574 was_hilighted = data_item_win_ptr->highlight;
10f59415 575
21e1c91e 576 tui_get_register (frame, data_item_win_ptr.get (),
41bcff7f
TT
577 data_item_win_ptr->item_no,
578 &data_item_win_ptr->highlight);
10f59415 579
41bcff7f 580 if (data_item_win_ptr->highlight || was_hilighted)
21e1c91e 581 tui_display_register (data_item_win_ptr.get ());
c906108c
SS
582 }
583 }
584 }
55fb0713 585}
c906108c 586
1cc6d956
MS
587/* Display a register in a window. If hilite is TRUE, then the value
588 will be displayed in reverse video. */
10f59415 589static void
41bcff7f 590tui_display_register (struct tui_data_item_window *data)
10f59415 591{
41bcff7f 592 if (data->handle != NULL)
10f59415
SC
593 {
594 int i;
c906108c 595
10f59415 596 if (data->highlight)
cae3f17b
JB
597 /* We ignore the return value, casting it to void in order to avoid
598 a compiler warning. The warning itself was introduced by a patch
599 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
600 to code that causes the compiler to generate an unused-value
601 warning. */
41bcff7f 602 (void) wstandout (data->handle);
10f59415 603
41bcff7f
TT
604 wmove (data->handle, 0, 0);
605 for (i = 1; i < data->width; i++)
606 waddch (data->handle, ' ');
607 wmove (data->handle, 0, 0);
10f59415 608 if (data->content)
41bcff7f 609 waddstr (data->handle, data->content);
10f59415
SC
610
611 if (data->highlight)
cae3f17b
JB
612 /* We ignore the return value, casting it to void in order to avoid
613 a compiler warning. The warning itself was introduced by a patch
614 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
615 to code that causes the compiler to generate an unused-value
616 warning. */
41bcff7f
TT
617 (void) wstandend (data->handle);
618 data->refresh_window ();
10f59415
SC
619 }
620}
621
51f0e40d
AB
622/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
623 around behaviour. Returns the next register group, or NULL if the
624 register window is not currently being displayed. */
625
626static struct reggroup *
fe3eaf1c 627tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
c906108c 628{
51f0e40d 629 struct reggroup *group = NULL;
e17c207e 630
fe3eaf1c 631 if (current_group != NULL)
10f59415 632 {
fe3eaf1c 633 group = reggroup_next (gdbarch, current_group);
b75c69bb
AB
634 if (group == NULL)
635 group = reggroup_next (gdbarch, NULL);
10f59415 636 }
51f0e40d 637 return group;
10f59415
SC
638}
639
51f0e40d
AB
640/* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
641 around behaviour. Returns the previous register group, or NULL if the
642 register window is not currently being displayed. */
55b40027 643
51f0e40d 644static struct reggroup *
fe3eaf1c 645tui_reg_prev (struct reggroup *current_group, struct gdbarch *gdbarch)
55b40027 646{
51f0e40d 647 struct reggroup *group = NULL;
55b40027 648
fe3eaf1c 649 if (current_group != NULL)
55b40027 650 {
fe3eaf1c 651 group = reggroup_prev (gdbarch, current_group);
55b40027
AB
652 if (group == NULL)
653 group = reggroup_prev (gdbarch, NULL);
55b40027 654 }
51f0e40d 655 return group;
55b40027
AB
656}
657
51f0e40d
AB
658/* Implement the 'tui reg' command. Changes the register group displayed
659 in the tui register window. Displays the tui register window if it is
660 not already on display. */
c906108c 661
10f59415 662static void
e2d8ae16 663tui_reg_command (const char *args, int from_tty)
10f59415 664{
51f0e40d 665 struct gdbarch *gdbarch = get_current_arch ();
c906108c 666
51f0e40d
AB
667 if (args != NULL)
668 {
669 struct reggroup *group, *match = NULL;
670 size_t len = strlen (args);
671
672 /* Make sure the curses mode is enabled. */
673 tui_enable ();
674
675 /* Make sure the register window is visible. If not, select an
676 appropriate layout. We need to do this before trying to run the
677 'next' or 'prev' commands. */
cb2ce893 678 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible)
0379b883 679 tui_reg_layout ();
51f0e40d 680
fe3eaf1c
TT
681 struct reggroup *current_group = NULL;
682 if (TUI_DATA_WIN != NULL)
683 current_group = TUI_DATA_WIN->current_group;
51f0e40d 684 if (strncmp (args, "next", len) == 0)
fe3eaf1c 685 match = tui_reg_next (current_group, gdbarch);
51f0e40d 686 else if (strncmp (args, "prev", len) == 0)
fe3eaf1c 687 match = tui_reg_prev (current_group, gdbarch);
51f0e40d
AB
688
689 /* This loop matches on the initial part of a register group
690 name. If this initial part in ARGS matches only one register
691 group then the switch is made. */
692 for (group = reggroup_next (gdbarch, NULL);
693 group != NULL;
694 group = reggroup_next (gdbarch, group))
695 {
696 if (strncmp (reggroup_name (group), args, len) == 0)
697 {
698 if (match != NULL)
699 error (_("ambiguous register group name '%s'"), args);
700 match = group;
701 }
702 }
703
704 if (match == NULL)
705 error (_("unknown register group '%s'"), args);
706
707 tui_show_registers (match);
708 }
709 else
710 {
711 struct reggroup *group;
712 int first;
713
714 printf_unfiltered (_("\"tui reg\" must be followed by the name of "
715 "either a register group,\nor one of 'next' "
716 "or 'prev'. Known register groups are:\n"));
717
718 for (first = 1, group = reggroup_next (gdbarch, NULL);
719 group != NULL;
720 first = 0, group = reggroup_next (gdbarch, group))
721 {
722 if (!first)
723 printf_unfiltered (", ");
724 printf_unfiltered ("%s", reggroup_name (group));
725 }
726
727 printf_unfiltered ("\n");
728 }
10f59415
SC
729}
730
51f0e40d
AB
731/* Complete names of register groups, and add the special "prev" and "next"
732 names. */
c906108c 733
eb3ff9a5 734static void
51f0e40d 735tui_reggroup_completer (struct cmd_list_element *ignore,
eb3ff9a5 736 completion_tracker &tracker,
51f0e40d 737 const char *text, const char *word)
10f59415 738{
51f0e40d
AB
739 static const char *extra[] = { "next", "prev", NULL };
740 size_t len = strlen (word);
741 const char **tmp;
742
eb3ff9a5 743 reggroup_completer (ignore, tracker, text, word);
51f0e40d 744
eb3ff9a5 745 /* XXXX use complete_on_enum instead? */
51f0e40d
AB
746 for (tmp = extra; *tmp != NULL; ++tmp)
747 {
748 if (strncmp (word, *tmp, len) == 0)
b02f78f9 749 tracker.add_completion (make_unique_xstrdup (*tmp));
51f0e40d 750 }
10f59415 751}
c906108c 752
6eed1678
PA
753/* Get the register from the frame and return a printable
754 representation of it. */
755
756static char *
757tui_register_format (struct frame_info *frame, int regnum)
c906108c 758{
5eccfcc2 759 struct gdbarch *gdbarch = get_frame_arch (frame);
d20c1c3f 760
d7e74731
PA
761 string_file stream;
762
31b68d4a
TT
763 scoped_restore save_pagination
764 = make_scoped_restore (&pagination_enabled, 0);
765 scoped_restore save_stdout
766 = make_scoped_restore (&gdb_stdout, &stream);
767
d7e74731 768 gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1);
c46cc7df
SC
769
770 /* Remove the possible \n. */
d7e74731
PA
771 std::string &str = stream.string ();
772 if (!str.empty () && str.back () == '\n')
773 str.resize (str.size () - 1);
c46cc7df 774
312809f8 775 /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
31b68d4a 776 return tui_expand_tabs (str.c_str (), 0);
c46cc7df 777}
c906108c 778
1cc6d956
MS
779/* Get the register value from the given frame and format it for the
780 display. When changep is set, check if the new register value has
781 changed with respect to the previous call. */
2cdfa113 782static void
5eccfcc2 783tui_get_register (struct frame_info *frame,
41bcff7f
TT
784 struct tui_data_item_window *data,
785 int regnum, bool *changedp)
c906108c 786{
10f59415 787 if (changedp)
41bcff7f 788 *changedp = false;
c906108c
SS
789 if (target_has_registers)
790 {
6eed1678 791 char *prev_content = data->content;
10f59415 792
6eed1678 793 data->content = tui_register_format (frame, regnum);
9c5ea4d9 794
6eed1678
PA
795 if (changedp != NULL
796 && strcmp (prev_content, data->content) != 0)
41bcff7f 797 *changedp = true;
d20c1c3f 798
6eed1678 799 xfree (prev_content);
c906108c 800 }
6ba8e26f 801}
18ab23af
TT
802
803void
804_initialize_tui_regs (void)
805{
806 struct cmd_list_element **tuicmd, *cmd;
807
808 tuicmd = tui_get_cmd_list ();
809
810 cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
811TUI command to control the register window."), tuicmd);
812 set_cmd_completer (cmd, tui_reggroup_completer);
813}
This page took 2.070579 seconds and 4 git commands to generate.