gdb/
[deliverable/binutils-gdb.git] / gdb / c-lang.c
index ad770bfca491135c3475265cc2105f5de4436e36..84830be774d33447e9ce185265d102933a12de24 100644 (file)
@@ -1,7 +1,7 @@
 /* C language support routines for GDB, the GNU debugger.
 
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003,
-   2004, 2005, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1992-1996, 1998-2000, 2002-2005, 2007-2012 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -87,7 +87,7 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch,
      that would do the wrong thing.  */
   while (elttype)
     {
-      char *name = TYPE_NAME (elttype);
+      const char *name = TYPE_NAME (elttype);
 
       if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name)
        {
@@ -140,123 +140,6 @@ classify_type (struct type *elttype, struct gdbarch *gdbarch,
   return result;
 }
 
-/* Return true if print_wchar can display W without resorting to a
-   numeric escape, false otherwise.  */
-
-static int
-wchar_printable (gdb_wchar_t w)
-{
-  return (gdb_iswprint (w)
-         || w == LCST ('\a') || w == LCST ('\b')
-         || w == LCST ('\f') || w == LCST ('\n')
-         || w == LCST ('\r') || w == LCST ('\t')
-         || w == LCST ('\v'));
-}
-
-/* A helper function that converts the contents of STRING to wide
-   characters and then appends them to OUTPUT.  */
-
-static void
-append_string_as_wide (const char *string,
-                      struct obstack *output)
-{
-  for (; *string; ++string)
-    {
-      gdb_wchar_t w = gdb_btowc (*string);
-      obstack_grow (output, &w, sizeof (gdb_wchar_t));
-    }
-}
-
-/* Print a wide character W to OUTPUT.  ORIG is a pointer to the
-   original (target) bytes representing the character, ORIG_LEN is the
-   number of valid bytes.  WIDTH is the number of bytes in a base
-   characters of the type.  OUTPUT is an obstack to which wide
-   characters are emitted.  QUOTER is a (narrow) character indicating
-   the style of quotes surrounding the character to be printed.
-   NEED_ESCAPE is an in/out flag which is used to track numeric
-   escapes across calls.  */
-
-static void
-print_wchar (gdb_wint_t w, const gdb_byte *orig,
-            int orig_len, int width,
-            enum bfd_endian byte_order,
-            struct obstack *output,
-            int quoter, int *need_escapep)
-{
-  int need_escape = *need_escapep;
-
-  *need_escapep = 0;
-  if (gdb_iswprint (w) && (!need_escape || (!gdb_iswdigit (w)
-                                           && w != LCST ('8')
-                                           && w != LCST ('9'))))
-    {
-      gdb_wchar_t wchar = w;
-
-      if (w == gdb_btowc (quoter) || w == LCST ('\\'))
-       obstack_grow_wstr (output, LCST ("\\"));
-      obstack_grow (output, &wchar, sizeof (gdb_wchar_t));
-    }
-  else
-    {
-      switch (w)
-       {
-       case LCST ('\a'):
-         obstack_grow_wstr (output, LCST ("\\a"));
-         break;
-       case LCST ('\b'):
-         obstack_grow_wstr (output, LCST ("\\b"));
-         break;
-       case LCST ('\f'):
-         obstack_grow_wstr (output, LCST ("\\f"));
-         break;
-       case LCST ('\n'):
-         obstack_grow_wstr (output, LCST ("\\n"));
-         break;
-       case LCST ('\r'):
-         obstack_grow_wstr (output, LCST ("\\r"));
-         break;
-       case LCST ('\t'):
-         obstack_grow_wstr (output, LCST ("\\t"));
-         break;
-       case LCST ('\v'):
-         obstack_grow_wstr (output, LCST ("\\v"));
-         break;
-       default:
-         {
-           int i;
-
-           for (i = 0; i + width <= orig_len; i += width)
-             {
-               char octal[30];
-               ULONGEST value;
-
-               value = extract_unsigned_integer (&orig[i], width,
-                                                 byte_order);
-               /* If the value fits in 3 octal digits, print it that
-                  way.  Otherwise, print it as a hex escape.  */
-               if (value <= 0777)
-                 sprintf (octal, "\\%.3o", (int) (value & 0777));
-               else
-                 sprintf (octal, "\\x%lx", (long) value);
-               append_string_as_wide (octal, output);
-             }
-           /* If we somehow have extra bytes, print them now.  */
-           while (i < orig_len)
-             {
-               char octal[5];
-
-               sprintf (octal, "\\%.3o", orig[i] & 0xff);
-               append_string_as_wide (octal, output);
-               ++i;
-             }
-
-           *need_escapep = 1;
-         }
-         break;
-       }
-    }
-}
-
 /* Print the character C on STREAM as part of the contents of a
    literal string whose delimiter is QUOTER.  Note that that format
    for printing characters and strings is language specific.  */
@@ -265,85 +148,10 @@ void
 c_emit_char (int c, struct type *type,
             struct ui_file *stream, int quoter)
 {
-  enum bfd_endian byte_order
-    = gdbarch_byte_order (get_type_arch (type));
-  struct obstack wchar_buf, output;
-  struct cleanup *cleanups;
   const char *encoding;
-  gdb_byte *buf;
-  struct wchar_iterator *iter;
-  int need_escape = 0;
 
   classify_type (type, get_type_arch (type), &encoding);
-
-  buf = alloca (TYPE_LENGTH (type));
-  pack_long (buf, type, c);
-
-  iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
-                             encoding, TYPE_LENGTH (type));
-  cleanups = make_cleanup_wchar_iterator (iter);
-
-  /* This holds the printable form of the wchar_t data.  */
-  obstack_init (&wchar_buf);
-  make_cleanup_obstack_free (&wchar_buf);
-
-  while (1)
-    {
-      int num_chars;
-      gdb_wchar_t *chars;
-      const gdb_byte *buf;
-      size_t buflen;
-      int print_escape = 1;
-      enum wchar_iterate_result result;
-
-      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
-      if (num_chars < 0)
-       break;
-      if (num_chars > 0)
-       {
-         /* If all characters are printable, print them.  Otherwise,
-            we're going to have to print an escape sequence.  We
-            check all characters because we want to print the target
-            bytes in the escape sequence, and we don't know character
-            boundaries there.  */
-         int i;
-
-         print_escape = 0;
-         for (i = 0; i < num_chars; ++i)
-           if (!wchar_printable (chars[i]))
-             {
-               print_escape = 1;
-               break;
-             }
-
-         if (!print_escape)
-           {
-             for (i = 0; i < num_chars; ++i)
-               print_wchar (chars[i], buf, buflen,
-                            TYPE_LENGTH (type), byte_order,
-                            &wchar_buf, quoter, &need_escape);
-           }
-       }
-
-      /* This handles the NUM_CHARS == 0 case as well.  */
-      if (print_escape)
-       print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
-                    byte_order, &wchar_buf, quoter, &need_escape);
-    }
-
-  /* The output in the host encoding.  */
-  obstack_init (&output);
-  make_cleanup_obstack_free (&output);
-
-  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
-                            obstack_base (&wchar_buf),
-                            obstack_object_size (&wchar_buf),
-                            1, &output, translit_char);
-  obstack_1grow (&output, '\0');
-
-  fputs_filtered (obstack_base (&output), stream);
-
-  do_cleanups (cleanups);
+  generic_emit_char (c, type, stream, quoter, encoding);
 }
 
 void
