2001-10-12 Daniel Jacobowitz <drow@mvista.com>
[external/binutils.git] / gdb / mi / mi-cmd-stack.c
1 /* MI Command Set - stack commands.
2    Copyright 2000 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 #ifdef UI_OUT
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 #endif
36
37 static void list_args_or_locals (int locals, int values, struct frame_info *fi);
38
39 /* Print a list of the stack frames. Args can be none, in which case
40    we want to print the whole backtrace, or a pair of numbers
41    specifying the frame numbers at which to start and stop the
42    display. If the two numbers are equal, a single frame will be
43    displayed. */
44 enum mi_cmd_result
45 mi_cmd_stack_list_frames (char *command, char **argv, int argc)
46 {
47   int frame_low;
48   int frame_high;
49   int i;
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   ui_out_list_begin (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   ui_out_list_end (uiout);
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]), 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
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   ui_out_list_begin (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       QUIT;
196       ui_out_tuple_begin (uiout, "frame");
197       ui_out_field_int (uiout, "level", i);
198       list_args_or_locals (0, atoi (argv[0]), fi);
199       ui_out_tuple_end (uiout);
200     }
201
202   ui_out_list_end (uiout);
203   if (i < frame_high)
204     error ("mi_cmd_stack_list_args: Not enough frames in stack.");
205
206   return MI_CMD_DONE;
207 }
208
209 /* Print a list of the locals or the arguments for the currently
210    selected frame.  If the argument passed is 0, printonly the names
211    of the variables, if an argument of 1 is passed, print the values
212    as well. */
213 static void
214 list_args_or_locals (int locals, int values, struct frame_info *fi)
215 {
216   struct block *block;
217   struct symbol *sym;
218   int i, nsyms;
219   int print_me = 0;
220   static struct ui_stream *stb = NULL;
221
222   stb = ui_out_stream_new (uiout);
223
224   block = get_frame_block (fi);
225
226   ui_out_list_begin (uiout, locals ? "locals" : "args");
227
228   while (block != 0)
229     {
230       ALL_BLOCK_SYMBOLS (block, i, sym)
231         {
232           switch (SYMBOL_CLASS (sym))
233             {
234             default:
235             case LOC_UNDEF:     /* catches errors        */
236             case LOC_CONST:     /* constant              */
237             case LOC_TYPEDEF:   /* local typedef         */
238             case LOC_LABEL:     /* local label           */
239             case LOC_BLOCK:     /* local function        */
240             case LOC_CONST_BYTES:       /* loc. byte seq.        */
241             case LOC_UNRESOLVED:        /* unresolved static     */
242             case LOC_OPTIMIZED_OUT:     /* optimized out         */
243               print_me = 0;
244               break;
245
246             case LOC_ARG:       /* argument              */
247             case LOC_REF_ARG:   /* reference arg         */
248             case LOC_REGPARM:   /* register arg          */
249             case LOC_REGPARM_ADDR:      /* indirect register arg */
250             case LOC_LOCAL_ARG: /* stack arg             */
251             case LOC_BASEREG_ARG:       /* basereg arg           */
252               if (!locals)
253                 print_me = 1;
254               break;
255
256             case LOC_LOCAL:     /* stack local           */
257             case LOC_BASEREG:   /* basereg local         */
258             case LOC_STATIC:    /* static                */
259             case LOC_REGISTER:  /* register              */
260               if (locals)
261                 print_me = 1;
262               break;
263             }
264           if (print_me)
265             {
266               if (values)
267                 ui_out_tuple_begin (uiout, NULL);
268               ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
269
270               if (values)
271                 {
272                   struct symbol *sym2;
273                   if (!locals)
274                     sym2 = lookup_symbol (SYMBOL_NAME (sym),
275                                           block, VAR_NAMESPACE,
276                                           (int *) NULL,
277                                           (struct symtab **) NULL);
278                   else
279                     sym2 = sym;
280                   print_variable_value (sym2, fi, stb->stream);
281                   ui_out_field_stream (uiout, "value", stb);
282                   ui_out_tuple_end (uiout);
283                 }
284             }
285         }
286       if (BLOCK_FUNCTION (block))
287         break;
288       else
289         block = BLOCK_SUPERBLOCK (block);
290     }
291   ui_out_list_end (uiout);
292   ui_out_stream_delete (stb);
293 }
294
295 enum mi_cmd_result
296 mi_cmd_stack_select_frame (char *command, char **argv, int argc)
297 {
298 #ifdef UI_OUT
299   if (!target_has_stack)
300     error ("mi_cmd_stack_select_frame: No stack.");
301
302   if (argc > 1)
303     error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
304
305   /* with no args, don't change frame */
306   if (argc == 0)
307     select_frame_command_wrapper (0, 1 /* not used */ );
308   else
309     select_frame_command_wrapper (argv[0], 1 /* not used */ );
310 #endif
311   return MI_CMD_DONE;
312 }