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