@@ -385,43 +193,21 @@ c_printstr (struct ui_file *stream, struct type *type,
            const char *user_encoding, int force_ellipses,
            const struct value_print_options *options)
 {
+  enum c_string_type str_type;
+  const char *type_encoding;
+  const char *encoding;
+
   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
   unsigned int i;
   unsigned int things_printed = 0;
   int in_quotes = 0;
   int need_comma = 0;
-  int width = TYPE_LENGTH (type);
   struct obstack wchar_buf, output;
   struct cleanup *cleanup;
-  enum c_string_type str_type;
-  const char *type_encoding;
-  const char *encoding;
   struct wchar_iterator *iter;
   int finished = 0;
   int need_escape = 0;
 
-  if (length == -1)
-    {
-      unsigned long current_char = 1;
-
-      for (i = 0; current_char; ++i)
-       {
-         QUIT;
-         current_char = extract_unsigned_integer (string + i * width,
-                                                  width, byte_order);
-       }
-      length = i;
-    }
-
-  /* If the string was not truncated due to `set print elements', and
-     the last byte of it is a null, we don't print that, in
-     traditional C style.  */
-  if (!force_ellipses
-      && length > 0
-      && (extract_unsigned_integer (string + (length - 1) * width,
-                                   width, byte_order) == 0))
-    length--;
-
   str_type = (classify_type (type, get_type_arch (type), &type_encoding)
              & ~C_CHAR);
   switch (str_type)
@@ -439,193 +225,10 @@ c_printstr (struct ui_file *stream, struct type *type,
       break;
     }
 
-  encoding = (user_encoding && *user_encoding)
-    ? user_encoding : type_encoding;
-
-  if (length == 0)
-    {
-      fputs_filtered ("\"\"", stream);
-      return;
-    }
-
-  /* Arrange to iterate over the characters, in wchar_t form.  */
-  iter = make_wchar_iterator (string, length * width, encoding, width);
-  cleanup = make_cleanup_wchar_iterator (iter);
-
-  /* WCHAR_BUF is the obstack we use to represent the string in
-     wchar_t form.  */
-  obstack_init (&wchar_buf);
-  make_cleanup_obstack_free (&wchar_buf);
-
-  while (!finished && things_printed < options->print_max)
-    {
-      int num_chars;
-      enum wchar_iterate_result result;
-      gdb_wchar_t *chars;
-      const gdb_byte *buf;
-      size_t buflen;
-
-      QUIT;
-
-      if (need_comma)
-       {
-         obstack_grow_wstr (&wchar_buf, LCST (", "));
-         need_comma = 0;
-       }
-
-      num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
-      /* We only look at repetitions when we were able to convert a
-        single character in isolation.  This makes the code simpler
-        and probably does the sensible thing in the majority of
-        cases.  */
-      while (num_chars == 1 && things_printed < options->print_max)
-       {
-         /* Count the number of repetitions.  */
-         unsigned int reps = 0;
-         gdb_wchar_t current_char = chars[0];
-         const gdb_byte *orig_buf = buf;
-         int orig_len = buflen;
-
-         if (need_comma)
-           {
-             obstack_grow_wstr (&wchar_buf, LCST (", "));
-             need_comma = 0;
-           }
-
-         while (num_chars == 1 && current_char == chars[0])
-           {
-             num_chars = wchar_iterate (iter, &result, &chars,
-                                        &buf, &buflen);
-             ++reps;
-           }
-
-         /* Emit CURRENT_CHAR according to the repetition count and
-            options.  */
-         if (reps > options->repeat_count_threshold)
-           {
-             if (in_quotes)
-               {
-                 if (options->inspect_it)
-                   obstack_grow_wstr (&wchar_buf, LCST ("\\\", "));
-                 else
-                   obstack_grow_wstr (&wchar_buf, LCST ("\", "));
-                 in_quotes = 0;
-               }
-             obstack_grow_wstr (&wchar_buf, LCST ("'"));
-             need_escape = 0;
-             print_wchar (current_char, orig_buf, orig_len, width,
-                          byte_order, &wchar_buf, '\'', &need_escape);
-             obstack_grow_wstr (&wchar_buf, LCST ("'"));
-             {
-               /* Painful gyrations.  */
-               int j;
-               char *s = xstrprintf (_(" <repeats %u times>"), reps);
-
-               for (j = 0; s[j]; ++j)
-                 {
-                   gdb_wchar_t w = gdb_btowc (s[j]);
-                   obstack_grow (&wchar_buf, &w, sizeof (gdb_wchar_t));
-                 }
-               xfree (s);
-             }
-             things_printed += options->repeat_count_threshold;
-             need_comma = 1;
-           }
-         else
-           {
-             /* Saw the character one or more times, but fewer than
-                the repetition threshold.  */
-             if (!in_quotes)
-               {
-                 if (options->inspect_it)
-                   obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
-                 else
-                   obstack_grow_wstr (&wchar_buf, LCST ("\""));
-                 in_quotes = 1;
-                 need_escape = 0;
-               }
-
-             while (reps-- > 0)
-               {
-                 print_wchar (current_char, orig_buf,
-                              orig_len, width,
-                              byte_order, &wchar_buf,
-                              '"', &need_escape);
-                 ++things_printed;
-               }
-           }
-       }
-
-      /* NUM_CHARS and the other outputs from wchar_iterate are valid
-        here regardless of which branch was taken above.  */
-      if (num_chars < 0)
-       {
-         /* Hit EOF.  */
-         finished = 1;
-         break;
-       }
-
-      switch (result)
-       {
-       case wchar_iterate_invalid:
-         if (!in_quotes)
-           {
-             if (options->inspect_it)
-               obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
-             else
-               obstack_grow_wstr (&wchar_buf, LCST ("\""));
-             in_quotes = 1;
-           }
-         need_escape = 0;
-         print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
-                      &wchar_buf, '"', &need_escape);
-         break;
-
-       case wchar_iterate_incomplete:
-         if (in_quotes)
-           {
-             if (options->inspect_it)
-               obstack_grow_wstr (&wchar_buf, LCST ("\\\","));
-             else
-               obstack_grow_wstr (&wchar_buf, LCST ("\","));
-             in_quotes = 0;
-           }
-         obstack_grow_wstr (&wchar_buf,
-                            LCST (" <incomplete sequence "));
-         print_wchar (gdb_WEOF, buf, buflen, width,
-                      byte_order, &wchar_buf,
-                      0, &need_escape);
-         obstack_grow_wstr (&wchar_buf, LCST (">"));
-         finished = 1;
-         break;
-       }
-    }
-
-  /* Terminate the quotes if necessary.  */
-  if (in_quotes)
-    {
-      if (options->inspect_it)
-       obstack_grow_wstr (&wchar_buf, LCST ("\\\""));
-      else
-       obstack_grow_wstr (&wchar_buf, LCST ("\""));
-    }
-
-  if (force_ellipses || !finished)
-    obstack_grow_wstr (&wchar_buf, LCST ("..."));
-
-  /* OUTPUT is where we collect `char's for printing.  */
-  obstack_init (&output);
-  make_cleanup_obstack_free (&output);
-
-  convert_between_encodings (INTERMEDIATE_ENCODING, host_charset (),
-                            obstack_base (&wchar_buf),
-                            obstack_object_size (&wchar_buf),
-                            1, &output, translit_char);
-  obstack_1grow (&output, '\0');
+  encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;
 
