Class-ify ui_out
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-stack.c
index baf9b6dbd68af0b902ccd322ac55a96234a15672..271cb840ca0399731962441e9fb3f8fe2f235a6a 100644 (file)
@@ -1,6 +1,5 @@
 /* MI Command Set - stack commands.
 /* MI Command Set - stack commands.
-   Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2016 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions (a Red Hat company).
 
    This file is part of GDB.
    Contributed by Cygnus Solutions (a Red Hat company).
 
    This file is part of GDB.
 #include "block.h"
 #include "stack.h"
 #include "dictionary.h"
 #include "block.h"
 #include "stack.h"
 #include "dictionary.h"
-#include "gdb_string.h"
 #include "language.h"
 #include "language.h"
+#include "valprint.h"
+#include "utils.h"
+#include "mi-getopt.h"
+#include "extension.h"
+#include <ctype.h>
+#include "mi-parse.h"
 
 
-static void list_args_or_locals (int locals, int values, struct frame_info *fi);
+enum what_to_list { locals, arguments, all };
 
 
-/* Print a list of the stack frames. Args can be none, in which case
+static void list_args_or_locals (enum what_to_list what,
+                                enum print_values values,
+                                struct frame_info *fi,
+                                int skip_unavailable);
+
+/* True if we want to allow Python-based frame filters.  */
+static int frame_filters = 0;
+
+void
+mi_cmd_enable_frame_filters (char *command, char **argv, int argc)
+{
+  if (argc != 0)
+    error (_("-enable-frame-filters: no arguments allowed"));
+  frame_filters = 1;
+}
+
+/* Like apply_ext_lang_frame_filter, but take a print_values */
+
+static enum ext_lang_bt_status
+mi_apply_ext_lang_frame_filter (struct frame_info *frame, int flags,
+                               enum print_values print_values,
+                               struct ui_out *out,
+                               int frame_low, int frame_high)
+{
+  /* ext_lang_frame_args's MI options are compatible with MI print
+     values.  */
+  return apply_ext_lang_frame_filter (frame, flags,
+                                     (enum ext_lang_frame_args) print_values,
+                                     out,
+                                     frame_low, frame_high);
+}
+
+/* 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
    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. */
+   display.  If the two numbers are equal, a single frame will be
+   displayed.  */
+
 void
 mi_cmd_stack_list_frames (char *command, char **argv, int argc)
 {
 void
 mi_cmd_stack_list_frames (char *command, char **argv, int argc)
 {
@@ -46,45 +83,98 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
   int i;
   struct cleanup *cleanup_stack;
   struct frame_info *fi;
   int i;
   struct cleanup *cleanup_stack;
   struct frame_info *fi;
+  enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
+  int raw_arg = 0;
+  int oind = 0;
+  enum opt
+    {
+      NO_FRAME_FILTERS
+    };
+  static const struct mi_opt opts[] =
+    {
+      {"-no-frame-filters", NO_FRAME_FILTERS, 0},
+      { 0, 0, 0 }
+    };
+
+  /* Parse arguments.  In this instance we are just looking for
+     --no-frame-filters.  */
+  while (1)
+    {
+      char *oarg;
+      int opt = mi_getopt ("-stack-list-frames", argc, argv,
+                          opts, &oind, &oarg);
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case NO_FRAME_FILTERS:
+         raw_arg = oind;
+         break;
+       }
+    }
 
 
-  if (argc > 2 || argc == 1)
-    error (_("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]"));
+  /* After the last option is parsed, there should either be low -
+     high range, or no further arguments.  */
+  if ((argc - oind != 0) && (argc - oind != 2))
+    error (_("-stack-list-frames: Usage: [--no-frame-filters] [FRAME_LOW FRAME_HIGH]"));
 
 
-  if (argc == 2)
+  /* If there is a range, set it.  */
+  if (argc - oind == 2)
     {
     {
-      frame_low = atoi (argv[0]);
-      frame_high = atoi (argv[1]);
+      frame_low = atoi (argv[0 + oind]);
+      frame_high = atoi (argv[1 + oind]);
     }
   else
     {
       /* Called with no arguments, it means we want the whole
     }
   else
     {
       /* Called with no arguments, it means we want the whole
-         backtrace. */
+         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
       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. */
+     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)
   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."));
+    error (_("-stack-list-frames: Not enough frames in stack."));
 
 
-  cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
+  cleanup_stack = make_cleanup_ui_out_list_begin_end (current_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))
+  if (! raw_arg && frame_filters)
+    {
+      int flags = PRINT_LEVEL | PRINT_FRAME_INFO;
+      int py_frame_low = frame_low;
+
+      /* We cannot pass -1 to frame_low, as that would signify a
+      relative backtrace from the tail of the stack.  So, in the case
+      of frame_low == -1, assign and increment it.  */
+      if (py_frame_low == -1)
+       py_frame_low++;
+
+      result = apply_ext_lang_frame_filter (get_current_frame (), flags,
+                                           NO_VALUES,  current_uiout,
+                                           py_frame_low, frame_high);
+    }
+
+  /* Run the inbuilt backtrace if there are no filters registered, or
+     if "--no-frame-filters" has been specified from the command.  */
+  if (! frame_filters || raw_arg  || result == EXT_LANG_BT_NO_FILTERS)
     {
     {
-      QUIT;
-      /* Print the location and the address always, even for level 0.
-         args == 0: don't print the arguments. */
-      print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* 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;
+         /* Print the location and the address always, even for level 0.
+            If args is 0, don't print the arguments.  */
+         print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */, 0);
+       }
     }
 
   do_cleanups (cleanup_stack);
     }
 
   do_cleanups (cleanup_stack);
