2003-05-14 Elena Zannoni <ezannoni@redhat.com>
[external/binutils.git] / gdb / mi / mi-cmd-stack.c
1 /* MI Command Set - stack commands.
2    Copyright 2000, 2002, 2003 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions (a Red Hat company).
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "target.h"
24 #include "frame.h"
25 #include "value.h"
26 #include "mi-cmds.h"
27 #include "ui-out.h"
28 #include "symtab.h"
29 #include "block.h"
30
31 /* FIXME: these should go in some .h file but stack.c doesn't have a
32    corresponding .h file. These wrappers will be obsolete anyway, once
33    we pull the plug on the sanitization. */
34 extern void select_frame_command_wrapper (char *, int);
35
36 static void list_args_or_locals (int locals, int values, struct frame_info *fi);
37
38 /* Print a list of the stack frames. Args can be none, in which case
39    we want to print the whole backtrace, or a pair of numbers
40    specifying the frame numbers at which to start and stop the
41    display. If the two numbers are equal, a single frame will be
42    displayed. */
43 enum mi_cmd_result
44 mi_cmd_stack_list_frames (char *command, char **argv, int argc)
45 {
46   int frame_low;
47   int frame_high;
48   int i;
49   struct cleanup *cleanup_stack;
50   struct frame_info *fi;
51
52   if (!target_has_stack)
53     error ("mi_cmd_stack_list_frames: No stack.");
54
55   if (argc > 2 || argc == 1)
56     error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
57
58   if (argc == 2)
59     {
60       frame_low = atoi (argv[0]);
61       frame_high = atoi (argv[1]);
62     }
63   else
64     {
65       /* Called with no arguments, it means we want the whole
66          backtrace. */
67       frame_low = -1;
68       frame_high = -1;
69     }
70
71   /* Let's position fi on the frame at which to start the
72      display. Could be the innermost frame if the whole stack needs
73      displaying, or if frame_low is 0. */
74   for (i = 0, fi = get_current_frame ();
75        fi && i < frame_low;
76        i++, fi = get_prev_frame (fi));
77
78   if (fi == NULL)
79     error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
80
81   cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
82
83   /* Now let;s print the frames up to frame_high, or until there are
84      frames in the stack. */
85   for (;
86        fi && (i <= frame_high || frame_high == -1);
87        i++, fi = get_prev_frame (fi))
88     {
89       QUIT;
90       /* level == i: always print the level 'i'
91          source == LOC_AND_ADDRESS: print the location and the address 
92          always, even for level 0.
93          args == 0: don't print the arguments. */
94       print_frame_info (fi /* frame info */ ,
95                         i /* level */ ,
96                         LOC_AND_ADDRESS /* source */ ,
97                         0 /* args */ );
98     }
99
100   do_cleanups (cleanup_stack);
101   if (i < frame_high)
102     error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
103
104   return MI_CMD_DONE;
105 }
106
107 enum mi_cmd_result
108 mi_cmd_stack_info_depth (char *command, char **argv, int argc)
109 {
110   int frame_high;
111   int i;
112   struct frame_info *fi;
113
114   if (!target_has_stack)
115     error ("mi_cmd_stack_info_depth: No stack.");
116
117   if (argc > 1)
118     error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
119
120   if (argc == 1)
121     frame_high = atoi (argv[0]);
122   else
123     /* Called with no arguments, it means we want the real depth of
124        the stack. */
125     frame_high = -1;
126
127   for (i = 0, fi = get_current_frame ();
128        fi && (i < frame_high || frame_high == -1);
129        i++, fi = get_prev_frame (fi))
130     QUIT;
131
132   ui_out_field_int (uiout, "depth", i);
133
134   return MI_CMD_DONE;
135 }
136
137 /* Print a list of the locals for the current frame. With argument of
138    0, print only the names, with argument of 1 print also the
139    values. */
140 enum mi_cmd_result
141 mi_cmd_stack_list_locals (char *command, char **argv, int argc)
142 {
143   if (argc != 1)
144     error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
145
146   list_args_or_locals (1, atoi (argv[0]), deprecated_selected_frame);
147   return MI_CMD_DONE;
148 }
149
150 /* Print a list of the arguments for the current frame. With argument
151    of 0, print only the names, with argument of 1 print also the
152    values. */
153 enum mi_cmd_result
154 mi_cmd_stack_list_args (char *command, char **argv, int argc)
155 {
156   int frame_low;
157   int frame_high;
158   int i;
159   struct frame_info *fi;
160   struct cleanup *cleanup_stack_args;
161
162   if (argc < 1 || argc > 3 || argc == 2)
163     error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
164
165   if (argc == 3)
166     {
167       frame_low = atoi (argv[1]);
168       frame_high = atoi (argv[2]);
169     }
170   else
171     {
172       /* Called with no arguments, it means we want args for the whole
173          backtrace. */
174       frame_low = -1;
175       frame_high = -1;
176     }
177
178   /* Let's position fi on the frame at which to start the
179      display. Could be the innermost frame if the whole stack needs
180      displaying, or if frame_low is 0. */
181   for (i = 0, fi = get_current_frame ();
182        fi && i < frame_low;
183        i++, fi = get_prev_frame (fi));
184
185   if (fi == NULL)
186     error ("mi_cmd_stack_list_args: Not enough frames in stack.");
187
188   cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
189
190   /* Now let's print the frames up to frame_high, or until there are
191      frames in the stack. */
192   for (;
193        fi && (i <= frame_high || frame_high == -1);
194        i++, fi = get_prev_frame (fi))
195     {
196       struct cleanup *cleanup_frame;
197       QUIT;
198       cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
199       ui_out_field_int (uiout, "level", i);
200       list_args_or_locals (0, atoi (argv[0]), fi);
201       do_cleanups (cleanup_frame);
202     }
203
204   do_cleanups (cleanup_stack_args);
205   if (i < frame_high)
206     error ("mi_cmd_stack_list_args: Not enough frames in stack.");
207
208   return MI_CMD_DONE;
209 }
210
211 /* Print a list of the locals or the arguments for the currently
212    selected frame.  If the argument passed is 0, printonly the names
213    of the variables, if an argument of 1 is passed, print the values
214    as well. */
215 static void
216 list_args_or_locals (int locals, int values, struct frame_info *fi)
217 {
218   struct block *block;
219   struct symbol *sym;
220   int i, nsyms;
221   struct cleanup *cleanup_list;
222   static struct ui_stream *stb = NULL;
223
224   stb = ui_out_stream_new (uiout);
225
226   block = get_frame_block (fi, 0);
227
228   cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
229
230   while (block != 0)
231     {
232       ALL_BLOCK_SYMBOLS (block, i, sym)
233         {
234           int print_me = 0;
235
236           switch (SYMBOL_CLASS (sym))
237             {
238             default:
239             case LOC_UNDEF:     /* catches errors        */
240             case LOC_CONST:     /* constant              */
241             case LOC_TYPEDEF:   /* local typedef         */
242             case LOC_LABEL:     /* local label           */
243             case LOC_BLOCK:     /* local function        */
244             case LOC_CONST_BYTES:       /* loc. byte seq.        */
245             case LOC_UNRESOLVED:        /* unresolved static     */
246             case LOC_OPTIMIZED_OUT:     /* optimized out         */
247               print_me = 0;
248               break;
249
250             case LOC_ARG:       /* argument              */
251             case LOC_REF_ARG:   /* reference arg         */
252             case LOC_REGPARM:   /* register arg          */
253             case LOC_REGPARM_ADDR:      /* indirect register arg */
254             case LOC_LOCAL_ARG: /* stack arg             */
255             case LOC_BASEREG_ARG:       /* basereg arg           */
256             case LOC_COMPUTED_ARG:      /* arg with computed location */
257               if (!locals)
258                 print_me = 1;
259               break;
260
261             case LOC_LOCAL:     /* stack local           */
262             case LOC_BASEREG:   /* basereg local         */
263             case LOC_STATIC:    /* static                */
264             case LOC_REGISTER:  /* register              */
265             case LOC_COMPUTED:  /* computed location     */
266               if (locals)
267                 print_me = 1;
268               break;
269             }
270           if (print_me)
271             {
272               struct cleanup *cleanup_tuple = NULL;
273               if (values)
274                 cleanup_tuple = 
275                   make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
276               ui_out_field_string (uiout, "name", DEPRECATED_SYMBOL_NAME (sym));
277
278               if (values)
279                 {
280                   struct symbol *sym2;
281                   if (!locals)
282                     sym2 = lookup_symbol (DEPRECATED_SYMBOL_NAME (sym),
283                                           block, VAR_DOMAIN,
284                                           (int *) NULL,
285                                           (struct symtab **) NULL);
286                   else
287                     sym2 = sym;
288                   print_variable_value (sym2, fi, stb->stream);
289                   ui_out_field_stream (uiout, "value", stb);
290                   do_cleanups (cleanup_tuple);
291                 }
292             }
293         }
294       if (BLOCK_FUNCTION (block))
295         break;
296       else
297         block = BLOCK_SUPERBLOCK (block);
298     }
299   do_cleanups (cleanup_list);
300   ui_out_stream_delete (stb);
301 }
302
303 enum mi_cmd_result
304 mi_cmd_stack_select_frame (char *command, char **argv, int argc)
305 {
306   if (!target_has_stack)
307     error ("mi_cmd_stack_select_frame: No stack.");
308
309   if (argc > 1)
310     error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
311
312   /* with no args, don't change frame */
313   if (argc == 0)
314     select_frame_command_wrapper (0, 1 /* not used */ );
315   else
316     select_frame_command_wrapper (argv[0], 1 /* not used */ );
317   return MI_CMD_DONE;
318 }