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