OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [mi/] [mi-cmd-stack.c] - Rev 1765

Compare with Previous | Blame | View Log

/* MI Command Set - stack commands.
   Copyright (C) 2000, Free Software Foundation, Inc.
   Contributed by Cygnus Solutions (a Red Hat company).
 
   This file is part of GDB.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
 
#include "defs.h"
#include "target.h"
#include "frame.h"
#include "value.h"
#include "mi-cmds.h"
#include "ui-out.h"
 
#ifdef UI_OUT
/* FIXME: these should go in some .h file but stack.c doesn't have a
   corresponding .h file. These wrappers will be obsolete anyway, once
   we pull the plug on the sanitization. */
extern void select_frame_command_wrapper (char *, int);
#endif
 
static void list_args_or_locals (int locals, int values, struct frame_info *fi);
 
/* Print a list of the stack frames. Args can be none, in which case
   we want to print the whole backtrace, or a pair of numbers
   specifying the frame numbers at which to start and stop the
   display. If the two numbers are equal, a single frame will be
   displayed. */
enum mi_cmd_result
mi_cmd_stack_list_frames (char *command, char **argv, int argc)
{
  int frame_low;
  int frame_high;
  int i;
  struct frame_info *fi;
 
  if (!target_has_stack)
    error ("mi_cmd_stack_list_frames: No stack.");
 
  if (argc > 2 || argc == 1)
    error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
 
  if (argc == 2)
    {
      frame_low = atoi (argv[0]);
      frame_high = atoi (argv[1]);
    }
  else
    {
      /* Called with no arguments, it means we want the whole
         backtrace. */
      frame_low = -1;
      frame_high = -1;
    }
 
  /* Let's position fi on the frame at which to start the
     display. Could be the innermost frame if the whole stack needs
     displaying, or if frame_low is 0. */
  for (i = 0, fi = get_current_frame ();
       fi && i < frame_low;
       i++, fi = get_prev_frame (fi));
 
  if (fi == NULL)
    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
 
  ui_out_list_begin (uiout, "stack");
 
  /* Now let;s print the frames up to frame_high, or until there are
     frames in the stack. */
  for (;
       fi && (i <= frame_high || frame_high == -1);
       i++, fi = get_prev_frame (fi))
    {
      QUIT;
      /* level == i: always print the level 'i'
         source == LOC_AND_ADDRESS: print the location and the address 
         always, even for level 0.
         args == 0: don't print the arguments. */
      print_frame_info (fi /* frame info */ ,
			i /* level */ ,
			LOC_AND_ADDRESS /* source */ ,
			0 /* args */ );
    }
 
  ui_out_list_end (uiout);
  if (i < frame_high)
    error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
 
  return MI_CMD_DONE;
}
 
enum mi_cmd_result
mi_cmd_stack_info_depth (char *command, char **argv, int argc)
{
  int frame_high;
  int i;
  struct frame_info *fi;
 
  if (!target_has_stack)
    error ("mi_cmd_stack_info_depth: No stack.");
 
  if (argc > 1)
    error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
 
  if (argc == 1)
    frame_high = atoi (argv[0]);
  else
    /* Called with no arguments, it means we want the real depth of
       the stack. */
    frame_high = -1;
 
  for (i = 0, fi = get_current_frame ();
       fi && (i < frame_high || frame_high == -1);
       i++, fi = get_prev_frame (fi))
    QUIT;
 
  ui_out_field_int (uiout, "depth", i);
 
  return MI_CMD_DONE;
}
 
/* Print a list of the locals for the current frame. With argument of
   0, print only the names, with argument of 1 print also the
   values. */
enum mi_cmd_result
mi_cmd_stack_list_locals (char *command, char **argv, int argc)
{
  if (argc != 1)
    error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
 
  list_args_or_locals (1, atoi (argv[0]), selected_frame);
  return MI_CMD_DONE;
}
 
/* Print a list of the arguments for the current frame. With argument
   of 0, print only the names, with argument of 1 print also the
   values. */