@@ -98,13 +188,13 @@ mi_cmd_stack_info_depth (char *command, char **argv, int argc)
   struct frame_info *fi;
 
   if (argc > 1)
   struct frame_info *fi;
 
   if (argc > 1)
-    error (_("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]"));
+    error (_("-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
 
   if (argc == 1)
     frame_high = atoi (argv[0]);
   else
     /* Called with no arguments, it means we want the real depth of
-       the stack. */
+       the stack.  */
     frame_high = -1;
 
   for (i = 0, fi = get_current_frame ();
     frame_high = -1;
 
   for (i = 0, fi = get_current_frame ();
@@ -112,42 +202,87 @@ mi_cmd_stack_info_depth (char *command, char **argv, int argc)
        i++, fi = get_prev_frame (fi))
     QUIT;
 
        i++, fi = get_prev_frame (fi))
     QUIT;
 
-  ui_out_field_int (uiout, "depth", i);
+  current_uiout->field_int ("depth", i);
 }
 
 }
 
-/* Print a list of the locals for the current frame. With argument of
+/* 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
    0, print only the names, with argument of 1 print also the
-   values. */
+   values.  */
+
 void
 mi_cmd_stack_list_locals (char *command, char **argv, int argc)
 {
   struct frame_info *frame;
 void
 mi_cmd_stack_list_locals (char *command, char **argv, int argc)
 {
   struct frame_info *frame;
-  enum print_values print_values;
+  int raw_arg = 0;
+  enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
+  enum print_values print_value;
+  int oind = 0;
+  int skip_unavailable = 0;
 
 
-  if (argc != 1)
-    error (_("mi_cmd_stack_list_locals: Usage: PRINT_VALUES"));
+  if (argc > 1)
+    {
+      enum opt
+      {
+       NO_FRAME_FILTERS,
+       SKIP_UNAVAILABLE,
+      };
+      static const struct mi_opt opts[] =
+       {
+         {"-no-frame-filters", NO_FRAME_FILTERS, 0},
+         {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
+         { 0, 0, 0 }
+       };
 
 
-   frame = get_selected_frame (NULL);
+      while (1)
+       {
+         char *oarg;
+         /* Don't parse 'print-values' as an option.  */
+         int opt = mi_getopt ("-stack-list-locals", argc - 1, argv,
+                              opts, &oind, &oarg);
+
+         if (opt < 0)
+           break;
+         switch ((enum opt) opt)
+           {
+           case NO_FRAME_FILTERS:
+             raw_arg = oind;
+           case SKIP_UNAVAILABLE:
+             skip_unavailable = 1;
+             break;
+           }
+       }
+    }
 
 
-   if (strcmp (argv[0], "0") == 0
-       || strcmp (argv[0], mi_no_values) == 0)
-     print_values = PRINT_NO_VALUES;
-   else if (strcmp (argv[0], "1") == 0
-           || strcmp (argv[0], mi_all_values) == 0)
-     print_values = PRINT_ALL_VALUES;
-   else if (strcmp (argv[0], "2") == 0
-           || strcmp (argv[0], mi_simple_values) == 0)
-     print_values = PRINT_SIMPLE_VALUES;
-   else
-     error (_("Unknown value for PRINT_VALUES: must be: \
-0 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
-           mi_no_values, mi_all_values, mi_simple_values);
-  list_args_or_locals (1, print_values, frame);
+  /* After the last option is parsed, there should be only
+     'print-values'.  */
+  if (argc - oind != 1)
+    error (_("-stack-list-locals: Usage: [--no-frame-filters] "
+            "[--skip-unavailable] PRINT_VALUES"));
+
+  frame = get_selected_frame (NULL);
+  print_value = mi_parse_print_values (argv[oind]);
+
+   if (! raw_arg && frame_filters)
+     {
+       int flags = PRINT_LEVEL | PRINT_LOCALS;
+
+       result = mi_apply_ext_lang_frame_filter (frame, flags, print_value,
+                                               current_uiout, 0, 0);
+     }
+
+   /* Run the inbuilt backtrace if there are no filters registered, or
+      if "--no-frame-filters" has been specified from the command.  */
+   if (! frame_filters || raw_arg  || result == EXT_LANG_BT_NO_FILTERS)
+     {
+       list_args_or_locals (locals, print_value, frame,
+                           skip_unavailable);
+     }
 }
 
 }
 
-/* Print a list of the arguments for the current frame. With argument
+/* 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
    of 0, print only the names, with argument of 1 print also the
-   values. */
+   values.  */
+
 void
 mi_cmd_stack_list_args (char *command, char **argv, int argc)
 {
 void
 mi_cmd_stack_list_args (char *command, char **argv, int argc)
 {
@@ -156,72 +291,316 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
   int i;
   struct frame_info *fi;
   struct cleanup *cleanup_stack_args;
   int i;
   struct frame_info *fi;
   struct cleanup *cleanup_stack_args;
+  enum print_values print_values;
+  struct ui_out *uiout = current_uiout;
+  int raw_arg = 0;
+  int oind = 0;
+  int skip_unavailable = 0;
+  enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
+  enum opt
+  {
+    NO_FRAME_FILTERS,
+    SKIP_UNAVAILABLE,
+  };
+  static const struct mi_opt opts[] =
+    {
+      {"-no-frame-filters", NO_FRAME_FILTERS, 0},
+      {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
+      { 0, 0, 0 }
+    };
 
 
-  if (argc < 1 || argc > 3 || argc == 2)
-    error (_("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]"));
+  while (1)
+    {
+      char *oarg;
+      int opt = mi_getopt_allow_unknown ("-stack-list-args", argc, argv,
+                                        opts, &oind, &oarg);
 
 
-  if (argc == 3)
+      if (opt < 0)
+       break;
+      switch ((enum opt) opt)
+       {
+       case NO_FRAME_FILTERS:
+         raw_arg = oind;
+         break;
+       case SKIP_UNAVAILABLE:
+         skip_unavailable = 1;
+         break;
+       }
+    }
+
+  if (argc - oind != 1 && argc - oind != 3)
+    error (_("-stack-list-arguments: Usage: "  \
+            "[--no-frame-filters] [--skip-unavailable] "
+            "PRINT_VALUES [FRAME_LOW FRAME_HIGH]"));
+
+  if (argc - oind == 3)
     {
     {
-      frame_low = atoi (argv[1]);
-      frame_high = atoi (argv[2]);
+      frame_low = atoi (argv[1 + oind]);
+      frame_high = atoi (argv[2 + oind]);
     }
   else
     {
       /* Called with no arguments, it means we want args for the whole
     }
   else
     {
       /* Called with no arguments, it means we want args for the whole
-         backtrace. */
+         backtrace.  */
       frame_low = -1;
       frame_high = -1;
     }
 
       frame_low = -1;
       frame_high = -1;
     }
 
+  print_values = mi_parse_print_values (argv[oind]);
+
   /* Let's position fi on the frame at which to start the
      display. Could be the innermost frame if the whole stack needs
   /* 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. */
+     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)
   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."));
+    error (_("-stack-list-arguments: Not enough frames in stack."));
 
 
-  cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
+  cleanup_stack_args
+    = make_cleanup_ui_out_list_begin_end (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))
+  if (! raw_arg && frame_filters)
     {
     {
-      struct cleanup *cleanup_frame;
-      QUIT;
-      cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
-      ui_out_field_int (uiout, "level", i);
-      list_args_or_locals (0, atoi (argv[0]), fi);
-      do_cleanups (cleanup_frame);
+      int flags = PRINT_LEVEL | PRINT_ARGS;
+      int py_frame_low = frame_low;
+
+      /* We cannot pass -1 to frame_low, as that would signify a
+      relative backtrace from the tail of the stack.  So, in the case
+      of frame_low == -1, assign and increment it.  */
+      if (py_frame_low == -1)
+       py_frame_low++;
+
+      result = mi_apply_ext_lang_frame_filter (get_current_frame (), flags,
+                                              print_values, current_uiout,
+                                              py_frame_low, frame_high);
     }
 
     }
 
+     /* Run the inbuilt backtrace if there are no filters registered, or
+      if "--no-frame-filters" has been specified from the command.  */
+   if (! frame_filters || raw_arg  || result == EXT_LANG_BT_NO_FILTERS)
+     {
+      /* 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))
+       {
+         struct cleanup *cleanup_frame;
+
+         QUIT;
+         cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
+         uiout->field_int ("level", i);
+         list_args_or_locals (arguments, print_values, fi, skip_unavailable);
+         do_cleanups (cleanup_frame);
+       }
+    }
   do_cleanups (cleanup_stack_args);
 }
 
   do_cleanups (cleanup_stack_args);
 }
 
-/* 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. */
+/* Print a list of the local variables (including arguments) for the 
+   current frame.  ARGC must be 1 and ARGV[0] specify if only the names,
+   or both names and values of the variables must be printed.  See 
+   parse_print_value for possible values.  */
+
+void
+mi_cmd_stack_list_variables (char *command, char **argv, int argc)
+{
+  struct frame_info *frame;
+  int raw_arg = 0;
+  enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
+  enum print_values print_value;
+  int oind = 0;
+  int skip_unavailable = 0;
+
+  if (argc > 1)
+    {
+      enum opt
+      {
+       NO_FRAME_FILTERS,
+       SKIP_UNAVAILABLE,
+      };
+      static const struct mi_opt opts[] =
+       {
+         {"-no-frame-filters", NO_FRAME_FILTERS, 0},
+         {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
+         { 0, 0, 0 }
+       };
+
+      while (1)
+       {
+         char *oarg;
+         /* Don't parse 'print-values' as an option.  */
+         int opt = mi_getopt ("-stack-list-variables", argc - 1,
+                              argv, opts, &oind, &oarg);
+         if (opt < 0)
+           break;
+         switch ((enum opt) opt)
+           {
+           case NO_FRAME_FILTERS:
+             raw_arg = oind;
+             break;
+           case SKIP_UNAVAILABLE:
+             skip_unavailable = 1;
+             break;
+           }
+       }
+    }
+
+  /* After the last option is parsed, there should be only
+     'print-values'.  */
+  if (argc - oind != 1)
+    error (_("-stack-list-variables: Usage: [--no-frame-filters] " \
+            "[--skip-unavailable] PRINT_VALUES"));
+
+   frame = get_selected_frame (NULL);
+   print_value = mi_parse_print_values (argv[oind]);
+
+   if (! raw_arg && frame_filters)
+     {
+       int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS;
+
+       result = mi_apply_ext_lang_frame_filter (frame, flags,
+                                               print_value,
+                                               current_uiout, 0, 0);
+     }
+
+   /* Run the inbuilt backtrace if there are no filters registered, or
+      if "--no-frame-filters" has been specified from the command.  */
+   if (! frame_filters || raw_arg  || result == EXT_LANG_BT_NO_FILTERS)
+     {
+       list_args_or_locals (all, print_value, frame,
+                           skip_unavailable);
+     }
+}
+
+/* Print single local or argument.  ARG must be already read in.  For
+   WHAT and VALUES see list_args_or_locals.
+
+   Errors are printed as if they would be the parameter value.  Use
+   zeroed ARG iff it should not be printed according to VALUES.  If
+   SKIP_UNAVAILABLE is true, only print ARG if it is available.  */
+
+static void
+list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
+                  enum print_values values, int skip_unavailable)
+{
+  struct cleanup *old_chain;
+  struct ui_out *uiout = current_uiout;
+  struct ui_file *stb;
+
+  gdb_assert (!arg->val || !arg->error);
+  gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL
+              && arg->error == NULL)
+             || values == PRINT_SIMPLE_VALUES
+             || (values == PRINT_ALL_VALUES
+                 && (arg->val != NULL || arg->error != NULL)));
+  gdb_assert (arg->entry_kind == print_entry_values_no
+             || (arg->entry_kind == print_entry_values_only
+                 && (arg->val || arg->error)));
+
+  if (skip_unavailable && arg->val != NULL
+      && (value_entirely_unavailable (arg->val)
+         /* A scalar object that does not have all bits available is
+            also considered unavailable, because all bits contribute
+            to its representation.  */
+         || (val_print_scalar_type_p (value_type (arg->val))
+             && !value_bytes_available (arg->val,
+                                        value_embedded_offset (arg->val),
+                                        TYPE_LENGTH (value_type (arg->val))))))
+    return;
+
+  stb = mem_fileopen ();
+  old_chain = make_cleanup_ui_file_delete (stb);
+
+  if (values != PRINT_NO_VALUES || what == all)
+    make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+
+  fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb);
+  if (arg->entry_kind == print_entry_values_only)
+    fputs_filtered ("@entry", stb);
+  uiout->field_stream ("name", stb);
+
+  if (what == all && SYMBOL_IS_ARGUMENT (arg->sym))
+    uiout->field_int ("arg", 1);
+
+  if (values == PRINT_SIMPLE_VALUES)
+    {
+      check_typedef (arg->sym->type);
+      type_print (arg->sym->type, "", stb, -1);
+      uiout->field_stream ("type", stb);
+    }
+
+  if (arg->val || arg->error)
+    {
+      const char *error_message = NULL;
+
+      if (arg->error)
+       error_message = arg->error;
+      else
+       {
+         TRY
+           {
+             struct value_print_options opts;
+
+             get_no_prettyformat_print_options (&opts);
+             opts.deref_ref = 1;
+             common_val_print (arg->val, stb, 0, &opts,
+                               language_def (SYMBOL_LANGUAGE (arg->sym)));
+           }
+         CATCH (except, RETURN_MASK_ERROR)
+           {
+             error_message = except.message;
+           }
+         END_CATCH
+       }
+      if (error_message != NULL)
+       fprintf_filtered (stb, _("<error reading variable: %s>"),
+                         error_message);
+      uiout->field_stream ("value", stb);
+    }
+
+  do_cleanups (old_chain);
+}
+
+/* Print a list of the objects for the frame FI in a certain form,
+   which is determined by VALUES.  The objects can be locals,
+   arguments or both, which is determined by WHAT.  If SKIP_UNAVAILABLE
+   is true, only print the arguments or local variables whose values
+   are available.  */
+
 static void
 static void
-list_args_or_locals (int locals, int values, struct frame_info *fi)
+list_args_or_locals (enum what_to_list what, enum print_values values,
+                    struct frame_info *fi, int skip_unavailable)
 {
 {
-  struct block *block;
+  const struct block *block;
   struct symbol *sym;
   struct symbol *sym;
-  struct dict_iterator iter;
-  int nsyms;
+  struct block_iterator iter;
   struct cleanup *cleanup_list;
   struct cleanup *cleanup_list;
-  static struct ui_stream *stb = NULL;
   struct type *type;
   struct type *type;
-
-  stb = ui_out_stream_new (uiout);
+  char *name_of_result;
+  struct ui_out *uiout = current_uiout;
 
   block = get_frame_block (fi, 0);
 
 
   block = get_frame_block (fi, 0);
 
-  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
+  switch (what)
+    {
+    case locals:
+      name_of_result = "locals";
+      break;
+    case arguments:
+      name_of_result = "args";
+      break;
+    case all:
+      name_of_result = "variables";
+      break;
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "unexpected what_to_list: %d", (int) what);
+    }
+
+  cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, name_of_result);
 
   while (block != 0)
     {
 
   while (block != 0)
     {
@@ -250,69 +629,73 @@ list_args_or_locals (int locals, int values, struct frame_info *fi)
            case LOC_STATIC:    /* static                */
            case LOC_REGISTER:  /* register              */
            case LOC_COMPUTED:  /* computed location     */
            case LOC_STATIC:    /* static                */
            case LOC_REGISTER:  /* register              */
            case LOC_COMPUTED:  /* computed location     */
-             if (SYMBOL_IS_ARGUMENT (sym) ? !locals : locals)
+             if (what == all)
                print_me = 1;
                print_me = 1;
+             else if (what == locals)
+               print_me = !SYMBOL_IS_ARGUMENT (sym);
+             else
+               print_me = SYMBOL_IS_ARGUMENT (sym);
              break;
            }
          if (print_me)
            {
              break;
            }
          if (print_me)
            {
-             struct cleanup *cleanup_tuple = NULL;
              struct symbol *sym2;
              struct symbol *sym2;
-             struct value *val;
-             if (values != PRINT_NO_VALUES)
-               cleanup_tuple =
-                 make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-             ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));
-
-             if (!locals)
-               sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
+             struct frame_arg arg, entryarg;
+
+             if (SYMBOL_IS_ARGUMENT (sym))
+               sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym),
                                      block, VAR_DOMAIN,
                                      block, VAR_DOMAIN,
