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