tui-regs.c revision 1.11 1 1.1 christos /* TUI display registers in window.
2 1.1 christos
3 1.11 christos Copyright (C) 1998-2024 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos Contributed by Hewlett-Packard Company.
6 1.1 christos
7 1.1 christos This file is part of GDB.
8 1.1 christos
9 1.1 christos This program is free software; you can redistribute it and/or modify
10 1.1 christos it under the terms of the GNU General Public License as published by
11 1.1 christos the Free Software Foundation; either version 3 of the License, or
12 1.1 christos (at your option) any later version.
13 1.1 christos
14 1.1 christos This program is distributed in the hope that it will be useful,
15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 1.1 christos GNU General Public License for more details.
18 1.1 christos
19 1.1 christos You should have received a copy of the GNU General Public License
20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 1.1 christos
22 1.1 christos #include "arch-utils.h"
23 1.1 christos #include "tui/tui.h"
24 1.1 christos #include "tui/tui-data.h"
25 1.1 christos #include "symtab.h"
26 1.1 christos #include "gdbtypes.h"
27 1.11 christos #include "cli/cli-cmds.h"
28 1.1 christos #include "frame.h"
29 1.1 christos #include "regcache.h"
30 1.1 christos #include "inferior.h"
31 1.1 christos #include "target.h"
32 1.1 christos #include "tui/tui-layout.h"
33 1.1 christos #include "tui/tui-win.h"
34 1.1 christos #include "tui/tui-wingeneral.h"
35 1.1 christos #include "tui/tui-file.h"
36 1.1 christos #include "tui/tui-regs.h"
37 1.3 christos #include "tui/tui-io.h"
38 1.1 christos #include "reggroups.h"
39 1.1 christos #include "valprint.h"
40 1.5 christos #include "completer.h"
41 1.1 christos
42 1.1 christos #include "gdb_curses.h"
43 1.1 christos
44 1.9 christos /* A subclass of string_file that expands tab characters. */
45 1.9 christos class tab_expansion_file : public string_file
46 1.9 christos {
47 1.9 christos public:
48 1.1 christos
49 1.9 christos tab_expansion_file () = default;
50 1.1 christos
51 1.9 christos void write (const char *buf, long length_buf) override;
52 1.1 christos
53 1.9 christos private:
54 1.1 christos
55 1.9 christos int m_column = 0;
56 1.9 christos };
57 1.1 christos
58 1.9 christos void
59 1.9 christos tab_expansion_file::write (const char *buf, long length_buf)
60 1.9 christos {
61 1.9 christos for (long i = 0; i < length_buf; ++i)
62 1.9 christos {
63 1.9 christos if (buf[i] == '\t')
64 1.9 christos {
65 1.9 christos do
66 1.9 christos {
67 1.9 christos string_file::write (" ", 1);
68 1.9 christos ++m_column;
69 1.9 christos }
70 1.9 christos while ((m_column % 8) != 0);
71 1.9 christos }
72 1.9 christos else
73 1.9 christos {
74 1.9 christos string_file::write (&buf[i], 1);
75 1.9 christos if (buf[i] == '\n')
76 1.9 christos m_column = 0;
77 1.9 christos else
78 1.9 christos ++m_column;
79 1.9 christos }
80 1.9 christos }
81 1.9 christos }
82 1.1 christos
83 1.9 christos /* Get the register from the frame and return a printable
84 1.9 christos representation of it. */
85 1.1 christos
86 1.9 christos static std::string
87 1.11 christos tui_register_format (const frame_info_ptr &frame, int regnum)
88 1.1 christos {
89 1.9 christos struct gdbarch *gdbarch = get_frame_arch (frame);
90 1.9 christos
91 1.9 christos /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
92 1.9 christos tab_expansion_file stream;
93 1.9 christos gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1);
94 1.1 christos
95 1.9 christos /* Remove the possible \n. */
96 1.10 christos std::string str = stream.release ();
97 1.9 christos if (!str.empty () && str.back () == '\n')
98 1.11 christos str.pop_back ();
99 1.9 christos
100 1.9 christos return str;
101 1.9 christos }
102 1.9 christos
103 1.11 christos /* Compute the register value from the given frame and format it for
104 1.11 christos the display. update 'content' and set 'highlight' if the contents
105 1.11 christos changed. */
106 1.11 christos void
107 1.11 christos tui_register_info::update (const frame_info_ptr &frame)
108 1.11 christos {
109 1.11 christos std::string new_content = tui_register_format (frame, m_regno);
110 1.11 christos highlight = content != new_content;
111 1.11 christos content = std::move (new_content);
112 1.9 christos }
113 1.9 christos
114 1.9 christos /* See tui-regs.h. */
115 1.9 christos
116 1.9 christos int
117 1.9 christos tui_data_window::last_regs_line_no () const
118 1.9 christos {
119 1.9 christos int num_lines = m_regs_content.size () / m_regs_column_count;
120 1.9 christos if (m_regs_content.size () % m_regs_column_count)
121 1.9 christos num_lines++;
122 1.1 christos return num_lines;
123 1.1 christos }
124 1.1 christos
125 1.9 christos /* See tui-regs.h. */
126 1.1 christos
127 1.1 christos int
128 1.9 christos tui_data_window::line_from_reg_element_no (int element_no) const
129 1.1 christos {
130 1.9 christos if (element_no < m_regs_content.size ())
131 1.1 christos {
132 1.1 christos int i, line = (-1);
133 1.1 christos
134 1.1 christos i = 1;
135 1.1 christos while (line == (-1))
136 1.1 christos {
137 1.9 christos if (element_no < m_regs_column_count * i)
138 1.1 christos line = i - 1;
139 1.1 christos else
140 1.1 christos i++;
141 1.1 christos }
142 1.1 christos
143 1.1 christos return line;
144 1.1 christos }
145 1.1 christos else
146 1.1 christos return (-1);
147 1.1 christos }
148 1.1 christos
149 1.9 christos /* See tui-regs.h. */
150 1.1 christos
151 1.1 christos int
152 1.9 christos tui_data_window::first_reg_element_no_inline (int line_no) const
153 1.1 christos {
154 1.9 christos if (line_no * m_regs_column_count <= m_regs_content.size ())
155 1.9 christos return ((line_no + 1) * m_regs_column_count) - m_regs_column_count;
156 1.1 christos else
157 1.1 christos return (-1);
158 1.1 christos }
159 1.1 christos
160 1.1 christos /* Show the registers of the given group in the data window
161 1.1 christos and refresh the window. */
162 1.1 christos void
163 1.11 christos tui_data_window::set_register_group (const reggroup *group)
164 1.1 christos {
165 1.11 christos update_register_data (group);
166 1.9 christos rerender ();
167 1.1 christos }
168 1.1 christos
169 1.1 christos /* Set the data window to display the registers of the register group
170 1.11 christos using the given frame. */
171 1.1 christos
172 1.9 christos void
173 1.11 christos tui_data_window::update_register_data (const reggroup *group)
174 1.1 christos {
175 1.11 christos if (group == nullptr)
176 1.11 christos group = general_reggroup;
177 1.11 christos
178 1.11 christos if (!target_has_registers ()
179 1.11 christos || !target_has_stack ()
180 1.11 christos || !target_has_memory ())
181 1.11 christos {
182 1.11 christos set_title (_("Registers"));
183 1.11 christos m_current_group = nullptr;
184 1.11 christos m_gdbarch = nullptr;
185 1.11 christos m_regs_content.clear ();
186 1.11 christos return;
187 1.11 christos }
188 1.11 christos
189 1.11 christos frame_info_ptr frame = get_selected_frame (nullptr);
190 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame);
191 1.1 christos
192 1.11 christos if (m_current_group == group && m_gdbarch == gdbarch)
193 1.1 christos {
194 1.11 christos /* Nothing to do here. */
195 1.11 christos return;
196 1.11 christos }
197 1.1 christos
198 1.11 christos m_current_group = group;
199 1.11 christos m_gdbarch = gdbarch;
200 1.1 christos
201 1.11 christos /* Make a new title showing which group we display. */
202 1.11 christos this->set_title (string_printf ("Register group: %s", group->name ()));
203 1.1 christos
204 1.11 christos /* Create the registers. */
205 1.11 christos m_regs_content.clear ();
206 1.9 christos
207 1.11 christos for (int regnum = 0;
208 1.11 christos regnum < gdbarch_num_cooked_regs (gdbarch);
209 1.11 christos regnum++)
210 1.1 christos {
211 1.9 christos /* Must be in the group. */
212 1.9 christos if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
213 1.9 christos continue;
214 1.9 christos
215 1.9 christos /* If the register name is empty, it is undefined for this
216 1.9 christos processor, so don't display anything. */
217 1.11 christos const char *name = gdbarch_register_name (gdbarch, regnum);
218 1.10 christos if (*name == '\0')
219 1.9 christos continue;
220 1.9 christos
221 1.11 christos m_regs_content.emplace_back (regnum, frame);
222 1.1 christos }
223 1.9 christos }
224 1.9 christos
225 1.9 christos /* See tui-regs.h. */
226 1.1 christos
227 1.9 christos void
228 1.9 christos tui_data_window::display_registers_from (int start_element_no)
229 1.9 christos {
230 1.11 christos werase (handle.get ());
231 1.11 christos check_and_display_highlight_if_needed ();
232 1.11 christos
233 1.11 christos /* In case the regs window is not boxed, we'll write the last char in the
234 1.11 christos last line here, causing a scroll, so prevent that. */
235 1.11 christos scrollok (handle.get (), FALSE);
236 1.11 christos
237 1.9 christos int max_len = 0;
238 1.9 christos for (auto &&data_item_win : m_regs_content)
239 1.1 christos {
240 1.9 christos int len = data_item_win.content.size ();
241 1.9 christos
242 1.9 christos if (len > max_len)
243 1.9 christos max_len = len;
244 1.1 christos }
245 1.9 christos m_item_width = max_len + 1;
246 1.10 christos
247 1.10 christos int i;
248 1.10 christos /* Mark register windows above the visible area. */
249 1.10 christos for (i = 0; i < start_element_no; i++)
250 1.10 christos m_regs_content[i].y = 0;
251 1.1 christos
252 1.11 christos m_regs_column_count = (width - box_size ()) / m_item_width;
253 1.9 christos if (m_regs_column_count == 0)
254 1.9 christos m_regs_column_count = 1;
255 1.11 christos m_item_width = (width - box_size ()) / m_regs_column_count;
256 1.9 christos
257 1.9 christos /* Now create each data "sub" window, and write the display into
258 1.9 christos it. */
259 1.11 christos int cur_y = box_width ();
260 1.11 christos while (i < m_regs_content.size () && cur_y <= height - box_size ())
261 1.1 christos {
262 1.9 christos for (int j = 0;
263 1.9 christos j < m_regs_column_count && i < m_regs_content.size ();
264 1.9 christos j++)
265 1.1 christos {
266 1.9 christos /* Create the window if necessary. */
267 1.11 christos m_regs_content[i].x = box_width () + (m_item_width * j);
268 1.9 christos m_regs_content[i].y = cur_y;
269 1.9 christos m_regs_content[i].rerender (handle.get (), m_item_width);
270 1.9 christos i++; /* Next register. */
271 1.1 christos }
272 1.9 christos cur_y++; /* Next row. */
273 1.9 christos }
274 1.10 christos
275 1.10 christos /* Mark register windows below the visible area. */
276 1.10 christos for (; i < m_regs_content.size (); i++)
277 1.10 christos m_regs_content[i].y = 0;
278 1.10 christos
279 1.10 christos refresh_window ();
280 1.9 christos }
281 1.1 christos
282 1.9 christos /* See tui-regs.h. */
283 1.9 christos
284 1.9 christos void
285 1.9 christos tui_data_window::display_reg_element_at_line (int start_element_no,
286 1.9 christos int start_line_no)
287 1.9 christos {
288 1.9 christos int element_no = start_element_no;
289 1.9 christos
290 1.9 christos if (start_element_no != 0 && start_line_no != 0)
291 1.9 christos {
292 1.9 christos int last_line_no, first_line_on_last_page;
293 1.1 christos
294 1.9 christos last_line_no = last_regs_line_no ();
295 1.11 christos first_line_on_last_page = last_line_no - (height - box_size ());
296 1.9 christos if (first_line_on_last_page < 0)
297 1.9 christos first_line_on_last_page = 0;
298 1.1 christos
299 1.9 christos /* If the element_no causes us to scroll past the end of the
300 1.9 christos registers, adjust what element to really start the
301 1.9 christos display at. */
302 1.9 christos if (start_line_no > first_line_on_last_page)
303 1.9 christos element_no = first_reg_element_no_inline (first_line_on_last_page);
304 1.1 christos }
305 1.9 christos display_registers_from (element_no);
306 1.1 christos }
307 1.1 christos
308 1.9 christos /* See tui-regs.h. */
309 1.1 christos
310 1.9 christos int
311 1.9 christos tui_data_window::display_registers_from_line (int line_no)
312 1.1 christos {
313 1.9 christos int element_no;
314 1.9 christos
315 1.9 christos if (line_no < 0)
316 1.9 christos line_no = 0;
317 1.9 christos else
318 1.1 christos {
319 1.9 christos /* Make sure that we don't display off the end of the
320 1.9 christos registers. */
321 1.9 christos if (line_no >= last_regs_line_no ())
322 1.9 christos {
323 1.9 christos line_no = line_from_reg_element_no (m_regs_content.size () - 1);
324 1.9 christos if (line_no < 0)
325 1.9 christos line_no = 0;
326 1.9 christos }
327 1.9 christos }
328 1.9 christos
329 1.9 christos element_no = first_reg_element_no_inline (line_no);
330 1.9 christos if (element_no < m_regs_content.size ())
331 1.9 christos display_reg_element_at_line (element_no, line_no);
332 1.9 christos else
333 1.9 christos line_no = (-1);
334 1.9 christos
335 1.9 christos return line_no;
336 1.9 christos }
337 1.1 christos
338 1.1 christos
339 1.9 christos /* Answer the index first element displayed. If none are displayed,
340 1.9 christos then return (-1). */
341 1.9 christos int
342 1.9 christos tui_data_window::first_data_item_displayed ()
343 1.9 christos {
344 1.9 christos for (int i = 0; i < m_regs_content.size (); i++)
345 1.9 christos {
346 1.11 christos if (m_regs_content[i].visible ())
347 1.9 christos return i;
348 1.1 christos }
349 1.9 christos
350 1.9 christos return -1;
351 1.1 christos }
352 1.1 christos
353 1.9 christos void
354 1.11 christos tui_data_window::erase_data_content ()
355 1.9 christos {
356 1.11 christos center_string (_("[ Register Values Unavailable ]"));
357 1.9 christos }
358 1.9 christos
359 1.9 christos /* See tui-regs.h. */
360 1.1 christos
361 1.9 christos void
362 1.9 christos tui_data_window::rerender ()
363 1.9 christos {
364 1.9 christos if (m_regs_content.empty ())
365 1.11 christos erase_data_content ();
366 1.9 christos else
367 1.11 christos display_registers_from (0);
368 1.11 christos tui_wrefresh (handle.get ());
369 1.9 christos }
370 1.9 christos
371 1.9 christos
372 1.9 christos /* Scroll the data window vertically forward or backward. */
373 1.9 christos void
374 1.9 christos tui_data_window::do_scroll_vertical (int num_to_scroll)
375 1.9 christos {
376 1.9 christos int first_element_no;
377 1.9 christos int first_line = (-1);
378 1.1 christos
379 1.9 christos first_element_no = first_data_item_displayed ();
380 1.9 christos if (first_element_no < m_regs_content.size ())
381 1.9 christos first_line = line_from_reg_element_no (first_element_no);
382 1.9 christos else
383 1.9 christos { /* Calculate the first line from the element number which is in
384 1.10 christos the general data content. */
385 1.1 christos }
386 1.1 christos
387 1.9 christos if (first_line >= 0)
388 1.9 christos {
389 1.9 christos first_line += num_to_scroll;
390 1.9 christos display_registers_from_line (first_line);
391 1.9 christos }
392 1.1 christos }
393 1.1 christos
394 1.1 christos /* This function check all displayed registers for changes in values,
395 1.1 christos given a particular frame. If the values have changed, they are
396 1.1 christos updated with the new value and highlighted. */
397 1.1 christos void
398 1.11 christos tui_data_window::check_register_values (const frame_info_ptr &frame)
399 1.1 christos {
400 1.11 christos if (frame == nullptr)
401 1.11 christos set_register_group (nullptr);
402 1.9 christos else
403 1.1 christos {
404 1.11 christos /* If the frame architecture changed, we need to reset the
405 1.11 christos register group. */
406 1.11 christos struct gdbarch *gdbarch = get_frame_arch (frame);
407 1.11 christos if (gdbarch != m_gdbarch)
408 1.11 christos set_register_group (nullptr);
409 1.11 christos else
410 1.9 christos {
411 1.11 christos for (tui_register_info &data_item_win : m_regs_content)
412 1.11 christos {
413 1.11 christos bool was_hilighted = data_item_win.highlight;
414 1.9 christos
415 1.11 christos data_item_win.update (frame);
416 1.1 christos
417 1.11 christos /* Register windows whose y == 0 are outside the visible area. */
418 1.11 christos if ((data_item_win.highlight || was_hilighted)
419 1.11 christos && data_item_win.visible ())
420 1.11 christos data_item_win.rerender (handle.get (), m_item_width);
421 1.11 christos }
422 1.1 christos }
423 1.11 christos tui_wrefresh (handle.get ());
424 1.1 christos }
425 1.1 christos }
426 1.1 christos
427 1.1 christos /* Display a register in a window. If hilite is TRUE, then the value
428 1.1 christos will be displayed in reverse video. */
429 1.9 christos void
430 1.11 christos tui_register_info::rerender (WINDOW *handle, int field_width)
431 1.1 christos {
432 1.9 christos if (highlight)
433 1.9 christos /* We ignore the return value, casting it to void in order to avoid
434 1.9 christos a compiler warning. The warning itself was introduced by a patch
435 1.9 christos to ncurses 5.7 dated 2009-08-29, changing this macro to expand
436 1.9 christos to code that causes the compiler to generate an unused-value
437 1.9 christos warning. */
438 1.9 christos (void) wstandout (handle);
439 1.9 christos
440 1.9 christos mvwaddnstr (handle, y, x, content.c_str (), field_width - 1);
441 1.10 christos if (content.size () < field_width)
442 1.10 christos waddstr (handle, n_spaces (field_width - content.size ()));
443 1.1 christos
444 1.9 christos if (highlight)
445 1.9 christos /* We ignore the return value, casting it to void in order to avoid
446 1.9 christos a compiler warning. The warning itself was introduced by a patch
447 1.9 christos to ncurses 5.7 dated 2009-08-29, changing this macro to expand
448 1.9 christos to code that causes the compiler to generate an unused-value
449 1.9 christos warning. */
450 1.9 christos (void) wstandend (handle);
451 1.1 christos }
452 1.1 christos
453 1.10 christos /* Helper for "tui reg next", returns the next register group after
454 1.10 christos CURRENT_GROUP in the register group list for GDBARCH, with wrap around
455 1.10 christos behaviour.
456 1.10 christos
457 1.10 christos If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
458 1.10 christos just been displayed and has no current group selected) or the currently
459 1.10 christos selected register group can't be found (e.g. if the architecture has
460 1.10 christos changed since the register window was last updated), then the first
461 1.10 christos register group will be returned. */
462 1.10 christos
463 1.10 christos static const reggroup *
464 1.10 christos tui_reg_next (const reggroup *current_group, struct gdbarch *gdbarch)
465 1.10 christos {
466 1.10 christos const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
467 1.10 christos auto it = std::find (groups.begin (), groups.end (), current_group);
468 1.10 christos if (it != groups.end ())
469 1.10 christos it++;
470 1.10 christos if (it == groups.end ())
471 1.10 christos return groups.front ();
472 1.10 christos return *it;
473 1.10 christos }
474 1.10 christos
475 1.10 christos /* Helper for "tui reg prev", returns the register group previous to
476 1.10 christos CURRENT_GROUP in the register group list for GDBARCH, with wrap around
477 1.10 christos behaviour.
478 1.10 christos
479 1.10 christos If CURRENT_GROUP is nullptr (e.g. if the tui register window has only
480 1.10 christos just been displayed and has no current group selected) or the currently
481 1.10 christos selected register group can't be found (e.g. if the architecture has
482 1.10 christos changed since the register window was last updated), then the last
483 1.10 christos register group will be returned. */
484 1.10 christos
485 1.10 christos static const reggroup *
486 1.10 christos tui_reg_prev (const reggroup *current_group, struct gdbarch *gdbarch)
487 1.10 christos {
488 1.10 christos const std::vector<const reggroup *> &groups = gdbarch_reggroups (gdbarch);
489 1.10 christos auto it = std::find (groups.rbegin (), groups.rend (), current_group);
490 1.10 christos if (it != groups.rend ())
491 1.10 christos it++;
492 1.10 christos if (it == groups.rend ())
493 1.10 christos return groups.back ();
494 1.10 christos return *it;
495 1.1 christos }
496 1.1 christos
497 1.5 christos /* Implement the 'tui reg' command. Changes the register group displayed
498 1.5 christos in the tui register window. Displays the tui register window if it is
499 1.5 christos not already on display. */
500 1.5 christos
501 1.1 christos static void
502 1.8 christos tui_reg_command (const char *args, int from_tty)
503 1.1 christos {
504 1.5 christos struct gdbarch *gdbarch = get_current_arch ();
505 1.5 christos
506 1.5 christos if (args != NULL)
507 1.5 christos {
508 1.5 christos size_t len = strlen (args);
509 1.5 christos
510 1.5 christos /* Make sure the curses mode is enabled. */
511 1.5 christos tui_enable ();
512 1.5 christos
513 1.9 christos tui_suppress_output suppress;
514 1.9 christos
515 1.5 christos /* Make sure the register window is visible. If not, select an
516 1.5 christos appropriate layout. We need to do this before trying to run the
517 1.5 christos 'next' or 'prev' commands. */
518 1.9 christos if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
519 1.9 christos tui_regs_layout ();
520 1.5 christos
521 1.10 christos const reggroup *match = nullptr;
522 1.10 christos const reggroup *current_group = TUI_DATA_WIN->get_current_group ();
523 1.5 christos if (strncmp (args, "next", len) == 0)
524 1.9 christos match = tui_reg_next (current_group, gdbarch);
525 1.5 christos else if (strncmp (args, "prev", len) == 0)
526 1.9 christos match = tui_reg_prev (current_group, gdbarch);
527 1.10 christos else
528 1.5 christos {
529 1.10 christos /* This loop matches on the initial part of a register group
530 1.10 christos name. If this initial part in ARGS matches only one register
531 1.10 christos group then the switch is made. */
532 1.10 christos for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
533 1.5 christos {
534 1.10 christos if (strncmp (group->name (), args, len) == 0)
535 1.10 christos {
536 1.10 christos if (match != NULL)
537 1.10 christos error (_("ambiguous register group name '%s'"), args);
538 1.10 christos match = group;
539 1.10 christos }
540 1.5 christos }
541 1.5 christos }
542 1.5 christos
543 1.5 christos if (match == NULL)
544 1.5 christos error (_("unknown register group '%s'"), args);
545 1.5 christos
546 1.11 christos TUI_DATA_WIN->set_register_group (match);
547 1.5 christos }
548 1.5 christos else
549 1.5 christos {
550 1.10 christos gdb_printf (_("\"tui reg\" must be followed by the name of "
551 1.10 christos "either a register group,\nor one of 'next' "
552 1.10 christos "or 'prev'. Known register groups are:\n"));
553 1.5 christos
554 1.10 christos bool first = true;
555 1.10 christos for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
556 1.5 christos {
557 1.5 christos if (!first)
558 1.10 christos gdb_printf (", ");
559 1.10 christos first = false;
560 1.10 christos gdb_printf ("%s", group->name ());
561 1.5 christos }
562 1.5 christos
563 1.10 christos gdb_printf ("\n");
564 1.5 christos }
565 1.1 christos }
566 1.1 christos
567 1.5 christos /* Complete names of register groups, and add the special "prev" and "next"
568 1.5 christos names. */
569 1.5 christos
570 1.8 christos static void
571 1.5 christos tui_reggroup_completer (struct cmd_list_element *ignore,
572 1.8 christos completion_tracker &tracker,
573 1.5 christos const char *text, const char *word)
574 1.1 christos {
575 1.9 christos static const char * const extra[] = { "next", "prev", NULL };
576 1.5 christos
577 1.8 christos reggroup_completer (ignore, tracker, text, word);
578 1.1 christos
579 1.9 christos complete_on_enum (tracker, extra, text, word);
580 1.1 christos }
581 1.1 christos
582 1.9 christos void _initialize_tui_regs ();
583 1.1 christos void
584 1.9 christos _initialize_tui_regs ()
585 1.1 christos {
586 1.5 christos struct cmd_list_element **tuicmd, *cmd;
587 1.1 christos
588 1.1 christos tuicmd = tui_get_cmd_list ();
589 1.1 christos
590 1.5 christos cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
591 1.9 christos TUI command to control the register window.\n\
592 1.9 christos Usage: tui reg NAME\n\
593 1.9 christos NAME is the name of the register group to display"), tuicmd);
594 1.5 christos set_cmd_completer (cmd, tui_reggroup_completer);
595 1.1 christos }
596