-                                     (int *) NULL);
+                                     NULL).symbol;
              else
                sym2 = sym;
              else
                sym2 = sym;
+             gdb_assert (sym2 != NULL);
+
+             memset (&arg, 0, sizeof (arg));
+             arg.sym = sym2;
+             arg.entry_kind = print_entry_values_no;
+             memset (&entryarg, 0, sizeof (entryarg));
+             entryarg.sym = sym2;
+             entryarg.entry_kind = print_entry_values_no;
+
              switch (values)
                {
                case PRINT_SIMPLE_VALUES:
                  type = check_typedef (sym2->type);
              switch (values)
                {
                case PRINT_SIMPLE_VALUES:
                  type = check_typedef (sym2->type);
-                 type_print (sym2->type, "", stb->stream, -1);
-                 ui_out_field_stream (uiout, "type", stb);
                  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
                      && TYPE_CODE (type) != TYPE_CODE_STRUCT
                      && TYPE_CODE (type) != TYPE_CODE_UNION)
                    {
                  if (TYPE_CODE (type) != TYPE_CODE_ARRAY
                      && TYPE_CODE (type) != TYPE_CODE_STRUCT
                      && TYPE_CODE (type) != TYPE_CODE_UNION)
                    {
-                     val = read_var_value (sym2, fi);
-                     common_val_print
-                       (val, stb->stream, 0, 1, 0, Val_no_prettyprint,
-                        language_def (SYMBOL_LANGUAGE (sym2)));
-                     ui_out_field_stream (uiout, "value", stb);
-                   }
-                 do_cleanups (cleanup_tuple);
-                 break;
                case PRINT_ALL_VALUES:
                case PRINT_ALL_VALUES:
-                 val = read_var_value (sym2, fi);
-                 common_val_print
-                   (val, stb->stream, 0, 1, 0, Val_no_prettyprint,
-                    language_def (SYMBOL_LANGUAGE (sym2)));
-                 ui_out_field_stream (uiout, "value", stb);
-                 do_cleanups (cleanup_tuple);
+                 if (SYMBOL_IS_ARGUMENT (sym))
+                   read_frame_arg (sym2, fi, &arg, &entryarg);
+                 else
+                   read_frame_local (sym2, fi, &arg);
+                   }
                  break;
                }
                  break;
                }
