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