198944Sobrien/* MI Command Set - stack commands.
2130803Smarcel   Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
398944Sobrien   Contributed by Cygnus Solutions (a Red Hat company).
498944Sobrien
598944Sobrien   This file is part of GDB.
698944Sobrien
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1198944Sobrien
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1698944Sobrien
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2098944Sobrien   Boston, MA 02111-1307, USA.  */
2198944Sobrien
2298944Sobrien#include "defs.h"
2398944Sobrien#include "target.h"
2498944Sobrien#include "frame.h"
2598944Sobrien#include "value.h"
2698944Sobrien#include "mi-cmds.h"
2798944Sobrien#include "ui-out.h"
2898944Sobrien#include "symtab.h"
29130803Smarcel#include "block.h"
30130803Smarcel#include "stack.h"
31130803Smarcel#include "dictionary.h"
32130803Smarcel#include "gdb_string.h"
3398944Sobrien
3498944Sobrienstatic void list_args_or_locals (int locals, int values, struct frame_info *fi);
3598944Sobrien
3698944Sobrien/* Print a list of the stack frames. Args can be none, in which case
3798944Sobrien   we want to print the whole backtrace, or a pair of numbers
3898944Sobrien   specifying the frame numbers at which to start and stop the
3998944Sobrien   display. If the two numbers are equal, a single frame will be
4098944Sobrien   displayed. */
4198944Sobrienenum mi_cmd_result
4298944Sobrienmi_cmd_stack_list_frames (char *command, char **argv, int argc)
4398944Sobrien{
4498944Sobrien  int frame_low;
4598944Sobrien  int frame_high;
4698944Sobrien  int i;
47130803Smarcel  struct cleanup *cleanup_stack;
4898944Sobrien  struct frame_info *fi;
4998944Sobrien
5098944Sobrien  if (!target_has_stack)
5198944Sobrien    error ("mi_cmd_stack_list_frames: No stack.");
5298944Sobrien
5398944Sobrien  if (argc > 2 || argc == 1)
5498944Sobrien    error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
5598944Sobrien
5698944Sobrien  if (argc == 2)
5798944Sobrien    {
5898944Sobrien      frame_low = atoi (argv[0]);
5998944Sobrien      frame_high = atoi (argv[1]);
6098944Sobrien    }
6198944Sobrien  else
6298944Sobrien    {
6398944Sobrien      /* Called with no arguments, it means we want the whole
6498944Sobrien         backtrace. */
6598944Sobrien      frame_low = -1;
6698944Sobrien      frame_high = -1;
6798944Sobrien    }
6898944Sobrien
6998944Sobrien  /* Let's position fi on the frame at which to start the
7098944Sobrien     display. Could be the innermost frame if the whole stack needs
7198944Sobrien     displaying, or if frame_low is 0. */
7298944Sobrien  for (i = 0, fi = get_current_frame ();
7398944Sobrien       fi && i < frame_low;
7498944Sobrien       i++, fi = get_prev_frame (fi));
7598944Sobrien
7698944Sobrien  if (fi == NULL)
7798944Sobrien    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
7898944Sobrien
79130803Smarcel  cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
8098944Sobrien
8198944Sobrien  /* Now let;s print the frames up to frame_high, or until there are
8298944Sobrien     frames in the stack. */
8398944Sobrien  for (;
8498944Sobrien       fi && (i <= frame_high || frame_high == -1);
8598944Sobrien       i++, fi = get_prev_frame (fi))
8698944Sobrien    {
8798944Sobrien      QUIT;
8898944Sobrien      /* level == i: always print the level 'i'
8998944Sobrien         source == LOC_AND_ADDRESS: print the location and the address
9098944Sobrien         always, even for level 0.
9198944Sobrien         args == 0: don't print the arguments. */
9298944Sobrien      print_frame_info (fi /* frame info */ ,
9398944Sobrien			i /* level */ ,
9498944Sobrien			LOC_AND_ADDRESS /* source */ ,
9598944Sobrien			0 /* args */ );
9698944Sobrien    }
9798944Sobrien
98130803Smarcel  do_cleanups (cleanup_stack);
9998944Sobrien  if (i < frame_high)
10098944Sobrien    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
10198944Sobrien
10298944Sobrien  return MI_CMD_DONE;
10398944Sobrien}
10498944Sobrien
10598944Sobrienenum mi_cmd_result
10698944Sobrienmi_cmd_stack_info_depth (char *command, char **argv, int argc)
10798944Sobrien{
10898944Sobrien  int frame_high;
10998944Sobrien  int i;
11098944Sobrien  struct frame_info *fi;
11198944Sobrien
11298944Sobrien  if (!target_has_stack)
11398944Sobrien    error ("mi_cmd_stack_info_depth: No stack.");
11498944Sobrien
11598944Sobrien  if (argc > 1)
11698944Sobrien    error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
11798944Sobrien
11898944Sobrien  if (argc == 1)
11998944Sobrien    frame_high = atoi (argv[0]);
12098944Sobrien  else
12198944Sobrien    /* Called with no arguments, it means we want the real depth of
12298944Sobrien       the stack. */
12398944Sobrien    frame_high = -1;
12498944Sobrien
12598944Sobrien  for (i = 0, fi = get_current_frame ();
12698944Sobrien       fi && (i < frame_high || frame_high == -1);
12798944Sobrien       i++, fi = get_prev_frame (fi))
12898944Sobrien    QUIT;
12998944Sobrien
13098944Sobrien  ui_out_field_int (uiout, "depth", i);
13198944Sobrien
13298944Sobrien  return MI_CMD_DONE;
13398944Sobrien}
13498944Sobrien
13598944Sobrien/* Print a list of the locals for the current frame. With argument of
13698944Sobrien   0, print only the names, with argument of 1 print also the
13798944Sobrien   values. */
13898944Sobrienenum mi_cmd_result
13998944Sobrienmi_cmd_stack_list_locals (char *command, char **argv, int argc)
14098944Sobrien{
141130803Smarcel  struct frame_info *frame;
142130803Smarcel  enum print_values print_values;
143130803Smarcel
14498944Sobrien  if (argc != 1)
14598944Sobrien    error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
14698944Sobrien
147130803Smarcel   frame = get_selected_frame ();
148130803Smarcel
149130803Smarcel   if (strcmp (argv[0], "0") == 0
150130803Smarcel       || strcmp (argv[0], "--no-values") == 0)
151130803Smarcel     print_values = PRINT_NO_VALUES;
152130803Smarcel   else if (strcmp (argv[0], "1") == 0
153130803Smarcel	    || strcmp (argv[0], "--all-values") == 0)
154130803Smarcel     print_values = PRINT_ALL_VALUES;
155130803Smarcel   else if (strcmp (argv[0], "2") == 0
156130803Smarcel	    || strcmp (argv[0], "--simple-values") == 0)
157130803Smarcel     print_values = PRINT_SIMPLE_VALUES;
158130803Smarcel   else
159130803Smarcel     error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\"");
160130803Smarcel  list_args_or_locals (1, print_values, frame);
16198944Sobrien  return MI_CMD_DONE;
16298944Sobrien}
16398944Sobrien
16498944Sobrien/* Print a list of the arguments for the current frame. With argument
16598944Sobrien   of 0, print only the names, with argument of 1 print also the
16698944Sobrien   values. */
16798944Sobrienenum mi_cmd_result
16898944Sobrienmi_cmd_stack_list_args (char *command, char **argv, int argc)
16998944Sobrien{
17098944Sobrien  int frame_low;
17198944Sobrien  int frame_high;
17298944Sobrien  int i;
17398944Sobrien  struct frame_info *fi;
174130803Smarcel  struct cleanup *cleanup_stack_args;
17598944Sobrien
17698944Sobrien  if (argc < 1 || argc > 3 || argc == 2)
17798944Sobrien    error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
17898944Sobrien
17998944Sobrien  if (argc == 3)
18098944Sobrien    {
18198944Sobrien      frame_low = atoi (argv[1]);
18298944Sobrien      frame_high = atoi (argv[2]);
18398944Sobrien    }
18498944Sobrien  else
18598944Sobrien    {
18698944Sobrien      /* Called with no arguments, it means we want args for the whole
18798944Sobrien         backtrace. */
18898944Sobrien      frame_low = -1;
18998944Sobrien      frame_high = -1;
19098944Sobrien    }
19198944Sobrien
19298944Sobrien  /* Let's position fi on the frame at which to start the
19398944Sobrien     display. Could be the innermost frame if the whole stack needs
19498944Sobrien     displaying, or if frame_low is 0. */
19598944Sobrien  for (i = 0, fi = get_current_frame ();
19698944Sobrien       fi && i < frame_low;
19798944Sobrien       i++, fi = get_prev_frame (fi));
19898944Sobrien
19998944Sobrien  if (fi == NULL)
20098944Sobrien    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
20198944Sobrien
202130803Smarcel  cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
20398944Sobrien
20498944Sobrien  /* Now let's print the frames up to frame_high, or until there are
20598944Sobrien     frames in the stack. */
20698944Sobrien  for (;
20798944Sobrien       fi && (i <= frame_high || frame_high == -1);
20898944Sobrien       i++, fi = get_prev_frame (fi))
20998944Sobrien    {
210130803Smarcel      struct cleanup *cleanup_frame;
21198944Sobrien      QUIT;
212130803Smarcel      cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
21398944Sobrien      ui_out_field_int (uiout, "level", i);
21498944Sobrien      list_args_or_locals (0, atoi (argv[0]), fi);
215130803Smarcel      do_cleanups (cleanup_frame);
21698944Sobrien    }
21798944Sobrien
218130803Smarcel  do_cleanups (cleanup_stack_args);
21998944Sobrien  if (i < frame_high)
22098944Sobrien    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
22198944Sobrien
22298944Sobrien  return MI_CMD_DONE;
22398944Sobrien}
22498944Sobrien
22598944Sobrien/* Print a list of the locals or the arguments for the currently
22698944Sobrien   selected frame.  If the argument passed is 0, printonly the names
22798944Sobrien   of the variables, if an argument of 1 is passed, print the values
22898944Sobrien   as well. */
22998944Sobrienstatic void
23098944Sobrienlist_args_or_locals (int locals, int values, struct frame_info *fi)
23198944Sobrien{
23298944Sobrien  struct block *block;
23398944Sobrien  struct symbol *sym;
234130803Smarcel  struct dict_iterator iter;
235130803Smarcel  int nsyms;
236130803Smarcel  struct cleanup *cleanup_list;
23798944Sobrien  static struct ui_stream *stb = NULL;
238130803Smarcel  struct type *type;
23998944Sobrien
24098944Sobrien  stb = ui_out_stream_new (uiout);
24198944Sobrien
242130803Smarcel  block = get_frame_block (fi, 0);
24398944Sobrien
244130803Smarcel  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
24598944Sobrien
24698944Sobrien  while (block != 0)
24798944Sobrien    {
248130803Smarcel      ALL_BLOCK_SYMBOLS (block, iter, sym)
24998944Sobrien	{
25098944Sobrien          int print_me = 0;
25198944Sobrien
25298944Sobrien	  switch (SYMBOL_CLASS (sym))
25398944Sobrien	    {
25498944Sobrien	    default:
25598944Sobrien	    case LOC_UNDEF:	/* catches errors        */
25698944Sobrien	    case LOC_CONST:	/* constant              */
25798944Sobrien	    case LOC_TYPEDEF:	/* local typedef         */
25898944Sobrien	    case LOC_LABEL:	/* local label           */
25998944Sobrien	    case LOC_BLOCK:	/* local function        */
26098944Sobrien	    case LOC_CONST_BYTES:	/* loc. byte seq.        */
26198944Sobrien	    case LOC_UNRESOLVED:	/* unresolved static     */
26298944Sobrien	    case LOC_OPTIMIZED_OUT:	/* optimized out         */
26398944Sobrien	      print_me = 0;
26498944Sobrien	      break;
26598944Sobrien
26698944Sobrien	    case LOC_ARG:	/* argument              */
26798944Sobrien	    case LOC_REF_ARG:	/* reference arg         */
26898944Sobrien	    case LOC_REGPARM:	/* register arg          */
26998944Sobrien	    case LOC_REGPARM_ADDR:	/* indirect register arg */
27098944Sobrien	    case LOC_LOCAL_ARG:	/* stack arg             */
27198944Sobrien	    case LOC_BASEREG_ARG:	/* basereg arg           */
272130803Smarcel	    case LOC_COMPUTED_ARG:	/* arg with computed location */
27398944Sobrien	      if (!locals)
27498944Sobrien		print_me = 1;
27598944Sobrien	      break;
27698944Sobrien
27798944Sobrien	    case LOC_LOCAL:	/* stack local           */
27898944Sobrien	    case LOC_BASEREG:	/* basereg local         */
27998944Sobrien	    case LOC_STATIC:	/* static                */
28098944Sobrien	    case LOC_REGISTER:	/* register              */
281130803Smarcel	    case LOC_COMPUTED:	/* computed location     */
28298944Sobrien	      if (locals)
28398944Sobrien		print_me = 1;
28498944Sobrien	      break;
28598944Sobrien	    }
28698944Sobrien	  if (print_me)
28798944Sobrien	    {
288130803Smarcel	      struct cleanup *cleanup_tuple = NULL;
289130803Smarcel	      struct symbol *sym2;
290130803Smarcel	      if (values != PRINT_NO_VALUES)
291130803Smarcel		cleanup_tuple =
292130803Smarcel		  make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
293130803Smarcel	      ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));
29498944Sobrien
295130803Smarcel	      if (!locals)
296130803Smarcel		sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
297130803Smarcel				      block, VAR_DOMAIN,
298130803Smarcel				      (int *) NULL,
299130803Smarcel				      (struct symtab **) NULL);
300130803Smarcel	      else
301130803Smarcel		    sym2 = sym;
302130803Smarcel	      switch (values)
30398944Sobrien		{
304130803Smarcel		case PRINT_SIMPLE_VALUES:
305130803Smarcel		  type = check_typedef (sym2->type);
306130803Smarcel		  type_print (sym2->type, "", stb->stream, -1);
307130803Smarcel		  ui_out_field_stream (uiout, "type", stb);
308130803Smarcel		  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
309130803Smarcel		      && TYPE_CODE (type) != TYPE_CODE_STRUCT
310130803Smarcel		      && TYPE_CODE (type) != TYPE_CODE_UNION)
311130803Smarcel		    {
312130803Smarcel		      print_variable_value (sym2, fi, stb->stream);
313130803Smarcel		      ui_out_field_stream (uiout, "value", stb);
314130803Smarcel		    }
315130803Smarcel		  do_cleanups (cleanup_tuple);
316130803Smarcel		  break;
317130803Smarcel		case PRINT_ALL_VALUES:
31898944Sobrien		  print_variable_value (sym2, fi, stb->stream);
31998944Sobrien		  ui_out_field_stream (uiout, "value", stb);
320130803Smarcel		  do_cleanups (cleanup_tuple);
321130803Smarcel		  break;
32298944Sobrien		}
32398944Sobrien	    }
32498944Sobrien	}
32598944Sobrien      if (BLOCK_FUNCTION (block))
32698944Sobrien	break;
32798944Sobrien      else
32898944Sobrien	block = BLOCK_SUPERBLOCK (block);
32998944Sobrien    }
330130803Smarcel  do_cleanups (cleanup_list);
33198944Sobrien  ui_out_stream_delete (stb);
33298944Sobrien}
33398944Sobrien
33498944Sobrienenum mi_cmd_result
33598944Sobrienmi_cmd_stack_select_frame (char *command, char **argv, int argc)
33698944Sobrien{
33798944Sobrien  if (!target_has_stack)
33898944Sobrien    error ("mi_cmd_stack_select_frame: No stack.");
33998944Sobrien
34098944Sobrien  if (argc > 1)
34198944Sobrien    error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
34298944Sobrien
34398944Sobrien  /* with no args, don't change frame */
34498944Sobrien  if (argc == 0)
345130803Smarcel    select_frame_command (0, 1 /* not used */ );
34698944Sobrien  else
347130803Smarcel    select_frame_command (argv[0], 1 /* not used */ );
34898944Sobrien  return MI_CMD_DONE;
34998944Sobrien}
350