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