gdb-2.8
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 04dda0752b6038f72d9b1d67be8276a4d069b698..3fb12e46b2c0a828061bde11ba3f0d9638bb7600 100644 (file)
@@ -1,4 +1,4 @@
-/* Print values for GNU debugger gdb.
+/* Print values for GNU debugger GDB.
    Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
 
 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -54,8 +54,17 @@ static CORE_ADDR last_examine_address;
 
 static value last_examine_value;
 
+/* Number of auto-display expression currently being displayed.
+   So that we can deleted it if we get an error or a signal within it.
+   -1 when not doing one.  */
+
+int current_display_number;
+
+static void do_one_display ();
+
 void do_displays ();
 void print_address ();
+void print_scalar_formatted ();
 
 START_FILE
 \f
@@ -123,25 +132,11 @@ print_formatted (val, format, size)
   if (VALUE_LVAL (val) == lval_memory)
     next_address = VALUE_ADDRESS (val) + len;
 
-  if (format && format != 's')
-    {
-      val_long = value_as_long (val);
-
-      /* If value is unsigned, truncate it in case negative.  */
-      if (format != 'd')
-       {
-         if (len == sizeof (char))
-           val_long &= (1 << 8 * sizeof(char)) - 1;
-         else if (len == sizeof (short))
-           val_long &= (1 << 8 * sizeof(short)) - 1;
-       }
-    }
-
   switch (format)
     {
     case 's':
       next_address = VALUE_ADDRESS (val)
-       + value_print (value_addr (val), stdout);
+       + value_print (value_addr (val), stdout, 0);
       break;
 
     case 'i':
@@ -149,6 +144,49 @@ print_formatted (val, format, size)
        + print_insn (VALUE_ADDRESS (val), stdout);
       break;
 
+    default:
+      if (format == 0
+         || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
+         || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
+         || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION)
+       value_print (val, stdout, format);
+      else
+       print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val),
+                               format, size, stdout);
+    }
+}
+
+/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
+   according to letters FORMAT and SIZE on STREAM.
+   FORMAT may not be zero.  Formats s and i are not supported at this level.
+
+   This is how the elements of an array or structure are printed
+   with a format.  */
+
+void
+print_scalar_formatted (valaddr, type, format, size, stream)
+     char *valaddr;
+     struct type *type;
+     char format;
+     int size;
+     FILE *stream;
+{
+  long val_long;
+  int len = TYPE_LENGTH (type);
+
+  val_long = unpack_long (type, valaddr);
+
+  /* If value is unsigned, truncate it in case negative.  */
+  if (format != 'd')
+    {
+      if (len == sizeof (char))
+       val_long &= (1 << 8 * sizeof(char)) - 1;
+      else if (len == sizeof (short))
+       val_long &= (1 << 8 * sizeof(short)) - 1;
+    }
+
+  switch (format)
+    {
     case 'x':
       switch (size)
        {
@@ -186,31 +224,30 @@ print_formatted (val, format, size)
       break;
 
     case 'a':
-      print_address (val_long, stdout);
+      print_address (val_long, stream);
       break;
 
     case 'c':
-      value_print (value_cast (builtin_type_char, val), stdout);
+      value_print (value_from_long (builtin_type_char, val_long), stream, 0);
       break;
 
     case 'f':
-      if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (float))
-       VALUE_TYPE (val) = builtin_type_float;
-      if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double))
-       VALUE_TYPE (val) = builtin_type_double;
+      if (len == sizeof (float))
+       type = builtin_type_float;
+      if (len == sizeof (double))
+       type = builtin_type_double;
 #ifdef IEEE_FLOAT
-      if (is_nan (value_as_double (val)))
+      if (is_nan (unpack_double (type, valaddr)))
        {
          printf ("Nan");
          break;
        }
 #endif
-      printf ("%g", value_as_double (val));
+      printf ("%g", unpack_double (type, valaddr));
       break;
 
     case 0:
-      value_print (val, stdout);
-      break;
+      abort ();
 
     default:
       error ("Undefined output format \"%c\".", format);