-  fputs_filtered (obstack_base (&output), stream);
-
-  do_cleanups (cleanup);
+  generic_printstr (stream, type, string, length, encoding, force_ellipses,
+                   '"', 1, options);
 }
 
 /* Obtain a C string from the inferior storing it in a newly allocated
@@ -978,6 +581,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        struct value *result;
        enum c_string_type dest_type;
        const char *dest_charset;
+       int satisfy_expected = 0;
 
        obstack_init (&output);
        cleanup = make_cleanup_obstack_free (&output);
@@ -1014,6 +618,22 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        /* Ensure TYPE_LENGTH is valid for TYPE.  */
        check_typedef (type);
 
+       /* If the caller expects an array of some integral type,
+          satisfy them.  If something odder is expected, rely on the
+          caller to cast.  */
+       if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+         {
+           struct type *element_type
+             = check_typedef (TYPE_TARGET_TYPE (expect_type));
+
+           if (TYPE_CODE (element_type) == TYPE_CODE_INT
+               || TYPE_CODE (element_type) == TYPE_CODE_CHAR)
+             {
+               type = element_type;
+               satisfy_expected = 1;
+             }
+         }
+
        dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
 
        ++*pos;
@@ -1036,7 +656,9 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        if (noside == EVAL_SKIP)
          {
            /* Return a dummy value of the appropriate type.  */
-           if ((dest_type & C_CHAR) != 0)
+           if (expect_type != NULL)
+             result = allocate_value (expect_type);
+           else if ((dest_type & C_CHAR) != 0)
              result = allocate_value (type);
            else
              result = value_cstring ("", 0, type);
@@ -1061,9 +683,30 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
            /* Write the terminating character.  */
            for (i = 0; i < TYPE_LENGTH (type); ++i)
              obstack_1grow (&output, 0);
-           result = value_cstring (obstack_base (&output),
-                                   obstack_object_size (&output),
-                                   type);
+
+           if (satisfy_expected)
+             {
+               LONGEST low_bound, high_bound;
+               int element_size = TYPE_LENGTH (type);
+
+               if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
+                                        &low_bound, &high_bound) < 0)
+                 {
+                   low_bound = 0;
+                   high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+                 }
+               if (obstack_object_size (&output) / element_size
+                   > (high_bound - low_bound + 1))
+                 error (_("Too many array elements"));
+
+               result = allocate_value (expect_type);
+               memcpy (value_contents_raw (result), obstack_base (&output),
+                       obstack_object_size (&output));
+             }
+           else
+             result = value_cstring (obstack_base (&output),
+                                     obstack_object_size (&output),
+                                     type);
          }
        do_cleanups (cleanup);
        return result;