+
+             if (arg.entry_kind != print_entry_values_only)
+               list_arg_or_local (&arg, what, values, skip_unavailable);
+             if (entryarg.entry_kind != print_entry_values_no)
+               list_arg_or_local (&entryarg, what, values, skip_unavailable);
+             xfree (arg.error);
+             xfree (entryarg.error);
            }
        }
            }
        }
+
       if (BLOCK_FUNCTION (block))
        break;
       else
        block = BLOCK_SUPERBLOCK (block);
     }
   do_cleanups (cleanup_list);
       if (BLOCK_FUNCTION (block))
        break;
       else
        block = BLOCK_SUPERBLOCK (block);
     }
   do_cleanups (cleanup_list);
-  ui_out_stream_delete (stb);
 }
 
 void
 mi_cmd_stack_select_frame (char *command, char **argv, int argc)
 {
   if (argc == 0 || argc > 1)
 }
 
 void
 mi_cmd_stack_select_frame (char *command, char **argv, int argc)
 {
   if (argc == 0 || argc > 1)
-    error (_("mi_cmd_stack_select_frame: Usage: FRAME_SPEC"));
+    error (_("-stack-select-frame: Usage: FRAME_SPEC"));
 
   select_frame_command (argv[0], 1 /* not used */ );
 }
 
   select_frame_command (argv[0], 1 /* not used */ );
 }
@@ -321,7 +704,7 @@ void
 mi_cmd_stack_info_frame (char *command, char **argv, int argc)
 {
   if (argc > 0)
 mi_cmd_stack_info_frame (char *command, char **argv, int argc)
 {
   if (argc > 0)
-    error (_("mi_cmd_stack_info_frame: No arguments required"));
+    error (_("-stack-info-frame: No arguments allowed"));
 
 
-  print_frame_info (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 0);
+  print_frame_info (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 0, 1);
 }
 }
This page took 0.031663 seconds and 4 git commands to generate.