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