@@ -364,7 +401,6 @@ print_command (exp)
   else
     val = access_value_history (0);
 
-  if (!val) return;       /*  C++  */
   histindex = record_latest_value (val);
   printf ("$%d = ", histindex);
 
@@ -414,41 +450,17 @@ set_command (exp)
   do_cleanups (old_chain);
 }
 
-/* C++: Modified to give useful information about variable which
-   hang off of `this'.  */
 static void
 address_info (exp)
      char *exp;
 {
   register struct symbol *sym;
   register CORE_ADDR val;
-  struct block *block, *get_selected_block ();
 
   if (exp == 0)
     error ("Argument required.");
 
-  block = get_selected_block ();
-  sym = lookup_symbol_1 (exp, block, VAR_NAMESPACE);
-  if (! sym)
-    {
-      value v;
-
-      /* C++: see if it hangs off of `this'.  Must
-        not inadvertently convert from a method call
-        to data ref.  */
-      v = value_of_this (0);
-      if (v)
-       {
-         val = check_field (v, exp);
-         if (val)
-           {
-             printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
-             return;
-           }
-       }
-      else
-       sym = lookup_symbol_2 (exp, 0, VAR_NAMESPACE);
-    }
+  sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE);
   if (sym == 0)
     {
       register int i;
@@ -572,12 +584,9 @@ whatis_command (exp)
   else
     val = access_value_history (0);
 
-  if (val != 0)
-    {
-      printf ("type = ");
-      type_print (VALUE_TYPE (val), "", stdout, 1);
-      printf ("\n");
-    }
+  printf ("type = ");
+  type_print (VALUE_TYPE (val), "", stdout, 1);
+  printf ("\n");
 
   if (exp)
     do_cleanups (old_chain);
@@ -639,143 +648,6 @@ ptype_command (typename)
   type_print (type, "", stdout, 1);
   printf ("\n");
 }
