Merge branch 'vendor/GDB'
[dragonfly.git] / contrib / gdb-7 / gdb / charset.c
index 7469111..6301c5e 100644 (file)
@@ -1,6 +1,6 @@
 /* Character set conversion support for GDB.
 
-   Copyright (C) 2001, 2003, 2007, 2008, 2009, 2010
+   Copyright (C) 2001, 2003, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 #undef iconv_t
 #define iconv_t int
 #undef iconv_open
+#define iconv_open phony_iconv_open
 #undef iconv
+#define iconv phony_iconv
 #undef iconv_close
+#define iconv_close phony_iconv_close
 
 #undef ICONV_CONST
 #define ICONV_CONST const
 #endif
 
 iconv_t
-iconv_open (const char *to, const char *from)
+phony_iconv_open (const char *to, const char *from)
 {
   /* We allow conversions from UTF-32BE, wchar_t, and the host charset.
      We allow conversions to wchar_t and the host charset.  */
@@ -122,14 +125,14 @@ iconv_open (const char *to, const char *from)
 }
 
 int
-iconv_close (iconv_t arg)
+phony_iconv_close (iconv_t arg)
 {
   return 0;
 }
 
 size_t
-iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
-       char **outbuf, size_t *outbytesleft)
+phony_iconv (iconv_t utf_flag, const char **inbuf, size_t *inbytesleft,
+            char **outbuf, size_t *outbytesleft)
 {
   if (utf_flag)
     {
@@ -235,8 +238,10 @@ show_target_charset_name (struct ui_file *file, int from_tty,
 
 static const char *target_wide_charset_name = "auto";
 static void
-show_target_wide_charset_name (struct ui_file *file, int from_tty,
-                              struct cmd_list_element *c, const char *value)
+show_target_wide_charset_name (struct ui_file *file, 
+                              int from_tty,
+                              struct cmd_list_element *c, 
+                              const char *value)
 {
   if (!strcmp (value, "auto"))
     fprintf_filtered (file,
@@ -319,13 +324,13 @@ validate (struct gdbarch *gdbarch)
 
   desc = iconv_open (target_wide_cset, host_cset);
   if (desc == (iconv_t) -1)
-    error ("Cannot convert between character sets `%s' and `%s'",
+    error (_("Cannot convert between character sets `%s' and `%s'"),
           target_wide_cset, host_cset);
   iconv_close (desc);
 
   desc = iconv_open (target_cset, host_cset);
   if (desc == (iconv_t) -1)
-    error ("Cannot convert between character sets `%s' and `%s'",
+    error (_("Cannot convert between character sets `%s' and `%s'"),
           target_cset, host_cset);
   iconv_close (desc);
 
@@ -335,9 +340,10 @@ validate (struct gdbarch *gdbarch)
 
 /* This is the sfunc for the 'set charset' command.  */
 static void
-set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
+set_charset_sfunc (char *charset, int from_tty, 
+                  struct cmd_list_element *c)
 {
-  /* CAREFUL: set the target charset here as well. */
+  /* CAREFUL: set the target charset here as well.  */
   target_charset_name = host_charset_name;
   validate (get_current_arch ());
 }
@@ -369,12 +375,14 @@ set_target_wide_charset_sfunc (char *charset, int from_tty,
 
 /* sfunc for the 'show charset' command.  */
 static void
-show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c,
+show_charset (struct ui_file *file, int from_tty, 
+             struct cmd_list_element *c,
              const char *name)
 {
   show_host_charset_name (file, from_tty, c, host_charset_name);
   show_target_charset_name (file, from_tty, c, target_charset_name);
-  show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name);
+  show_target_wide_charset_name (file, from_tty, c, 
+                                target_wide_charset_name);
 }
 
 \f
@@ -512,7 +520,7 @@ convert_between_encodings (const char *from, const char *to,
   if (!strcmp (from, "wchar_t"))
     {
       if (strcmp (to, host_charset ()))
-       perror_with_name ("Converting character sets");
+       perror_with_name (_("Converting character sets"));
       cleanups = NULL; /* silence gcc complaints */
       use_wctomb = 1;
     }
@@ -520,7 +528,7 @@ convert_between_encodings (const char *from, const char *to,
     {
       desc = iconv_open (to, from);
       if (desc == (iconv_t) -1)
-       perror_with_name ("Converting character sets");
+       perror_with_name (_("Converting character sets"));
       cleanups = make_cleanup (cleanup_iconv, &desc);
     }
 
@@ -560,8 +568,8 @@ convert_between_encodings (const char *from, const char *to,
 
                /* Invalid input sequence.  */
                if (translit == translit_none)
-                 error (_("Could not convert character to `%s' character set"),
-                        to);
+                 error (_("Could not convert character "
+                          "to `%s' character set"), to);
 
                /* We emit escape sequence for the bytes, skip them,
                   and try again.  */
@@ -591,7 +599,8 @@ convert_between_encodings (const char *from, const char *to,
              break;
 
            default:
-             perror_with_name ("Internal error while converting character sets");
+             perror_with_name (_("Internal error while "
+                                 "converting character sets"));
            }
        }
     }
@@ -627,15 +636,15 @@ struct wchar_iterator
 
 /* Create a new iterator.  */
 struct wchar_iterator *
-make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
-                    size_t width)
+make_wchar_iterator (const gdb_byte *input, size_t bytes, 
+                    const char *charset, size_t width)
 {
   struct wchar_iterator *result;
   iconv_t desc;
 
   desc = iconv_open (host_charset (), charset);
   if (desc == (iconv_t) -1)
-    perror_with_name ("Converting character sets");
+    perror_with_name (_("Converting character sets"));
 
   result = XNEW (struct wchar_iterator);
   result->desc = desc;
@@ -732,7 +741,8 @@ wchar_iterate (struct wchar_iterator *iter,
                  return 0;
 
                default:
-                 perror_with_name ("Internal error while converting character sets");
+                 perror_with_name (_("Internal error while "
+                                     "converting character sets"));
                }
            }
 
@@ -751,7 +761,8 @@ wchar_iterate (struct wchar_iterator *iter,
 
       /* This must never happen: we just converted to a valid charset! */
       if (r < 0)
-       perror_with_name ("Internal error while converting character sets");
+       perror_with_name (_("Internal error while "
+                           "converting character sets"));
 
       /* NUL bytes are alright */
       if (r == 0)
@@ -860,9 +871,9 @@ find_charset_names (void)
   int fail = 1;
   struct gdb_environ *iconv_env;
 
-  /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is not
-     a tty.  We need to recognize it and ignore it.  This text is subject
-     to translation, so force LANGUAGE=C.  */
+  /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is
+     not a tty.  We need to recognize it and ignore it.  This text is
+     subject to translation, so force LANGUAGE=C.  */
   iconv_env = make_environ ();
   init_environ (iconv_env);
   set_in_environ (iconv_env, "LANGUAGE", "C");
@@ -911,8 +922,8 @@ find_charset_names (void)
          buf[len] = '\0';
 
          /* libiconv will print multiple entries per line, separated
-            by spaces.  Older iconvs will print multiple entries per line,
-            indented by two spaces, and separated by ", "
+            by spaces.  Older iconvs will print multiple entries per
+            line, indented by two spaces, and separated by ", "
             (i.e. the human readable form).  */
          start = buf;
          while (1)
@@ -981,6 +992,72 @@ default_auto_wide_charset (void)
   return GDB_DEFAULT_TARGET_WIDE_CHARSET;
 }
 
+
+#ifdef USE_INTERMEDIATE_ENCODING_FUNCTION
+/* Macro used for UTF or UCS endianness suffix.  */
+#if WORDS_BIGENDIAN
+#define ENDIAN_SUFFIX "BE"
+#else
+#define ENDIAN_SUFFIX "LE"
+#endif
+
+/* The code below serves to generate a compile time error if
+   gdb_wchar_t type is not of size 2 nor 4, despite the fact that
+   macro __STDC_ISO_10646__ is defined.
+   This is better than a gdb_assert call, because GDB cannot handle
+   strings correctly if this size is different.  */
+
+extern char your_gdb_wchar_t_is_bogus[(sizeof (gdb_wchar_t) == 2
+                                      || sizeof (gdb_wchar_t) == 4)
+                                     ? 1 : -1];
+
+/* intermediate_encoding returns the charset unsed internally by
+   GDB to convert between target and host encodings. As the test above
+   compiled, sizeof (gdb_wchar_t) is either 2 or 4 bytes.
+   UTF-16/32 is tested first, UCS-2/4 is tested as a second option,
+   otherwise an error is generated.  */
+
+const char *
+intermediate_encoding (void)
+{
+  iconv_t desc;
+  static const char *stored_result = NULL;
+  char *result;
+  int i;
+
+  if (stored_result)
+    return stored_result;
+  result = xstrprintf ("UTF-%d%s", (int) (sizeof (gdb_wchar_t) * 8),
+                      ENDIAN_SUFFIX);
+  /* Check that the name is supported by iconv_open.  */
+  desc = iconv_open (result, host_charset ());
+  if (desc != (iconv_t) -1)
+    {
+      iconv_close (desc);
+      stored_result = result;
+      return result;
+    }
+  /* Not valid, free the allocated memory.  */
+  xfree (result);
+  /* Second try, with UCS-2 type.  */
+  result = xstrprintf ("UCS-%d%s", (int) sizeof (gdb_wchar_t),
+                      ENDIAN_SUFFIX);
+  /* Check that the name is supported by iconv_open.  */
+  desc = iconv_open (result, host_charset ());
+  if (desc != (iconv_t) -1)
+    {
+      iconv_close (desc);
+      stored_result = result;
+      return result;
+    }
+  /* Not valid, free the allocated memory.  */
+  xfree (result);
+  /* No valid charset found, generate error here.  */
+  error (_("Unable to find a vaild charset for string conversions"));
+}
+
+#endif /* USE_INTERMEDIATE_ENCODING_FUNCTION */
+
 void
 _initialize_charset (void)
 {
@@ -999,15 +1076,16 @@ _initialize_charset (void)
      leak a little memory, if the user later changes the host charset,
      but that doesn't matter much.  */
   auto_host_charset_name = xstrdup (nl_langinfo (CODESET));
-  /* Solaris will return `646' here -- but the Solaris iconv then
-     does not accept this.  Darwin (and maybe FreeBSD) may return "" here,
+  /* Solaris will return `646' here -- but the Solaris iconv then does
+     not accept this.  Darwin (and maybe FreeBSD) may return "" here,
      which GNU libiconv doesn't like (infinite loop).  */
   if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
     auto_host_charset_name = "ASCII";
   auto_target_charset_name = auto_host_charset_name;
 #elif defined (USE_WIN32API)
   {
-    static char w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
+    /* "CP" + x<=5 digits + paranoia.  */
+    static char w32_host_default_charset[16];
 
     snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
              "CP%d", GetACP());
@@ -1062,8 +1140,8 @@ To see a list of the character sets GDB supports, type `set target-charset'<TAB>
                        _("\
 Set the target wide character set."), _("\
 Show the target wide character set."), _("\
-The `target wide character set' is the one used by the program being debugged.\n\
-In particular it is the encoding used by `wchar_t'.\n\
+The `target wide character set' is the one used by the program being debugged.\
+\nIn particular it is the encoding used by `wchar_t'.\n\
 GDB translates characters and strings between the host and target\n\
 character sets as needed.\n\
 To see a list of the character sets GDB supports, type\n\