enum mi_cmd_result
mi_cmd_stack_list_args (char *command, char **argv, int argc)
{
  int frame_low;
  int frame_high;
  int i;
  struct frame_info *fi;
 
  if (argc < 1 || argc > 3 || argc == 2)
    error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
 
  if (argc == 3)
    {
      frame_low = atoi (argv[1]);
      frame_high = atoi (argv[2]);
    }
  else
    {
      /* Called with no arguments, it means we want args for the whole
         backtrace. */
      frame_low = -1;
      frame_high = -1;
    }
 
  /* Let's position fi on the frame at which to start the
     display. Could be the innermost frame if the whole stack needs
     displaying, or if frame_low is 0. */
  for (i = 0, fi = get_current_frame ();
       fi && i < frame_low;
       i++, fi = get_prev_frame (fi));
 
  if (fi == NULL)
    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
 
  ui_out_list_begin (uiout, "stack-args");
 
  /* Now let's print the frames up to frame_high, or until there are
     frames in the stack. */
  for (;
       fi && (i <= frame_high || frame_high == -1);
       i++, fi = get_prev_frame (fi))
    {
      QUIT;
      ui_out_list_begin (uiout, "frame");
      ui_out_field_int (uiout, "level", i);
      list_args_or_locals (0, atoi (argv[0]), fi);
      ui_out_list_end (uiout);
    }
 
  ui_out_list_end (uiout);
  if (i < frame_high)
    error ("mi_cmd_stack_list_args: Not enough frames in stack.");
 
  return MI_CMD_DONE;
}
 
/* Print a list of the locals or the arguments for the currently
   selected frame.  If the argument passed is 0, printonly the names
   of the variables, if an argument of 1 is passed, print the values
   as well. */
static void
list_args_or_locals (int locals, int values, struct frame_info *fi)
{
  struct block *block;
  struct symbol *sym;
  int i, nsyms;
  int print_me = 0;
  static struct ui_stream *stb = NULL;
 
  stb = ui_out_stream_new (uiout);
 
  block = get_frame_block (fi);
 
  ui_out_list_begin (uiout, locals ? "locals" : "args");
 
  while (block != 0)
    {
      nsyms = BLOCK_NSYMS (block);
      for (i = 0; i < nsyms; i++)
	{
	  sym = BLOCK_SYM (block, i);
	  switch (SYMBOL_CLASS (sym))
	    {
	    default:
	    case LOC_UNDEF:	/* catches errors        */
	    case LOC_CONST:	/* constant              */
	    case LOC_TYPEDEF:	/* local typedef         */
	    case LOC_LABEL:	/* local label           */
	    case LOC_BLOCK:	/* local function        */
	    case LOC_CONST_BYTES:	/* loc. byte seq.        */
	    case LOC_UNRESOLVED:	/* unresolved static     */
	    case LOC_OPTIMIZED_OUT:	/* optimized out         */
	      print_me = 0;
	      break;
 
	    case LOC_ARG:	/* argument              */
	    case LOC_REF_ARG:	/* reference arg         */
	    case LOC_REGPARM:	/* register arg          */
	    case LOC_REGPARM_ADDR:	/* indirect register arg */
	    case LOC_LOCAL_ARG:	/* stack arg             */
	    case LOC_BASEREG_ARG:	/* basereg arg           */
	      if (!locals)
		print_me = 1;
	      break;
 
	    case LOC_LOCAL:	/* stack local           */
	    case LOC_BASEREG:	/* basereg local         */
	    case LOC_STATIC:	/* static                */
	    case LOC_REGISTER:	/* register              */
	      if (locals)
		print_me = 1;
	      break;
	    }
	  if (print_me)
	    {
	      if (values)
		ui_out_list_begin (uiout, NULL);
	      ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
 
	      if (values)
		{
		  struct symbol *sym2;
		  if (!locals)
		    sym2 = lookup_symbol (SYMBOL_NAME (sym),
					  block, VAR_NAMESPACE,
					  (int *) NULL,
					  (struct symtab **) NULL);
		  else
		    sym2 = sym;
		  print_variable_value (sym2, fi, stb->stream);
		  ui_out_field_stream (uiout, "value", stb);
		  ui_out_list_end (uiout);
		}
	    }
	}
      if (BLOCK_FUNCTION (block))
	break;
      else
	block = BLOCK_SUPERBLOCK (block);
    }
  ui_out_list_end (uiout);
  ui_out_stream_delete (stb);
}
 
enum mi_cmd_result
mi_cmd_stack_select_frame (char *command, char **argv, int argc)
{
#ifdef UI_OUT
  if (!target_has_stack)
    error ("mi_cmd_stack_select_frame: No stack.");
 
  if (argc > 1)
    error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
 
  /* with no args, don't change frame */
  if (argc == 0)
    select_frame_command_wrapper (0, 1 /* not used */ );
  else
    select_frame_command_wrapper (argv[0], 1 /* not used */ );
#endif
  return MI_CMD_DONE;
}
 
/* Local variables: */
/* change-log-default-name: "ChangeLog-mi" */
/* End: */
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.