-
-/* Print all the methods that correspond to the name METHOD.
-   Can optionally qualify the method with a CLASSNAME, as
-   in CLASSNAME :: METHODNAME.  This routine does not call
-   parse_c_expression, so the input must conform to one of
-   these two forms.  */
-
-static void
-pmethod_command (exp)
-     char *exp;
-{
-# if 0
-  struct expression *expr;
-  register value val;
-  register struct cleanup *old_chain;
-  char *classname, *methodname;
-
-  methodname = exp;
-  while (*exp++ <= ' ') ;      /* remove leading whitespace */
-  if (exp[-1] == ':')
-    if (*exp == ':')
-      classname = (char *)1;
-    else error ("Invalid syntax: \"%s\"", methodname);
-  else
-    {
-      classname = exp-1;
-      while (*exp++ != ':') ;
-      exp[-1] = '\0';
-      if (*exp == ':')
-       {
-         while (*exp++ <= ' ') ; /* remove leading 2nd whitespace */
-         methodname = exp-1;
-         while (((*exp | 0x20) >= 'a' && ((*exp | 0x20) <= 'z')) || *exp == '_')
-           exp++;
-         if (*exp)
-           {
-             *exp++ = '\0';
-             while (*exp)
-               if (*exp > ' ') error ("junk after method name");
-           }
-       }
-      else error ("Invalid syntax: \"%s\"", methodname);
-    }
-  if (classname)
-    {
-      if (classname != (char *)1)
-       classtype = lookup_typename (classname);
-      else
-       {
-         register struct symtab *s;
-         register struct blockvector *bv;
-         struct blockvector *prev_bv = 0;
-         register struct block *b;
-         register int i, j;
-         register struct symbol *sym;
-         char *val;
-         int found_in_file;
-         static char *classnames[]
-           = {"variable", "function", "type", "method"};
-         int print_count = 0;
-
-         if (regexp)
-           if (val = (char *) re_comp (regexp))
-             error ("Invalid regexp: %s", val);
-
-         printf (regexp
-                 ? "All %ss matching regular expression \"%s\":\n"
-                 : "All defined %ss:\n",
-                 classnames[class],
-                 regexp);
-
-         for (s = symtab_list; s; s = s->next)
-           {
-             found_in_file = 0;
-             bv = BLOCKVECTOR (s);
-             /* Often many files share a blockvector.
-                Scan each blockvector only once so that
-                we don't get every symbol many times.
-                It happens that the first symtab in the list
-                for any given blockvector is the main file.  */
-             if (bv != prev_bv)
-               for (i = 0; i < 2; i++)
-                 {
-                   b = BLOCKVECTOR_BLOCK (bv, i);
-                   for (j = 0; j < BLOCK_NSYMS (b); j++)
-                     {
-                       QUIT;
-                       sym = BLOCK_SYM (b, j);
-                       if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
-                           && ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
-                                && SYMBOL_CLASS (sym) != LOC_BLOCK)
-                               || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
-                               || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
-                               || (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
-                         {
-                           if (!found_in_file)
-                             {
-                               printf ("\nFile %s:\n", s->filename);
-                               print_count += 2;
-                             }
-                           found_in_file = 1;
-                           MORE;
-                           if (i == 1)
-                             printf ("static ");
-
-                           type_print (SYMBOL_TYPE (sym),
-                                       (SYMBOL_CLASS (sym) == LOC_TYPEDEF
-                                        ? "" : SYMBOL_NAME (sym)),
-                                       stdout, 0);
-                           printf (";\n");
-                         }
-                     }
-                 }
-             prev_bv = bv;
-           }
-       }
-    }
-  if (exp)
-    {
-      expr = parse_c_expression (exp);
-      old_chain = make_cleanup (free_current_contents, &expr);
-      val = evaluate_type (expr);
-    }
-  else
-    val = access_value_history (0);
-
-  if (val != 0)
-    {
-      printf ("type = ");
-      type_print (VALUE_TYPE (val), "", stdout, 1);
-      printf ("\n");
-    }
-
-  if (exp)
-    do_cleanups (old_chain);
-# endif
-}
 \f
 struct display
 {
@@ -802,8 +674,9 @@ static int display_number;
    Specify the expression.  */
 
 static void
-display_command (exp)
+display_command (exp, from_tty)
      char *exp;
+     int from_tty;
 {
   struct format_data fmt;
   register struct expression *expr;
@@ -841,6 +714,9 @@ display_command (exp)
   new->format = fmt;
   display_chain = new;
 
+  if (from_tty)
+    do_one_display (new);
+
   dont_repeat ();
 }
 
@@ -869,6 +745,38 @@ clear_displays ()
     }
 }
 
+/* Delete the auto-display number NUM.  */
+
+void
+delete_display (num)
+     int num;
+{
+  register struct display *d1, *d;
+
+  if (!display_chain)
+    error ("No display number %d.", num);
+
+  if (display_chain->number == num)
+    {
+      d1 = display_chain;
+      display_chain = d1->next;
+      free_display (d1);
+    }
+  else
+    for (d = display_chain; ; d = d->next)
+      {
+       if (d->next == 0)
+         error ("No display number %d.", num);
+       if (d->next->number == num)
+         {
+           d1 = d->next;
+           d->next = d1->next;
+           free_display (d1);
+           break;
+         }
+      }
+}
+
 /* Delete some values from the auto-display chain.
    Specify the element numbers.  */
 
@@ -898,25 +806,7 @@ undisplay_command (args)
 
       num = atoi (p);
 
-      if (display_chain->number == num)
-       {
-         d1 = display_chain;
-         display_chain = d1->next;
-         free_display (d1);
-       }
-      else
-       for (d = display_chain; ; d = d->next)
-         {
-           if (d->next == 0)
-             error ("No display number %d.", num);
-           if (d->next->number == num)
-             {
-               d1 = d->next;
-               d->next = d1->next;
-               free_display (d1);
-               break;
-             }
-         }
+      delete_display (num);
 
       p = p1;
       while (*p == ' ' || *p == '\t') p++;
@@ -924,6 +814,47 @@ undisplay_command (args)
   dont_repeat ();
 }
 
