tui-regs.c revision 1.5 1 1.1 christos /* TUI display registers in window.
2 1.1 christos
3 1.3 christos Copyright (C) 1998-2015 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-windata.h"
36 1.1 christos #include "tui/tui-wingeneral.h"
37 1.1 christos #include "tui/tui-file.h"
38 1.1 christos #include "tui/tui-regs.h"
39 1.3 christos #include "tui/tui-io.h"
40 1.1 christos #include "reggroups.h"
41 1.1 christos #include "valprint.h"
42 1.5 christos #include "completer.h"
43 1.1 christos
44 1.1 christos #include "gdb_curses.h"
45 1.1 christos
46 1.1 christos
47 1.1 christos /*****************************************
48 1.1 christos ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
49 1.1 christos ******************************************/
50 1.1 christos static void
51 1.1 christos tui_display_register (struct tui_data_element *data,
52 1.1 christos struct tui_gen_win_info *win_info);
53 1.1 christos
54 1.1 christos static enum tui_status tui_show_register_group (struct reggroup *group,
55 1.1 christos struct frame_info *frame,
56 1.1 christos int refresh_values_only);
57 1.1 christos
58 1.1 christos static enum tui_status tui_get_register (struct frame_info *frame,
59 1.1 christos struct tui_data_element *data,
60 1.1 christos int regnum, int *changedp);
61 1.1 christos
62 1.1 christos
63 1.1 christos
64 1.1 christos /*****************************************
65 1.1 christos ** PUBLIC FUNCTIONS **
66 1.1 christos ******************************************/
67 1.1 christos
68 1.1 christos /* Answer the number of the last line in the regs display. If there
69 1.1 christos are no registers (-1) is returned. */
70 1.1 christos int
71 1.1 christos tui_last_regs_line_no (void)
72 1.1 christos {
73 1.1 christos int num_lines = (-1);
74 1.1 christos
75 1.1 christos if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
76 1.1 christos {
77 1.1 christos num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count /
78 1.1 christos TUI_DATA_WIN->detail.data_display_info.regs_column_count);
79 1.1 christos if (TUI_DATA_WIN->detail.data_display_info.regs_content_count %
80 1.1 christos TUI_DATA_WIN->detail.data_display_info.regs_column_count)
81 1.1 christos num_lines++;
82 1.1 christos }
83 1.1 christos return num_lines;
84 1.1 christos }
85 1.1 christos
86 1.1 christos
87 1.1 christos /* Answer the line number that the register element at element_no is
88 1.1 christos on. If element_no is greater than the number of register elements
89 1.1 christos there are, -1 is returned. */
90 1.1 christos int
91 1.1 christos tui_line_from_reg_element_no (int element_no)
92 1.1 christos {
93 1.1 christos if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
94 1.1 christos {
95 1.1 christos int i, line = (-1);
96 1.1 christos
97 1.1 christos i = 1;
98 1.1 christos while (line == (-1))
99 1.1 christos {
100 1.1 christos if (element_no <
101 1.1 christos (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i))
102 1.1 christos line = i - 1;
103 1.1 christos else
104 1.1 christos i++;
105 1.1 christos }
106 1.1 christos
107 1.1 christos return line;
108 1.1 christos }
109 1.1 christos else
110 1.1 christos return (-1);
111 1.1 christos }
112 1.1 christos
113 1.1 christos
114 1.1 christos /* Answer the index of the first element in line_no. If line_no is
115 1.1 christos past the register area (-1) is returned. */
116 1.1 christos int
117 1.1 christos tui_first_reg_element_no_inline (int line_no)
118 1.1 christos {
119 1.1 christos if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count)
120 1.1 christos <= TUI_DATA_WIN->detail.data_display_info.regs_content_count)
121 1.1 christos return ((line_no + 1) *
122 1.1 christos TUI_DATA_WIN->detail.data_display_info.regs_column_count) -
123 1.1 christos TUI_DATA_WIN->detail.data_display_info.regs_column_count;
124 1.1 christos else
125 1.1 christos return (-1);
126 1.1 christos }
127 1.1 christos
128 1.1 christos
129 1.1 christos /* Show the registers of the given group in the data window
130 1.1 christos and refresh the window. */
131 1.1 christos void
132 1.1 christos tui_show_registers (struct reggroup *group)
133 1.1 christos {
134 1.1 christos enum tui_status ret = TUI_FAILURE;
135 1.1 christos struct tui_data_info *display_info;
136 1.1 christos
137 1.1 christos /* Make sure the curses mode is enabled. */
138 1.1 christos tui_enable ();
139 1.1 christos
140 1.1 christos /* Make sure the register window is visible. If not, select an
141 1.1 christos appropriate layout. */
142 1.1 christos if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
143 1.5 christos tui_set_layout_by_name (DATA_NAME);
144 1.1 christos
145 1.1 christos display_info = &TUI_DATA_WIN->detail.data_display_info;
146 1.1 christos if (group == 0)
147 1.1 christos group = general_reggroup;
148 1.1 christos
149 1.1 christos /* Say that registers should be displayed, even if there is a
150 1.1 christos problem. */
151 1.1 christos display_info->display_regs = TRUE;
152 1.1 christos
153 1.1 christos if (target_has_registers && target_has_stack && target_has_memory)
154 1.1 christos {
155 1.1 christos ret = tui_show_register_group (group, get_selected_frame (NULL),
156 1.1 christos group == display_info->current_group);
157 1.1 christos }
158 1.1 christos if (ret == TUI_FAILURE)
159 1.1 christos {
160 1.1 christos display_info->current_group = 0;
161 1.1 christos tui_erase_data_content (NO_REGS_STRING);
162 1.1 christos }
163 1.1 christos else
164 1.1 christos {
165 1.1 christos int i;
166 1.1 christos
167 1.1 christos /* Clear all notation of changed values. */
168 1.1 christos for (i = 0; i < display_info->regs_content_count; i++)
169 1.1 christos {
170 1.1 christos struct tui_gen_win_info *data_item_win;
171 1.1 christos struct tui_win_element *win;
172 1.1 christos
173 1.1 christos data_item_win = &display_info->regs_content[i]
174 1.1 christos ->which_element.data_window;
175 1.5 christos win = data_item_win->content[0];
176 1.1 christos win->which_element.data.highlight = FALSE;
177 1.1 christos }
178 1.1 christos display_info->current_group = group;
179 1.1 christos tui_display_all_data ();
180 1.1 christos }
181 1.1 christos }
182 1.1 christos
183 1.1 christos
184 1.1 christos /* Set the data window to display the registers of the register group
185 1.1 christos using the given frame. Values are refreshed only when
186 1.1 christos refresh_values_only is TRUE. */
187 1.1 christos
188 1.1 christos static enum tui_status
189 1.1 christos tui_show_register_group (struct reggroup *group,
190 1.1 christos struct frame_info *frame,
191 1.1 christos int refresh_values_only)
192 1.1 christos {
193 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame);
194 1.1 christos enum tui_status ret = TUI_FAILURE;
195 1.1 christos int nr_regs;
196 1.1 christos int allocated_here = FALSE;
197 1.1 christos int regnum, pos;
198 1.1 christos char title[80];
199 1.1 christos struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
200 1.1 christos
201 1.1 christos /* Make a new title showing which group we display. */
202 1.1 christos snprintf (title, sizeof (title) - 1, "Register group: %s",
203 1.1 christos reggroup_name (group));
204 1.1 christos xfree (TUI_DATA_WIN->generic.title);
205 1.1 christos TUI_DATA_WIN->generic.title = xstrdup (title);
206 1.1 christos
207 1.1 christos /* See how many registers must be displayed. */
208 1.1 christos nr_regs = 0;
209 1.1 christos for (regnum = 0;
210 1.1 christos regnum < gdbarch_num_regs (gdbarch)
211 1.1 christos + gdbarch_num_pseudo_regs (gdbarch);
212 1.1 christos regnum++)
213 1.1 christos {
214 1.1 christos const char *name;
215 1.1 christos
216 1.1 christos /* Must be in the group. */
217 1.1 christos if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
218 1.1 christos continue;
219 1.1 christos
220 1.1 christos /* If the register name is empty, it is undefined for this
221 1.1 christos processor, so don't display anything. */
222 1.1 christos name = gdbarch_register_name (gdbarch, regnum);
223 1.1 christos if (name == 0 || *name == '\0')
224 1.1 christos continue;
225 1.1 christos
226 1.1 christos nr_regs++;
227 1.1 christos }
228 1.1 christos
229 1.1 christos if (display_info->regs_content_count > 0 && !refresh_values_only)
230 1.1 christos {
231 1.1 christos tui_free_data_content (display_info->regs_content,
232 1.1 christos display_info->regs_content_count);
233 1.1 christos display_info->regs_content_count = 0;
234 1.1 christos }
235 1.1 christos
236 1.1 christos if (display_info->regs_content_count <= 0)
237 1.1 christos {
238 1.1 christos display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN);
239 1.1 christos allocated_here = TRUE;
240 1.1 christos refresh_values_only = FALSE;
241 1.1 christos }
242 1.1 christos
243 1.1 christos if (display_info->regs_content != (tui_win_content) NULL)
244 1.1 christos {
245 1.1 christos if (!refresh_values_only || allocated_here)
246 1.1 christos {
247 1.1 christos TUI_DATA_WIN->generic.content = (void*) NULL;
248 1.1 christos TUI_DATA_WIN->generic.content_size = 0;
249 1.1 christos tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs);
250 1.1 christos display_info->regs_content
251 1.1 christos = (tui_win_content) TUI_DATA_WIN->generic.content;
252 1.1 christos display_info->regs_content_count = nr_regs;
253 1.1 christos }
254 1.1 christos
255 1.1 christos /* Now set the register names and values. */
256 1.1 christos pos = 0;
257 1.1 christos for (regnum = 0;
258 1.1 christos regnum < gdbarch_num_regs (gdbarch)
259 1.1 christos + gdbarch_num_pseudo_regs (gdbarch);
260 1.1 christos regnum++)
261 1.1 christos {
262 1.1 christos struct tui_gen_win_info *data_item_win;
263 1.1 christos struct tui_data_element *data;
264 1.1 christos const char *name;
265 1.1 christos
266 1.1 christos /* Must be in the group. */
267 1.1 christos if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
268 1.1 christos continue;
269 1.1 christos
270 1.1 christos /* If the register name is empty, it is undefined for this
271 1.1 christos processor, so don't display anything. */
272 1.1 christos name = gdbarch_register_name (gdbarch, regnum);
273 1.1 christos if (name == 0 || *name == '\0')
274 1.1 christos continue;
275 1.1 christos
276 1.1 christos data_item_win =
277 1.1 christos &display_info->regs_content[pos]->which_element.data_window;
278 1.5 christos data = &data_item_win->content[0]->which_element.data;
279 1.1 christos if (data)
280 1.1 christos {
281 1.1 christos if (!refresh_values_only)
282 1.1 christos {
283 1.1 christos data->item_no = regnum;
284 1.1 christos data->name = name;
285 1.1 christos data->highlight = FALSE;
286 1.1 christos }
287 1.1 christos tui_get_register (frame, data, regnum, 0);
288 1.1 christos }
289 1.1 christos pos++;
290 1.1 christos }
291 1.1 christos
292 1.1 christos TUI_DATA_WIN->generic.content_size =
293 1.1 christos display_info->regs_content_count + display_info->data_content_count;
294 1.1 christos ret = TUI_SUCCESS;
295 1.1 christos }
296 1.1 christos
297 1.1 christos return ret;
298 1.1 christos }
299 1.1 christos
300 1.1 christos /* Function to display the registers in the content from
301 1.1 christos 'start_element_no' until the end of the register content or the end
302 1.1 christos of the display height. No checking for displaying past the end of
303 1.1 christos the registers is done here. */
304 1.1 christos void
305 1.1 christos tui_display_registers_from (int start_element_no)
306 1.1 christos {
307 1.1 christos struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info;
308 1.1 christos
309 1.1 christos if (display_info->regs_content != (tui_win_content) NULL
310 1.1 christos && display_info->regs_content_count > 0)
311 1.1 christos {
312 1.1 christos int i = start_element_no;
313 1.1 christos int j, item_win_width, cur_y;
314 1.1 christos
315 1.1 christos int max_len = 0;
316 1.1 christos for (i = 0; i < display_info->regs_content_count; i++)
317 1.1 christos {
318 1.1 christos struct tui_data_element *data;
319 1.1 christos struct tui_gen_win_info *data_item_win;
320 1.1 christos char *p;
321 1.1 christos int len;
322 1.1 christos
323 1.1 christos data_item_win
324 1.1 christos = &display_info->regs_content[i]->which_element.data_window;
325 1.5 christos data = &data_item_win->content[0]->which_element.data;
326 1.1 christos len = 0;
327 1.1 christos p = data->content;
328 1.1 christos if (p != 0)
329 1.1 christos while (*p)
330 1.1 christos {
331 1.1 christos if (*p++ == '\t')
332 1.1 christos len = 8 * ((len / 8) + 1);
333 1.1 christos else
334 1.1 christos len++;
335 1.1 christos }
336 1.1 christos
337 1.1 christos if (len > max_len)
338 1.1 christos max_len = len;
339 1.1 christos }
340 1.1 christos item_win_width = max_len + 1;
341 1.1 christos i = start_element_no;
342 1.1 christos
343 1.1 christos display_info->regs_column_count =
344 1.1 christos (TUI_DATA_WIN->generic.width - 2) / item_win_width;
345 1.1 christos if (display_info->regs_column_count == 0)
346 1.1 christos display_info->regs_column_count = 1;
347 1.1 christos item_win_width =
348 1.1 christos (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count;
349 1.1 christos
350 1.1 christos /* Now create each data "sub" window, and write the display into
351 1.1 christos it. */
352 1.1 christos cur_y = 1;
353 1.1 christos while (i < display_info->regs_content_count
354 1.1 christos && cur_y <= TUI_DATA_WIN->generic.viewport_height)
355 1.1 christos {
356 1.1 christos for (j = 0;
357 1.1 christos j < display_info->regs_column_count
358 1.1 christos && i < display_info->regs_content_count;
359 1.1 christos j++)
360 1.1 christos {
361 1.1 christos struct tui_gen_win_info *data_item_win;
362 1.1 christos struct tui_data_element *data_element_ptr;
363 1.1 christos
364 1.1 christos /* Create the window if necessary. */
365 1.1 christos data_item_win = &display_info->regs_content[i]
366 1.1 christos ->which_element.data_window;
367 1.5 christos data_element_ptr = &data_item_win->content[0]->which_element.data;
368 1.1 christos if (data_item_win->handle != (WINDOW*) NULL
369 1.1 christos && (data_item_win->height != 1
370 1.1 christos || data_item_win->width != item_win_width
371 1.1 christos || data_item_win->origin.x != (item_win_width * j) + 1
372 1.1 christos || data_item_win->origin.y != cur_y))
373 1.1 christos {
374 1.1 christos tui_delete_win (data_item_win->handle);
375 1.1 christos data_item_win->handle = 0;
376 1.1 christos }
377 1.1 christos
378 1.1 christos if (data_item_win->handle == (WINDOW *) NULL)
379 1.1 christos {
380 1.1 christos data_item_win->height = 1;
381 1.1 christos data_item_win->width = item_win_width;
382 1.1 christos data_item_win->origin.x = (item_win_width * j) + 1;
383 1.1 christos data_item_win->origin.y = cur_y;
384 1.1 christos tui_make_window (data_item_win, DONT_BOX_WINDOW);
385 1.1 christos scrollok (data_item_win->handle, FALSE);
386 1.1 christos }
387 1.1 christos touchwin (data_item_win->handle);
388 1.1 christos
389 1.1 christos /* Get the printable representation of the register
390 1.1 christos and display it. */
391 1.1 christos tui_display_register (data_element_ptr, data_item_win);
392 1.1 christos i++; /* Next register. */
393 1.1 christos }
394 1.1 christos cur_y++; /* Next row. */
395 1.1 christos }
396 1.1 christos }
397 1.1 christos }
398 1.1 christos
399 1.1 christos
400 1.1 christos /* Function to display the registers in the content from
401 1.1 christos 'start_element_no' on 'start_line_no' until the end of the register
402 1.1 christos content or the end of the display height. This function checks
403 1.1 christos that we won't display off the end of the register display. */
404 1.1 christos static void
405 1.1 christos tui_display_reg_element_at_line (int start_element_no,
406 1.1 christos int start_line_no)
407 1.1 christos {
408 1.1 christos if (TUI_DATA_WIN->detail.data_display_info.regs_content
409 1.1 christos != (tui_win_content) NULL
410 1.1 christos && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
411 1.1 christos {
412 1.1 christos int element_no = start_element_no;
413 1.1 christos
414 1.1 christos if (start_element_no != 0 && start_line_no != 0)
415 1.1 christos {
416 1.1 christos int last_line_no, first_line_on_last_page;
417 1.1 christos
418 1.1 christos last_line_no = tui_last_regs_line_no ();
419 1.1 christos first_line_on_last_page
420 1.1 christos = last_line_no - (TUI_DATA_WIN->generic.height - 2);
421 1.1 christos if (first_line_on_last_page < 0)
422 1.1 christos first_line_on_last_page = 0;
423 1.1 christos
424 1.1 christos /* If there is no other data displayed except registers, and
425 1.1 christos the element_no causes us to scroll past the end of the
426 1.1 christos registers, adjust what element to really start the
427 1.1 christos display at. */
428 1.1 christos if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0
429 1.1 christos && start_line_no > first_line_on_last_page)
430 1.1 christos element_no
431 1.1 christos = tui_first_reg_element_no_inline (first_line_on_last_page);
432 1.1 christos }
433 1.1 christos tui_display_registers_from (element_no);
434 1.1 christos }
435 1.1 christos }
436 1.1 christos
437 1.1 christos
438 1.1 christos
439 1.1 christos /* Function to display the registers starting at line line_no in the
440 1.1 christos data window. Answers the line number that the display actually
441 1.1 christos started from. If nothing is displayed (-1) is returned. */
442 1.1 christos int
443 1.1 christos tui_display_registers_from_line (int line_no,
444 1.1 christos int force_display)
445 1.1 christos {
446 1.1 christos if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0)
447 1.1 christos {
448 1.1 christos int line, element_no;
449 1.1 christos
450 1.1 christos if (line_no < 0)
451 1.1 christos line = 0;
452 1.1 christos else if (force_display)
453 1.1 christos { /* If we must display regs (force_display is true), then
454 1.1 christos make sure that we don't display off the end of the
455 1.1 christos registers. */
456 1.1 christos if (line_no >= tui_last_regs_line_no ())
457 1.1 christos {
458 1.1 christos if ((line = tui_line_from_reg_element_no (
459 1.1 christos TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0)
460 1.1 christos line = 0;
461 1.1 christos }
462 1.1 christos else
463 1.1 christos line = line_no;
464 1.1 christos }
465 1.1 christos else
466 1.1 christos line = line_no;
467 1.1 christos
468 1.1 christos element_no = tui_first_reg_element_no_inline (line);
469 1.1 christos if (element_no
470 1.1 christos < TUI_DATA_WIN->detail.data_display_info.regs_content_count)
471 1.1 christos tui_display_reg_element_at_line (element_no, line);
472 1.1 christos else
473 1.1 christos line = (-1);
474 1.1 christos
475 1.1 christos return line;
476 1.1 christos }
477 1.1 christos
478 1.1 christos return (-1); /* Nothing was displayed. */
479 1.1 christos }
480 1.1 christos
481 1.1 christos
482 1.1 christos /* This function check all displayed registers for changes in values,
483 1.1 christos given a particular frame. If the values have changed, they are
484 1.1 christos updated with the new value and highlighted. */
485 1.1 christos void
486 1.1 christos tui_check_register_values (struct frame_info *frame)
487 1.1 christos {
488 1.1 christos if (TUI_DATA_WIN != NULL
489 1.1 christos && TUI_DATA_WIN->generic.is_visible)
490 1.1 christos {
491 1.1 christos struct tui_data_info *display_info
492 1.1 christos = &TUI_DATA_WIN->detail.data_display_info;
493 1.1 christos
494 1.1 christos if (display_info->regs_content_count <= 0
495 1.1 christos && display_info->display_regs)
496 1.1 christos tui_show_registers (display_info->current_group);
497 1.1 christos else
498 1.1 christos {
499 1.1 christos int i;
500 1.1 christos
501 1.1 christos for (i = 0; (i < display_info->regs_content_count); i++)
502 1.1 christos {
503 1.1 christos struct tui_data_element *data;
504 1.1 christos struct tui_gen_win_info *data_item_win_ptr;
505 1.1 christos int was_hilighted;
506 1.1 christos
507 1.1 christos data_item_win_ptr = &display_info->regs_content[i]->
508 1.1 christos which_element.data_window;
509 1.5 christos data = &data_item_win_ptr->content[0]->which_element.data;
510 1.1 christos was_hilighted = data->highlight;
511 1.1 christos
512 1.1 christos tui_get_register (frame, data,
513 1.1 christos data->item_no, &data->highlight);
514 1.1 christos
515 1.1 christos if (data->highlight || was_hilighted)
516 1.1 christos {
517 1.1 christos tui_display_register (data, data_item_win_ptr);
518 1.1 christos }
519 1.1 christos }
520 1.1 christos }
521 1.1 christos }
522 1.1 christos }
523 1.1 christos
524 1.1 christos /* Display a register in a window. If hilite is TRUE, then the value
525 1.1 christos will be displayed in reverse video. */
526 1.1 christos static void
527 1.1 christos tui_display_register (struct tui_data_element *data,
528 1.1 christos struct tui_gen_win_info *win_info)
529 1.1 christos {
530 1.1 christos if (win_info->handle != (WINDOW *) NULL)
531 1.1 christos {
532 1.1 christos int i;
533 1.1 christos
534 1.1 christos if (data->highlight)
535 1.1 christos /* We ignore the return value, casting it to void in order to avoid
536 1.1 christos a compiler warning. The warning itself was introduced by a patch
537 1.1 christos to ncurses 5.7 dated 2009-08-29, changing this macro to expand
538 1.1 christos to code that causes the compiler to generate an unused-value
539 1.1 christos warning. */
540 1.1 christos (void) wstandout (win_info->handle);
541 1.1 christos
542 1.1 christos wmove (win_info->handle, 0, 0);
543 1.1 christos for (i = 1; i < win_info->width; i++)
544 1.1 christos waddch (win_info->handle, ' ');
545 1.1 christos wmove (win_info->handle, 0, 0);
546 1.1 christos if (data->content)
547 1.1 christos waddstr (win_info->handle, data->content);
548 1.1 christos
549 1.1 christos if (data->highlight)
550 1.1 christos /* We ignore the return value, casting it to void in order to avoid
551 1.1 christos a compiler warning. The warning itself was introduced by a patch
552 1.1 christos to ncurses 5.7 dated 2009-08-29, changing this macro to expand
553 1.1 christos to code that causes the compiler to generate an unused-value
554 1.1 christos warning. */
555 1.1 christos (void) wstandend (win_info->handle);
556 1.1 christos tui_refresh_win (win_info);
557 1.1 christos }
558 1.1 christos }
559 1.1 christos
560 1.5 christos /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
561 1.5 christos around behaviour. Returns the next register group, or NULL if the
562 1.5 christos register window is not currently being displayed. */
563 1.5 christos
564 1.5 christos static struct reggroup *
565 1.5 christos tui_reg_next (struct gdbarch *gdbarch)
566 1.1 christos {
567 1.5 christos struct reggroup *group = NULL;
568 1.1 christos
569 1.5 christos if (TUI_DATA_WIN != NULL)
570 1.1 christos {
571 1.5 christos group = TUI_DATA_WIN->detail.data_display_info.current_group;
572 1.1 christos group = reggroup_next (gdbarch, group);
573 1.5 christos if (group == NULL)
574 1.5 christos group = reggroup_next (gdbarch, NULL);
575 1.1 christos }
576 1.5 christos return group;
577 1.1 christos }
578 1.1 christos
579 1.5 christos /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
580 1.5 christos around behaviour. Returns the previous register group, or NULL if the
581 1.5 christos register window is not currently being displayed. */
582 1.5 christos
583 1.5 christos static struct reggroup *
584 1.5 christos tui_reg_prev (struct gdbarch *gdbarch)
585 1.1 christos {
586 1.5 christos struct reggroup *group = NULL;
587 1.5 christos
588 1.5 christos if (TUI_DATA_WIN != NULL)
589 1.5 christos {
590 1.5 christos group = TUI_DATA_WIN->detail.data_display_info.current_group;
591 1.5 christos group = reggroup_prev (gdbarch, group);
592 1.5 christos if (group == NULL)
593 1.5 christos group = reggroup_prev (gdbarch, NULL);
594 1.5 christos }
595 1.5 christos return group;
596 1.1 christos }
597 1.1 christos
598 1.5 christos /* Implement the 'tui reg' command. Changes the register group displayed
599 1.5 christos in the tui register window. Displays the tui register window if it is
600 1.5 christos not already on display. */
601 1.5 christos
602 1.1 christos static void
603 1.5 christos tui_reg_command (char *args, int from_tty)
604 1.1 christos {
605 1.5 christos struct gdbarch *gdbarch = get_current_arch ();
606 1.5 christos
607 1.5 christos if (args != NULL)
608 1.5 christos {
609 1.5 christos struct reggroup *group, *match = NULL;
610 1.5 christos size_t len = strlen (args);
611 1.5 christos
612 1.5 christos /* Make sure the curses mode is enabled. */
613 1.5 christos tui_enable ();
614 1.5 christos
615 1.5 christos /* Make sure the register window is visible. If not, select an
616 1.5 christos appropriate layout. We need to do this before trying to run the
617 1.5 christos 'next' or 'prev' commands. */
618 1.5 christos if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible)
619 1.5 christos tui_set_layout_by_name (DATA_NAME);
620 1.5 christos
621 1.5 christos if (strncmp (args, "next", len) == 0)
622 1.5 christos match = tui_reg_next (gdbarch);
623 1.5 christos else if (strncmp (args, "prev", len) == 0)
624 1.5 christos match = tui_reg_prev (gdbarch);
625 1.5 christos
626 1.5 christos /* This loop matches on the initial part of a register group
627 1.5 christos name. If this initial part in ARGS matches only one register
628 1.5 christos group then the switch is made. */
629 1.5 christos for (group = reggroup_next (gdbarch, NULL);
630 1.5 christos group != NULL;
631 1.5 christos group = reggroup_next (gdbarch, group))
632 1.5 christos {
633 1.5 christos if (strncmp (reggroup_name (group), args, len) == 0)
634 1.5 christos {
635 1.5 christos if (match != NULL)
636 1.5 christos error (_("ambiguous register group name '%s'"), args);
637 1.5 christos match = group;
638 1.5 christos }
639 1.5 christos }
640 1.5 christos
641 1.5 christos if (match == NULL)
642 1.5 christos error (_("unknown register group '%s'"), args);
643 1.5 christos
644 1.5 christos tui_show_registers (match);
645 1.5 christos }
646 1.5 christos else
647 1.5 christos {
648 1.5 christos struct reggroup *group;
649 1.5 christos int first;
650 1.5 christos
651 1.5 christos printf_unfiltered (_("\"tui reg\" must be followed by the name of "
652 1.5 christos "either a register group,\nor one of 'next' "
653 1.5 christos "or 'prev'. Known register groups are:\n"));
654 1.5 christos
655 1.5 christos for (first = 1, group = reggroup_next (gdbarch, NULL);
656 1.5 christos group != NULL;
657 1.5 christos first = 0, group = reggroup_next (gdbarch, group))
658 1.5 christos {
659 1.5 christos if (!first)
660 1.5 christos printf_unfiltered (", ");
661 1.5 christos printf_unfiltered ("%s", reggroup_name (group));
662 1.5 christos }
663 1.5 christos
664 1.5 christos printf_unfiltered ("\n");
665 1.5 christos }
666 1.1 christos }
667 1.1 christos
668 1.5 christos /* Complete names of register groups, and add the special "prev" and "next"
669 1.5 christos names. */
670 1.5 christos
671 1.5 christos static VEC (char_ptr) *
672 1.5 christos tui_reggroup_completer (struct cmd_list_element *ignore,
673 1.5 christos const char *text, const char *word)
674 1.1 christos {
675 1.5 christos VEC (char_ptr) *result = NULL;
676 1.5 christos static const char *extra[] = { "next", "prev", NULL };
677 1.5 christos size_t len = strlen (word);
678 1.5 christos const char **tmp;
679 1.5 christos
680 1.5 christos result = reggroup_completer (ignore, text, word);
681 1.1 christos
682 1.5 christos for (tmp = extra; *tmp != NULL; ++tmp)
683 1.5 christos {
684 1.5 christos if (strncmp (word, *tmp, len) == 0)
685 1.5 christos VEC_safe_push (char_ptr, result, xstrdup (*tmp));
686 1.5 christos }
687 1.1 christos
688 1.5 christos return result;
689 1.1 christos }
690 1.1 christos
691 1.1 christos /* Provide a prototype to silence -Wmissing-prototypes. */
692 1.1 christos extern initialize_file_ftype _initialize_tui_regs;
693 1.1 christos
694 1.1 christos void
695 1.1 christos _initialize_tui_regs (void)
696 1.1 christos {
697 1.5 christos struct cmd_list_element **tuicmd, *cmd;
698 1.1 christos
699 1.1 christos tuicmd = tui_get_cmd_list ();
700 1.1 christos
701 1.5 christos cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
702 1.5 christos TUI command to control the register window."), tuicmd);
703 1.5 christos set_cmd_completer (cmd, tui_reggroup_completer);
704 1.1 christos }
705 1.1 christos
706 1.1 christos
707 1.1 christos /*****************************************
708 1.1 christos ** STATIC LOCAL FUNCTIONS **
709 1.1 christos ******************************************/
710 1.1 christos
711 1.1 christos static void
712 1.1 christos tui_restore_gdbout (void *ui)
713 1.1 christos {
714 1.1 christos ui_file_delete (gdb_stdout);
715 1.1 christos gdb_stdout = (struct ui_file*) ui;
716 1.1 christos pagination_enabled = 1;
717 1.1 christos }
718 1.1 christos
719 1.1 christos /* Get the register from the frame and return a printable
720 1.1 christos representation of it. */
721 1.1 christos
722 1.1 christos static char *
723 1.1 christos tui_register_format (struct frame_info *frame, int regnum)
724 1.1 christos {
725 1.1 christos struct gdbarch *gdbarch = get_frame_arch (frame);
726 1.1 christos struct ui_file *stream;
727 1.1 christos struct ui_file *old_stdout;
728 1.1 christos struct cleanup *cleanups;
729 1.1 christos char *p, *s;
730 1.1 christos char *ret;
731 1.1 christos
732 1.1 christos pagination_enabled = 0;
733 1.1 christos old_stdout = gdb_stdout;
734 1.1 christos stream = tui_sfileopen (256);
735 1.1 christos gdb_stdout = stream;
736 1.1 christos cleanups = make_cleanup (tui_restore_gdbout, (void*) old_stdout);
737 1.1 christos gdbarch_print_registers_info (gdbarch, stream, frame, regnum, 1);
738 1.1 christos
739 1.1 christos /* Save formatted output in the buffer. */
740 1.1 christos p = tui_file_get_strbuf (stream);
741 1.1 christos
742 1.1 christos /* Remove the possible \n. */
743 1.1 christos s = strrchr (p, '\n');
744 1.1 christos if (s && s[1] == 0)
745 1.1 christos *s = 0;
746 1.1 christos
747 1.3 christos /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
748 1.3 christos ret = tui_expand_tabs (p, 0);
749 1.3 christos
750 1.1 christos do_cleanups (cleanups);
751 1.1 christos
752 1.1 christos return ret;
753 1.1 christos }
754 1.1 christos
755 1.1 christos /* Get the register value from the given frame and format it for the
756 1.1 christos display. When changep is set, check if the new register value has
757 1.1 christos changed with respect to the previous call. */
758 1.1 christos static enum tui_status
759 1.1 christos tui_get_register (struct frame_info *frame,
760 1.1 christos struct tui_data_element *data,
761 1.1 christos int regnum, int *changedp)
762 1.1 christos {
763 1.1 christos enum tui_status ret = TUI_FAILURE;
764 1.1 christos
765 1.1 christos if (changedp)
766 1.1 christos *changedp = FALSE;
767 1.1 christos if (target_has_registers)
768 1.1 christos {
769 1.1 christos char *prev_content = data->content;
770 1.1 christos
771 1.1 christos data->content = tui_register_format (frame, regnum);
772 1.1 christos
773 1.1 christos if (changedp != NULL
774 1.1 christos && strcmp (prev_content, data->content) != 0)
775 1.1 christos *changedp = 1;
776 1.1 christos
777 1.1 christos xfree (prev_content);
778 1.1 christos
779 1.1 christos ret = TUI_SUCCESS;
780 1.1 christos }
781 1.1 christos return ret;
782 1.1 christos }
783