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