@@ -1188,7 +831,6 @@ const struct language_defn c_language_defn =
   "c",                         /* Language name */
   language_c,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
@@ -1203,6 +845,7 @@ const struct language_defn c_language_defn =
   c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
@@ -1219,6 +862,8 @@ const struct language_defn c_language_defn =
   default_print_array_index,
   default_pass_by_reference,
   c_get_string,
+  NULL,                                /* la_get_symbol_name_cmp */
+  iterate_over_symbols,
   LANG_MAGIC
 };
 
@@ -1309,7 +954,6 @@ const struct language_defn cplus_language_defn =
   "c++",                       /* Language name */
   language_cplus,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
@@ -1324,6 +968,7 @@ const struct language_defn cplus_language_defn =
   c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
+  default_read_var_value,      /* la_read_var_value */
   cplus_skip_trampoline,       /* Language specific skip_trampoline */
   "this",                       /* name_of_this */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
@@ -1340,6 +985,8 @@ const struct language_defn cplus_language_defn =
   default_print_array_index,
   cp_pass_by_reference,
   c_get_string,
+  NULL,                                /* la_get_symbol_name_cmp */
+  iterate_over_symbols,
   LANG_MAGIC
 };
 
@@ -1348,7 +995,6 @@ const struct language_defn asm_language_defn =
   "asm",                       /* Language name */
   language_asm,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
@@ -1363,6 +1009,7 @@ const struct language_defn asm_language_defn =
   c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
@@ -1379,6 +1026,8 @@ const struct language_defn asm_language_defn =
   default_print_array_index,
   default_pass_by_reference,
   c_get_string,
+  NULL,                                /* la_get_symbol_name_cmp */
+  iterate_over_symbols,
   LANG_MAGIC
 };
 
@@ -1392,7 +1041,6 @@ const struct language_defn minimal_language_defn =
   "minimal",                   /* Language name */
   language_minimal,
   range_check_off,
-  type_check_off,
   case_sensitive_on,
   array_row_major,
   macro_expansion_c,
@@ -1407,6 +1055,7 @@ const struct language_defn minimal_language_defn =
   c_print_typedef,             /* Print a typedef using appropriate syntax */
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
+  default_read_var_value,      /* la_read_var_value */
   NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
@@ -1423,6 +1072,8 @@ const struct language_defn minimal_language_defn =
   default_print_array_index,
   default_pass_by_reference,
   c_get_string,
+  NULL,                                /* la_get_symbol_name_cmp */
+  iterate_over_symbols,
   LANG_MAGIC
 };
 
This page took 0.029896 seconds and 4 git commands to generate.