+/* Display a single auto-display.  */
+
+static void
+do_one_display (d)
+     struct display *d;
+{
+  current_display_number = d->number;
+
+  printf ("%d: ", d->number);
+  if (d->format.size)
+    {
+      printf ("x/");
+      if (d->format.count != 1)
+       printf ("%d", d->format.count);
+      printf ("%c", d->format.format);
+      if (d->format.format != 'i' && d->format.format != 's')
+       printf ("%c", d->format.size);
+      printf (" ");
+      print_expression (d->exp, stdout);
+      if (d->format.count != 1)
+       printf ("\n");
+      else
+       printf ("  ");
+      do_examine (d->format,
+                 value_as_long (evaluate_expression (d->exp)));
+    }
+  else
+    {
+      if (d->format.format)
+       printf ("/%c ", d->format.format);
+      print_expression (d->exp, stdout);
+      printf (" = ");
+      print_formatted (evaluate_expression (d->exp),
+                      d->format.format, d->format.size);
+      printf ("\n");
+    }
+
+  fflush (stdout);
+  current_display_number = -1;
+}
+
 /* Display all of the values on the auto-display chain.  */
 
 void
@@ -932,37 +863,22 @@ do_displays ()
   register struct display *d;
 
   for (d = display_chain; d; d = d->next)
+    do_one_display (d);
+}
+
+/* Delete the auto-display which we were in the process of displaying.
+   This is done when there is an error or a signal.  */
+
+void
+delete_current_display ()
+{
+  if (current_display_number >= 0)
     {
-      printf ("%d: ", d->number);
-      if (d->format.size)
-       {
-         printf ("x/");
-         if (d->format.count != 1)
-           printf ("%d", d->format.count);
-         printf ("%c", d->format.format);
-         if (d->format.format != 'i' && d->format.format != 's')
-           printf ("%c", d->format.size);
-         printf (" ");
-         print_expression (d->exp, stdout);
-         if (d->format.count != 1)
-           printf ("\n");
-         else
-           printf ("  ");
-         do_examine (d->format,
-                     value_as_long (evaluate_expression (d->exp)));
-       }
-      else
-       {
-         if (d->format.format)
-           printf ("/%c ", d->format.format);
-         print_expression (d->exp, stdout);
-         printf (" = ");
-         print_formatted (evaluate_expression (d->exp),
-                          d->format.format, d->format.size);
-         printf ("\n");
-       }
-      fflush (stdout);
+      delete_display (current_display_number);
+      fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n",
+              current_display_number);
     }
+  current_display_number = -1;
 }
 
 static void
@@ -998,7 +914,7 @@ print_variable_value (var, frame, stream)
      FILE *stream;
 {
   value val = read_var_value (var, frame);
-  value_print (val, stream);
+  value_print (val, stream, 0);
 }
 
 /* Print the arguments of a stack frame, given the function FUNC
@@ -1057,7 +973,7 @@ print_frame_args (func, addr, num, stream)
       if (! first)
        fprintf (stream, ", ");
       fprintf (stream, "%s=", SYMBOL_NAME (sym));
-      value_print (val, stream);
+      value_print (val, stream, 0);
       first = 0;
       last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
       /* Round up address of next arg to multiple of size of int.  */
@@ -1255,6 +1171,8 @@ printf_command (arg)
 static
 initialize ()
 {
+  current_display_number = -1;
+
   add_info ("address", address_info,
           "Describe where variable VAR is stored.");
 
@@ -1281,11 +1199,6 @@ The selected stack frame's lexical context is used to look up the name.");
   add_com ("whatis", class_vars, whatis_command,
           "Print data type of expression EXP.");
 
-  add_com ("pmethod", class_vars, pmethod_command,
-          "Print definitions of method METHOD.\n\
-Argument must resolve to a method name within the containing scope.\n\
-All definitions found go into history array.");
-
   add_info ("display", display_info,
            "Expressions to display when program stops, with code numbers.");
   add_com ("undisplay", class_vars, undisplay_command,
This page took 0.031354 seconds and 4 git commands to generate.