daily update
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index e531175455399a311ac84e6c7bfab9723ad076f7..ad9401866817399c7d2cc76a4fc283a5b8a115f1 100644 (file)
@@ -1,8 +1,8 @@
 /* Print values for GNU debugger GDB.
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+   2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "tui/tui.h"           /* For tui_active et.al.   */
 #endif
 
+#if defined(__MINGW32__)
+# define USE_PRINTF_I64 1
+# define PRINTF_HAS_LONG_LONG
+#else
+# define USE_PRINTF_I64 0
+#endif
+
 extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
 extern int addressprint;       /* Whether to print hex addresses in HLL " */
 
@@ -285,6 +292,7 @@ print_formatted (struct value *val, int format, int size,
     }
 
   if (format == 0 || format == 's'
+      || TYPE_CODE (type) == TYPE_CODE_REF
       || TYPE_CODE (type) == TYPE_CODE_ARRAY
       || TYPE_CODE (type) == TYPE_CODE_STRING
       || TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -314,13 +322,15 @@ print_scalar_formatted (const void *valaddr, struct type *type,
 {
   LONGEST val_long = 0;
   unsigned int len = TYPE_LENGTH (type);
+  enum bfd_endian byte_order = gdbarch_byte_order (current_gdbarch);
 
   /* If we get here with a string format, try again without it.  Go
      all the way back to the language printers, which may call us
      again.  */
   if (format == 's')
     {
-      val_print (type, valaddr, 0, 0, stream, 0, 0, 0, Val_pretty_default);
+      val_print (type, valaddr, 0, 0, stream, 0, 0, 0, Val_pretty_default,
+                current_language);
       return;
     }
 
@@ -331,20 +341,20 @@ print_scalar_formatted (const void *valaddr, struct type *type,
       switch (format)
        {
        case 'o':
-         print_octal_chars (stream, valaddr, len);
+         print_octal_chars (stream, valaddr, len, byte_order);
          return;
        case 'u':
        case 'd':
-         print_decimal_chars (stream, valaddr, len);
+         print_decimal_chars (stream, valaddr, len, byte_order);
          return;
        case 't':
-         print_binary_chars (stream, valaddr, len);
+         print_binary_chars (stream, valaddr, len, byte_order);
          return;
        case 'x':
-         print_hex_chars (stream, valaddr, len);
+         print_hex_chars (stream, valaddr, len, byte_order);
          return;
        case 'c':
-         print_char_chars (stream, valaddr, len);
+         print_char_chars (stream, valaddr, len, byte_order);
          return;
        default:
          break;
@@ -666,23 +676,6 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
   return 0;
 }
 
-/* Print address ADDR on STREAM.  USE_LOCAL means the same thing as for
-   print_longest.  */
-void
-deprecated_print_address_numeric (CORE_ADDR addr, int use_local,
-                                 struct ui_file *stream)
-{
-  if (use_local)
-    fputs_filtered (paddress (addr), stream);
-  else
-    {
-      int addr_bit = gdbarch_addr_bit (current_gdbarch);
-
-      if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
-       addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
-      print_longest (stream, 'x', 0, (ULONGEST) addr);
-    }
-}
 
 /* Print address ADDR symbolically on STREAM.
    First print it as a number.  Then perhaps print
@@ -691,7 +684,7 @@ deprecated_print_address_numeric (CORE_ADDR addr, int use_local,
 void
 print_address (CORE_ADDR addr, struct ui_file *stream)
 {
-  deprecated_print_address_numeric (addr, 1, stream);
+  fputs_filtered (paddress (addr), stream);
   print_address_symbolic (addr, stream, asm_demangle, " ");
 }
 
@@ -710,7 +703,7 @@ print_address_demangle (CORE_ADDR addr, struct ui_file *stream,
     }
   else if (addressprint)
     {
-      deprecated_print_address_numeric (addr, 1, stream);
+      fputs_filtered (paddress (addr), stream);
       print_address_symbolic (addr, stream, do_demangle, " ");
     }
   else
@@ -1032,7 +1025,6 @@ address_info (char *exp, int from_tty)
   struct symbol *sym;
   struct minimal_symbol *msymbol;
   long val;
-  long basereg;
   asection *section;
   CORE_ADDR load_addr;
   int is_a_field_of_this;      /* C++: lookup_symbol sets this to nonzero
@@ -1042,7 +1034,7 @@ address_info (char *exp, int from_tty)
     error (_("Argument required."));
 
   sym = lookup_symbol (exp, get_selected_block (0), VAR_DOMAIN,
-                      &is_a_field_of_this, (struct symtab **) NULL);
+                      &is_a_field_of_this);
   if (sym == NULL)
     {
       if (is_a_field_of_this)
@@ -1068,14 +1060,14 @@ address_info (char *exp, int from_tty)
          fprintf_symbol_filtered (gdb_stdout, exp,
                                   current_language->la_language, DMGL_ANSI);
          printf_filtered ("\" is at ");
-         deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+         fputs_filtered (paddress (load_addr), gdb_stdout);
          printf_filtered (" in a file compiled without debugging");
          section = SYMBOL_BFD_SECTION (msymbol);
          if (section_is_overlay (section))
            {
              load_addr = overlay_unmapped_address (load_addr, section);
              printf_filtered (",\n -- loaded at ");
-             deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+             fputs_filtered (paddress (load_addr), gdb_stdout);
              printf_filtered (" in overlay section %s", section->name);
            }
          printf_filtered (".\n");
@@ -1090,7 +1082,6 @@ address_info (char *exp, int from_tty)
                           current_language->la_language, DMGL_ANSI);
   printf_filtered ("\" is ");
   val = SYMBOL_VALUE (sym);
-  basereg = SYMBOL_BASEREG (sym);
   section = SYMBOL_BFD_SECTION (sym);
 
   switch (SYMBOL_CLASS (sym))
@@ -1102,13 +1093,13 @@ address_info (char *exp, int from_tty)
 
     case LOC_LABEL:
       printf_filtered ("a label at address ");
-      deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
-                            1, gdb_stdout);
+      fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
+                     gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (",\n -- loaded at ");
-         deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+         fputs_filtered (paddress (load_addr), gdb_stdout);
          printf_filtered (" in overlay section %s", section->name);
        }
       break;
@@ -1130,27 +1121,13 @@ address_info (char *exp, int from_tty)
 
     case LOC_STATIC:
       printf_filtered (_("static storage at address "));
-      deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
-                            1, gdb_stdout);
+     fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
+                    gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (_(",\n -- loaded at "));
-         deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
-         printf_filtered (_(" in overlay section %s"), section->name);
-       }
-      break;
-
-    case LOC_INDIRECT:
-      printf_filtered (_("external global (indirect addressing), at address *("));
-      deprecated_print_address_numeric (load_addr = SYMBOL_VALUE_ADDRESS (sym),
-                            1, gdb_stdout);
-      printf_filtered (")");
-      if (section_is_overlay (section))
-       {
-         load_addr = overlay_unmapped_address (load_addr, section);
-         printf_filtered (_(",\n -- loaded at "));
-         deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+         fputs_filtered (paddress (load_addr), gdb_stdout);
          printf_filtered (_(" in overlay section %s"), section->name);
        }
       break;
@@ -1169,10 +1146,6 @@ address_info (char *exp, int from_tty)
       printf_filtered (_("an argument at offset %ld"), val);
       break;
 
-    case LOC_LOCAL_ARG:
-      printf_filtered (_("an argument at frame offset %ld"), val);
-      break;
-
     case LOC_LOCAL:
       printf_filtered (_("a local variable at frame offset %ld"), val);
       break;
@@ -1181,16 +1154,6 @@ address_info (char *exp, int from_tty)
       printf_filtered (_("a reference argument at offset %ld"), val);
       break;
 
-    case LOC_BASEREG:
-      printf_filtered (_("a variable at offset %ld from register %s"),
-                      val, gdbarch_register_name (current_gdbarch, basereg));
-      break;
-
-    case LOC_BASEREG_ARG:
-      printf_filtered (_("an argument at offset %ld from register %s"),
-                      val, gdbarch_register_name (current_gdbarch, basereg));
-      break;
-
     case LOC_TYPEDEF:
       printf_filtered (_("a typedef"));
       break;
@@ -1198,12 +1161,12 @@ address_info (char *exp, int from_tty)
     case LOC_BLOCK:
       printf_filtered (_("a function at address "));
       load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-      deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+      fputs_filtered (paddress (load_addr), gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (_(",\n -- loaded at "));
-         deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+         fputs_filtered (paddress (load_addr), gdb_stdout);
          printf_filtered (_(" in overlay section %s"), section->name);
        }
       break;
@@ -1220,24 +1183,18 @@ address_info (char *exp, int from_tty)
            section = SYMBOL_BFD_SECTION (msym);
            printf_filtered (_("static storage at address "));
            load_addr = SYMBOL_VALUE_ADDRESS (msym);
-           deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+           fputs_filtered (paddress (load_addr), gdb_stdout);
            if (section_is_overlay (section))
              {
                load_addr = overlay_unmapped_address (load_addr, section);
                printf_filtered (_(",\n -- loaded at "));
-               deprecated_print_address_numeric (load_addr, 1, gdb_stdout);
+               fputs_filtered (paddress (load_addr), gdb_stdout);
                printf_filtered (_(" in overlay section %s"), section->name);
              }
          }
       }
       break;
 
-    case LOC_HP_THREAD_LOCAL_STATIC:
-      printf_filtered (_("\
-a thread-local variable at offset %ld from the thread base register %s"),
-                      val, gdbarch_register_name (current_gdbarch, basereg));
-      break;
-
     case LOC_OPTIMIZED_OUT:
       printf_filtered (_("optimized out"));
       break;
@@ -1837,7 +1794,8 @@ printf_command (char *arg, int from_tty)
        {
          int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
          int seen_space = 0, seen_plus = 0;
-         int seen_big_l = 0, seen_h = 0;
+         int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
+         int seen_big_d = 0, seen_double_big_d = 0;
          int bad = 0;
 
          /* Check the validity of the format specifier, and work
@@ -1901,6 +1859,26 @@ printf_command (char *arg, int from_tty)
              seen_big_l = 1;
              f++;
            }
+         /* Decimal32 modifier.  */
+         else if (*f == 'H')
+           {
+             seen_big_h = 1;
+             f++;
+           }
+         /* Decimal64 and Decimal128 modifiers.  */
+         else if (*f == 'D')
+           {
+             f++;
+
+             /* Check for a Decimal128.  */
+             if (*f == 'D')
+               {
+                 f++;
+                 seen_double_big_d = 1;
+               }
+             else
+               seen_big_d = 1;
+           }
 
          switch (*f)
            {
@@ -1929,34 +1907,6 @@ printf_command (char *arg, int from_tty)
                bad = 1;
              break;
 
-           /* DFP Decimal32 types.  */
-           case 'H':
-             this_argclass = decfloat_arg;
-
-#ifndef PRINTF_HAS_DECFLOAT
-              if (lcount || seen_h || seen_big_l)
-                bad = 1;
-              if (seen_prec || seen_zero || seen_space || seen_plus)
-                bad = 1;
-#endif
-             break;
-
-           /* DFP Decimal64 and Decimal128 types.  */
-           case 'D':
-             this_argclass = decfloat_arg;
-
-#ifndef PRINTF_HAS_DECFLOAT
-              if (lcount || seen_h || seen_big_l)
-                bad = 1;
-              if (seen_prec || seen_zero || seen_space || seen_plus)
-                bad = 1;
-#endif
-             /* Check for a Decimal128.  */
-             if (*(f + 1) == 'D')
-               f++;
-
-             break;
-
            case 'c':
              this_argclass = int_arg;
              if (lcount || seen_h || seen_big_l)
@@ -1986,7 +1936,9 @@ printf_command (char *arg, int from_tty)
            case 'g':
            case 'E':
            case 'G':
-             if (seen_big_l)
+             if (seen_big_h || seen_big_d || seen_double_big_d)
+               this_argclass = decfloat_arg;
+             else if (seen_big_l)
                this_argclass = long_double_arg;
              else
                this_argclass = double_arg;
@@ -2013,8 +1965,23 @@ printf_command (char *arg, int from_tty)
                   *f);
 
          f++;
-         strncpy (current_substring, last_arg, f - last_arg);
-         current_substring += f - last_arg;
+
+         if (lcount > 1 && USE_PRINTF_I64)
+           {
+             /* Windows' printf does support long long, but not the usual way.
+                Convert %lld to %I64d.  */
+             int length_before_ll = f - last_arg - 1 - lcount;
+             strncpy (current_substring, last_arg, length_before_ll);
+             strcpy (current_substring + length_before_ll, "I64");
+             current_substring[length_before_ll + 3] =
+               last_arg[length_before_ll + lcount];
+             current_substring += length_before_ll + 4;
+           }
+         else
+           {
+             strncpy (current_substring, last_arg, f - last_arg);
+             current_substring += f - last_arg;
+           }
          *current_substring++ = '\0';
          last_arg = f;
          argclass[nargs_wanted++] = this_argclass;
@@ -2124,50 +2091,101 @@ printf_command (char *arg, int from_tty)
              break;
            }
 
-         /* Handles decimal floating point values.  */
-         case decfloat_arg:
+         /* Handles decimal floating values.  */
+       case decfloat_arg:
            {
-             char *eos;
-             char decstr[MAX_DECIMAL_STRING];
-             unsigned int dfp_len = TYPE_LENGTH (value_type (val_args[i]));
-             unsigned char *dfp_value_ptr = (unsigned char *) value_contents_all (val_args[i])
-                                      + value_offset (val_args[i]);
-
+             const gdb_byte *param_ptr = value_contents (val_args[i]);
 #if defined (PRINTF_HAS_DECFLOAT)
-             printf_filtered (current_substring, dfp_value_ptr);
+             /* If we have native support for Decimal floating
+                printing, handle it here.  */
+             printf_filtered (current_substring, param_ptr);
 #else
-             if (TYPE_CODE (value_type (val_args[i])) != TYPE_CODE_DECFLOAT)
-               error (_("Cannot convert parameter to decfloat."));
 
              /* As a workaround until vasprintf has native support for DFP
-                we convert the DFP values to string and print them using
-                the %s format specifier.  */
-             decimal_to_string (dfp_value_ptr, dfp_len, decstr);
+              we convert the DFP values to string and print them using
+              the %s format specifier.  */
+
+             char *eos, *sos;
+             int nnull_chars = 0;
+
+             /* Parameter data.  */
+             struct type *param_type = value_type (val_args[i]);
+             unsigned int param_len = TYPE_LENGTH (param_type);
+
+             /* DFP output data.  */
+             struct value *dfp_value = NULL;
+             gdb_byte *dfp_ptr;
+             int dfp_len = 16;
+             gdb_byte dec[16];
+             struct type *dfp_type = NULL;
+             char decstr[MAX_DECIMAL_STRING];
 
              /* Points to the end of the string so that we can go back
-                and check for DFP format specifiers.  */
+                and check for DFP length modifiers.  */
              eos = current_substring + strlen (current_substring);
 
-             /* Replace %H, %D and %DD with %s's.  */
-             while (*--eos != '%')
-               if (*eos == 'D' && *(eos - 1) == 'D')
-                 {
-                   *(eos - 1) = 's';
-
-                   /* If we've found a %DD format specifier we need to go
-                      through the whole string pulling back one character
-                      since this format specifier has two chars.  */
-                   while (eos < last_arg)
-                     {
-                       *eos = *(eos + 1);
-                       eos++;
-                     }
-                 }
-               else if (*eos == 'D' || *eos == 'H')
-                 *eos = 's';
+             /* Look for the float/double format specifier.  */
+             while (*eos != 'f' && *eos != 'e' && *eos != 'E'
+                    && *eos != 'g' && *eos != 'G')
+                 eos--;
+
+             sos = eos;
+
+             /* Search for the '%' char and extract the size and type of
+                the output decimal value based on its modifiers
+                (%Hf, %Df, %DDf).  */
+             while (*--sos != '%')
+               {
+                 if (*sos == 'H')
+                   {
+                     dfp_len = 4;
+                     dfp_type = builtin_type (current_gdbarch)->builtin_decfloat;
+                   }
+                 else if (*sos == 'D' && *(sos - 1) == 'D')
+                   {
+                     dfp_len = 16;
+                     dfp_type = builtin_type (current_gdbarch)->builtin_declong;
+                     sos--;
+                   }
+                 else
+                   {
+                     dfp_len = 8;
+                     dfp_type = builtin_type (current_gdbarch)->builtin_decdouble;
+                   }
+               }
+
+             /* Replace %Hf, %Df and %DDf with %s's.  */
+             *++sos = 's';
+
+             /* Go through the whole format string and pull the correct
+                number of chars back to compensate for the change in the
+                format specifier.  */
+             while (nnull_chars < nargs - i)
+               {
+                 if (*eos == '\0')
+                   nnull_chars++;
+
+                 *++sos = *++eos;
+               }
+
+             /* Conversion between different DFP types.  */
+             if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
+               decimal_convert (param_ptr, param_len, dec, dfp_len);
+             else
+               /* If this is a non-trivial conversion, just output 0.
+                  A correct converted value can be displayed by explicitly
+                  casting to a DFP type.  */
+               decimal_from_string (dec, dfp_len, "0");
+
+             dfp_value = value_from_decfloat (dfp_type, dec);
+
+             dfp_ptr = (gdb_byte *) value_contents (dfp_value);
+
+             decimal_to_string (dfp_ptr, dfp_len, decstr);
 
              /* Print the DFP value.  */
              printf_filtered (current_substring, decstr);
+
              break;
 #endif
            }
This page took 0.029676 seconds and 4 git commands to generate.