gdb
authorTom Tromey <tromey@redhat.com>
Fri, 5 Mar 2010 20:18:19 +0000 (20:18 +0000)
committerTom Tromey <tromey@redhat.com>
Fri, 5 Mar 2010 20:18:19 +0000 (20:18 +0000)
2010-03-05  Corinna Vinschen  <vinschen@redhat.com>
    Tom Tromey  <tromey@redhat.com>

* utils.c (host_char_to_target): Add 'gdbarch' argument.
(parse_escape): Likewise.
* python/py-utils.c (unicode_to_target_string): Update.
(unicode_to_target_python_string): Update.
(target_string_to_unicode): Update.
* printcmd.c (printf_command): Update.
* p-exp.y (yylex): Update.
* objc-exp.y (yylex): Update.
* mi/mi-parse.c: Include charset.h.
(mi_parse_escape): New function.
(mi_parse_argv): Use it.
* jv-exp.y (yylex): Update.
* i386-cygwin-tdep.c (i386_cygwin_auto_wide_charset): New
function.
(i386_cygwin_init_abi): Call set_gdbarch_auto_wide_charset.
* gdbarch.sh (auto_charset, auto_wide_charset): New.
* gdbarch.c: Rebuild.
* gdbarch.h: Rebuild.
* defs.h (parse_escape): Update.
* cli/cli-setshow.c: Include arch-utils.h.
(do_setshow_command): Update.
* cli/cli-cmds.c (echo_command): Update.
* charset.h (target_charset, target_wide_charset): Update.
* charset.c: Include arch-utils.h.
(target_charset_name): Default to "auto".
(target_wide_charset_name): Likewise.
(show_target_charset_name): Handle "auto".
(show_target_wide_charset_name): Likewise.
(be_le_arch): New global.
(set_be_le_names): Add 'gdbarch' argument.
(validate): Likewise.  Don't call set_be_le_names.
(set_charset_sfunc, set_host_charset_sfunc)
(set_target_charset_sfunc, set_target_wide_charset_sfunc):
Update.
(target_charset): Add 'gdbarch' argument.
(target_wide_charset): Likewise.  Remove 'byte_order' argument.
(auto_target_charset_name): New global.
(default_auto_charset, default_auto_wide_charset): New functions.
(_initialize_charset): Set auto_target_charset_name.  Allow "auto"
for target charsets.  Copy result of nl_langinfo.  Use GetACP if
USE_WIN32API.
* c-lang.c (charset_for_string_type): Add 'gdbarch' argument,
remove 'byte_order' argument.  Update.
(classify_type): Likewise.
(c_emit_char): Update.
(c_printchar): Update.
(c_printstr): Update.
(c_get_string): Update.
(evaluate_subexp_c): Update.
* arch-utils.h (default_auto_charset, default_auto_wide_charset):
Declare.
* python/python.c (gdbpy_target_charset): New function.
(gdbpy_target_wide_charset): Likewise.
(GdbMethods): Update.
* NEWS: Update.
gdb/doc
* gdb.texinfo (Basic Python): Document target_charset and
target_wide_charset.
gdb/testsuite
* gdb.python/py-prettyprint.py (pp_nullstr.to_string): Use
gdb.target_charset.
(pp_ns.to_string): Likewise.

25 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/arch-utils.h
gdb/c-lang.c
gdb/charset.c
gdb/charset.h
gdb/cli/cli-cmds.c
gdb/cli/cli-setshow.c
gdb/defs.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/i386-cygwin-tdep.c
gdb/jv-exp.y
gdb/mi/mi-parse.c
gdb/objc-exp.y
gdb/p-exp.y
gdb/printcmd.c
gdb/python/py-utils.c
gdb/python/python.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-prettyprint.py
gdb/utils.c

index d922c27..5b9f608 100644 (file)
@@ -1,3 +1,62 @@
+2010-03-05  Corinna Vinschen  <vinschen@redhat.com>
+           Tom Tromey  <tromey@redhat.com>
+
+       * utils.c (host_char_to_target): Add 'gdbarch' argument.
+       (parse_escape): Likewise.
+       * python/py-utils.c (unicode_to_target_string): Update.
+       (unicode_to_target_python_string): Update.
+       (target_string_to_unicode): Update.
+       * printcmd.c (printf_command): Update.
+       * p-exp.y (yylex): Update.
+       * objc-exp.y (yylex): Update.
+       * mi/mi-parse.c: Include charset.h.
+       (mi_parse_escape): New function.
+       (mi_parse_argv): Use it.
+       * jv-exp.y (yylex): Update.
+       * i386-cygwin-tdep.c (i386_cygwin_auto_wide_charset): New
+       function.
+       (i386_cygwin_init_abi): Call set_gdbarch_auto_wide_charset.
+       * gdbarch.sh (auto_charset, auto_wide_charset): New.
+       * gdbarch.c: Rebuild.
+       * gdbarch.h: Rebuild.
+       * defs.h (parse_escape): Update.
+       * cli/cli-setshow.c: Include arch-utils.h.
+       (do_setshow_command): Update.
+       * cli/cli-cmds.c (echo_command): Update.
+       * charset.h (target_charset, target_wide_charset): Update.
+       * charset.c: Include arch-utils.h.
+       (target_charset_name): Default to "auto".
+       (target_wide_charset_name): Likewise.
+       (show_target_charset_name): Handle "auto".
+       (show_target_wide_charset_name): Likewise.
+       (be_le_arch): New global.
+       (set_be_le_names): Add 'gdbarch' argument.
+       (validate): Likewise.  Don't call set_be_le_names.
+       (set_charset_sfunc, set_host_charset_sfunc)
+       (set_target_charset_sfunc, set_target_wide_charset_sfunc):
+       Update.
+       (target_charset): Add 'gdbarch' argument.
+       (target_wide_charset): Likewise.  Remove 'byte_order' argument.
+       (auto_target_charset_name): New global.
+       (default_auto_charset, default_auto_wide_charset): New functions.
+       (_initialize_charset): Set auto_target_charset_name.  Allow "auto"
+       for target charsets.  Copy result of nl_langinfo.  Use GetACP if
+       USE_WIN32API.
+       * c-lang.c (charset_for_string_type): Add 'gdbarch' argument,
+       remove 'byte_order' argument.  Update.
+       (classify_type): Likewise.
+       (c_emit_char): Update.
+       (c_printchar): Update.
+       (c_printstr): Update.
+       (c_get_string): Update.
+       (evaluate_subexp_c): Update.
+       * arch-utils.h (default_auto_charset, default_auto_wide_charset):
+       Declare.
+       * python/python.c (gdbpy_target_charset): New function.
+       (gdbpy_target_wide_charset): Likewise.
+       (GdbMethods): Update.
+       * NEWS: Update.
+
 2010-03-05  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * symfile.c (build_section_addr_info_from_objfile): Do not mask
index e8c1935..7e33caa 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
 
 * Python scripting
 
-The GDB Python API now has access to symbols, symbol tables, and
-frame's code blocks.
+** The GDB Python API now has access to symbols, symbol tables, and
+   frame's code blocks.
+
+** New methods gdb.target_charset and gdb.target_wide_charset.
 
 * New targets
 
index d5d7f1d..dbeb67f 100644 (file)
@@ -162,4 +162,7 @@ extern int default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
 extern void default_remote_breakpoint_from_pc (struct gdbarch *,
                                               CORE_ADDR *pcptr, int *kindptr);
 
+extern const char *default_auto_charset (void);
+extern const char *default_auto_wide_charset (void);
+
 #endif
index d620881..fefd675 100644 (file)
@@ -43,23 +43,23 @@ extern void _initialize_c_language (void);
 
 static const char *
 charset_for_string_type (enum c_string_type str_type,
-                        enum bfd_endian byte_order)
+                        struct gdbarch *gdbarch)
 {
   switch (str_type & ~C_CHAR)
     {
     case C_STRING:
-      return target_charset ();
+      return target_charset (gdbarch);
     case C_WIDE_STRING:
-      return target_wide_charset (byte_order);
+      return target_wide_charset (gdbarch);
     case C_STRING_16:
       /* FIXME: UTF-16 is not always correct.  */
-      if (byte_order == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
        return "UTF-16BE";
       else
        return "UTF-16LE";
     case C_STRING_32:
       /* FIXME: UTF-32 is not always correct.  */
-      if (byte_order == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
        return "UTF-32BE";
       else
        return "UTF-32LE";
@@ -73,7 +73,7 @@ charset_for_string_type (enum c_string_type str_type,
    characters of this type in target BYTE_ORDER to the host character set.  */
 
 static enum c_string_type
-classify_type (struct type *elttype, enum bfd_endian byte_order,
+classify_type (struct type *elttype, struct gdbarch *gdbarch,
               const char **encoding)
 {
   struct type *saved_type;
@@ -134,7 +134,7 @@ classify_type (struct type *elttype, enum bfd_endian byte_order,
 
  done:
   if (encoding)
-    *encoding = charset_for_string_type (result, byte_order);
+    *encoding = charset_for_string_type (result, gdbarch);
 
   return result;
 }
@@ -264,7 +264,7 @@ c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
   struct wchar_iterator *iter;
   int need_escape = 0;
 
-  classify_type (type, byte_order, &encoding);
+  classify_type (type, get_type_arch (type), &encoding);
 
   buf = alloca (TYPE_LENGTH (type));
   pack_long (buf, type, c);
@@ -340,7 +340,7 @@ c_printchar (int c, struct type *type, struct ui_file *stream)
 {
   enum c_string_type str_type;
 
-  str_type = classify_type (type, BFD_ENDIAN_UNKNOWN, NULL);
+  str_type = classify_type (type, get_type_arch (type), NULL);
   switch (str_type)
     {
     case C_CHAR:
@@ -396,7 +396,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
                                    width, byte_order) == 0))
     length--;
 
-  str_type = classify_type (type, byte_order, &type_encoding) & ~C_CHAR;
+  str_type = (classify_type (type, get_type_arch (type), &type_encoding)
+             & ~C_CHAR);
   switch (str_type)
     {
     case C_STRING:
@@ -659,7 +660,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
   if (! c_textual_element_type (element_type, 0))
     goto error;
   kind = classify_type (element_type,
-                       gdbarch_byte_order (get_type_arch (element_type)),
+                       get_type_arch (element_type),
                        charset);
   width = TYPE_LENGTH (element_type);
 
@@ -942,7 +943,6 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        struct value *result;
        enum c_string_type dest_type;
        const char *dest_charset;
-       enum bfd_endian byte_order;
 
        obstack_init (&output);
        cleanup = make_cleanup_obstack_free (&output);
@@ -979,8 +979,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        /* Ensure TYPE_LENGTH is valid for TYPE.  */
        check_typedef (type);
 
-       byte_order = gdbarch_byte_order (exp->gdbarch);
-       dest_charset = charset_for_string_type (dest_type, byte_order);
+       dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
 
        ++*pos;
        while (*pos < limit)
index 8977f27..9c1e7f4 100644 (file)
@@ -27,6 +27,7 @@
 #include "charset-list.h"
 #include "vec.h"
 #include "environ.h"
+#include "arch-utils.h"
 
 #include <stddef.h>
 #include "gdb_string.h"
@@ -213,22 +214,34 @@ show_host_charset_name (struct ui_file *file, int from_tty,
     fprintf_filtered (file, _("The host character set is \"%s\".\n"), value);
 }
 
-static const char *target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
+static const char *target_charset_name = "auto";
 static void
 show_target_charset_name (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("The target character set is \"%s\".\n"),
-                   value);
+  if (!strcmp (value, "auto"))
+    fprintf_filtered (file,
+                     _("The target character set is \"auto; "
+                       "currently %s\".\n"),
+                     gdbarch_auto_charset (get_current_arch ()));
+  else
+    fprintf_filtered (file, _("The target character set is \"%s\".\n"),
+                     value);
 }
 
-static const char *target_wide_charset_name = GDB_DEFAULT_TARGET_WIDE_CHARSET;
+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)
 {
-  fprintf_filtered (file, _("The target wide character set is \"%s\".\n"),
-                   value);
+  if (!strcmp (value, "auto"))
+    fprintf_filtered (file,
+                     _("The target wide character set is \"auto; "
+                       "currently %s\".\n"),
+                     gdbarch_auto_wide_charset (get_current_arch ()));
+  else
+    fprintf_filtered (file, _("The target wide character set is \"%s\".\n"),
+                     value);
 }
 
 static const char *default_charset_names[] =
@@ -245,21 +258,33 @@ static const char **charset_enum;
 static const char *target_wide_charset_be_name;
 static const char *target_wide_charset_le_name;
 
-/* A helper function for validate which sets the target wide big- and
-   little-endian character set names, if possible.  */
+/* The architecture for which the BE- and LE-names are valid.  */
+static struct gdbarch *be_le_arch;
+
+/* A helper function which sets the target wide big- and little-endian
+   character set names, if possible.  */
 
 static void
-set_be_le_names (void)
+set_be_le_names (struct gdbarch *gdbarch)
 {
   int i, len;
+  const char *target_wide;
+
+  if (be_le_arch == gdbarch)
+    return;
+  be_le_arch = gdbarch;
 
   target_wide_charset_le_name = NULL;
   target_wide_charset_be_name = NULL;
 
-  len = strlen (target_wide_charset_name);
+  target_wide = target_wide_charset_name;
+  if (!strcmp (target_wide, "auto"))
+    target_wide = gdbarch_auto_wide_charset (gdbarch);
+
+  len = strlen (target_wide);
   for (i = 0; charset_enum[i]; ++i)
     {
-      if (strncmp (target_wide_charset_name, charset_enum[i], len))
+      if (strncmp (target_wide, charset_enum[i], len))
        continue;
       if ((charset_enum[i][len] == 'B'
           || charset_enum[i][len] == 'L')
@@ -278,24 +303,29 @@ set_be_le_names (void)
    target-wide-charset', 'set charset' sfunc's.  */
 
 static void
-validate (void)
+validate (struct gdbarch *gdbarch)
 {
   iconv_t desc;
   const char *host_cset = host_charset ();
+  const char *target_cset = target_charset (gdbarch);
+  const char *target_wide_cset = target_wide_charset_name;
+  if (!strcmp (target_wide_cset, "auto"))
+    target_wide_cset = gdbarch_auto_wide_charset (gdbarch);
 
-  desc = iconv_open (target_wide_charset_name, host_cset);
+  desc = iconv_open (target_wide_cset, host_cset);
   if (desc == (iconv_t) -1)
     error ("Cannot convert between character sets `%s' and `%s'",
-          target_wide_charset_name, host_cset);
+          target_wide_cset, host_cset);
   iconv_close (desc);
 
-  desc = iconv_open (target_charset_name, host_cset);
+  desc = iconv_open (target_cset, host_cset);
   if (desc == (iconv_t) -1)
     error ("Cannot convert between character sets `%s' and `%s'",
-          target_charset_name, host_cset);
+          target_cset, host_cset);
   iconv_close (desc);
 
-  set_be_le_names ();
+  /* Clear the cache.  */
+  be_le_arch = NULL;
 }
 
 /* This is the sfunc for the 'set charset' command.  */
@@ -304,7 +334,7 @@ set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c)
 {
   /* CAREFUL: set the target charset here as well. */
   target_charset_name = host_charset_name;
-  validate ();
+  validate (get_current_arch ());
 }
 
 /* 'set host-charset' command sfunc.  We need a wrapper here because
@@ -313,7 +343,7 @@ static void
 set_host_charset_sfunc (char *charset, int from_tty,
                        struct cmd_list_element *c)
 {
-  validate ();
+  validate (get_current_arch ());
 }
 
 /* Wrapper for the 'set target-charset' command.  */
@@ -321,7 +351,7 @@ static void
 set_target_charset_sfunc (char *charset, int from_tty,
                          struct cmd_list_element *c)
 {
-  validate ();
+  validate (get_current_arch ());
 }
 
 /* Wrapper for the 'set target-wide-charset' command.  */
@@ -329,7 +359,7 @@ static void
 set_target_wide_charset_sfunc (char *charset, int from_tty,
                               struct cmd_list_element *c)
 {
-  validate ();
+  validate (get_current_arch ());
 }
 
 /* sfunc for the 'show charset' command.  */
@@ -354,14 +384,19 @@ host_charset (void)
 }
 
 const char *
-target_charset (void)
+target_charset (struct gdbarch *gdbarch)
 {
+  if (!strcmp (target_charset_name, "auto"))
+    return gdbarch_auto_charset (gdbarch);
   return target_charset_name;
 }
 
 const char *
-target_wide_charset (enum bfd_endian byte_order)
+target_wide_charset (struct gdbarch *gdbarch)
 {
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  set_be_le_names (gdbarch);
   if (byte_order == BFD_ENDIAN_BIG)
     {
       if (target_wide_charset_be_name)
@@ -373,6 +408,9 @@ target_wide_charset (enum bfd_endian byte_order)
        return target_wide_charset_le_name;
     }
 
+  if (!strcmp (target_wide_charset_name, "auto"))
+    return gdbarch_auto_wide_charset (gdbarch);
+
   return target_wide_charset_name;
 }
 
@@ -851,13 +889,27 @@ find_charset_names (void)
 #endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
 #endif /* PHONY_ICONV */
 
+/* The "auto" target charset used by default_auto_charset.  */
+static const char *auto_target_charset_name = GDB_DEFAULT_TARGET_CHARSET;
+
+const char *
+default_auto_charset (void)
+{
+  return auto_target_charset_name;
+}
+
+const char *
+default_auto_wide_charset (void)
+{
+  return GDB_DEFAULT_TARGET_WIDE_CHARSET;
+}
+
 void
 _initialize_charset (void)
 {
   struct cmd_list_element *new_cmd;
 
-  /* The first element is always "auto"; then we skip it for the
-     commands where it is not allowed.  */
+  /* The first element is always "auto".  */
   VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
   find_charset_names ();
 
@@ -868,20 +920,30 @@ _initialize_charset (void)
 
 #ifndef PHONY_ICONV
 #ifdef HAVE_LANGINFO_CODESET
-  auto_host_charset_name = nl_langinfo (CODESET);
+  /* The result of nl_langinfo may be overwritten later.  This may
+     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,
      which GNU libiconv doesn't like (infinite loop).  */
   if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
     auto_host_charset_name = "ASCII";
-  target_charset_name = auto_host_charset_name;
-
-  set_be_le_names ();
+  auto_target_charset_name = auto_host_charset_name;
+#elif defined (USE_WIN32API)
+  {
+    static w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
+
+    snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
+             "CP%d", GetACP());
+    auto_host_charset_name = w32_host_default_charset;
+    auto_target_charset_name = auto_host_charset_name;
+  }
 #endif
 #endif
 
   add_setshow_enum_cmd ("charset", class_support,
-                       &charset_enum[1], &host_charset_name, _("\
+                       charset_enum, &host_charset_name, _("\
 Set the host and target character sets."), _("\
 Show the host and target character sets."), _("\
 The `host character set' is the one used by the system GDB is running on.\n\
@@ -909,7 +971,7 @@ To see a list of the character sets GDB supports, type `set host-charset <TAB>'.
                        &setlist, &showlist);
 
   add_setshow_enum_cmd ("target-charset", class_support,
-                       &charset_enum[1], &target_charset_name, _("\
+                       charset_enum, &target_charset_name, _("\
 Set the target character set."), _("\
 Show the target character set."), _("\
 The `target character set' is the one used by the program being debugged.\n\
@@ -921,7 +983,7 @@ To see a list of the character sets GDB supports, type `set target-charset'<TAB>
                        &setlist, &showlist);
 
   add_setshow_enum_cmd ("target-wide-charset", class_support,
-                       &charset_enum[1], &target_wide_charset_name,
+                       charset_enum, &target_wide_charset_name,
                        _("\
 Set the target wide character set."), _("\
 Show the target wide character set."), _("\
index 7700168..bd93d01 100644 (file)
@@ -33,8 +33,8 @@
    result is owned by the charset module; the caller should not free
    it.  */
 const char *host_charset (void);
-const char *target_charset (void);
-const char *target_wide_charset (enum bfd_endian byte_order);
+const char *target_charset (struct gdbarch *gdbarch);
+const char *target_wide_charset (struct gdbarch *gdbarch);
 
 /* These values are used to specify the type of transliteration done
    by convert_between_encodings.  */
index 7400967..bc79258 100644 (file)
@@ -618,7 +618,7 @@ echo_command (char *text, int from_tty)
            if (*p == 0)
              return;
 
-           c = parse_escape (&p);
+           c = parse_escape (get_current_arch (), &p);
            if (c >= 0)
              printf_filtered ("%c", c);
          }
index c1dafb4..d8ec100 100644 (file)
@@ -21,6 +21,7 @@
 #include "value.h"
 #include <ctype.h>
 #include "gdb_string.h"
+#include "arch-utils.h"
 
 #include "ui-out.h"
 
@@ -152,7 +153,7 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
                       right before a newline.  */
                    if (*p == 0)
                      break;
-                   ch = parse_escape (&p);
+                   ch = parse_escape (get_current_arch (), &p);
                    if (ch == 0)
                      break;    /* C loses */
                    else if (ch > 0)
index ca903b8..5983289 100644 (file)
@@ -899,7 +899,7 @@ extern char *xstrvprintf (const char *format, va_list ap)
 extern int xsnprintf (char *str, size_t size, const char *format, ...)
      ATTR_FORMAT (printf, 3, 4);
 
-extern int parse_escape (char **);
+extern int parse_escape (struct gdbarch *, char **);
 
 /* Message to be printed before the error message, when an error occurs.  */
 
index 2bd09a8..bbd7895 100644 (file)
@@ -1,5 +1,10 @@
 2010-03-05  Tom Tromey  <tromey@redhat.com>
 
+       * gdb.texinfo (Basic Python): Document target_charset and
+       target_wide_charset.
+
+2010-03-05  Tom Tromey  <tromey@redhat.com>
+
        * gdb.texinfo (Data): Link to pretty-printing.
        (Output Formats): Likewise.  Correct text.
 
index 6ea3a60..41b11b6 100644 (file)
@@ -19634,6 +19634,21 @@ Flush @value{GDBN}'s paginated standard output stream.  Flushing
 function.
 @end defun
 
+@findex gdb.target_charset
+@defun target_charset
+Return the name of the current target character set (@pxref{Character
+Sets}).  This differs from @code{gdb.parameter('target-charset')} in
+that @samp{auto} is never returned.
+@end defun
+
+@findex gdb.target_wide_charset
+@defun target_wide_charset
+Return the name of the current target wide character set
+(@pxref{Character Sets}).  This differs from
+@code{gdb.parameter('target-wide-charset')} in that @samp{auto} is
+never returned.
+@end defun
+
 @node Exception Handling
 @subsubsection Exception Handling
 @cindex python exceptions
index cfb042b..f482572 100644 (file)
@@ -253,6 +253,8 @@ struct gdbarch
   gdbarch_has_shared_address_space_ftype *has_shared_address_space;
   gdbarch_fast_tracepoint_valid_at_ftype *fast_tracepoint_valid_at;
   const char * qsupported;
+  gdbarch_auto_charset_ftype *auto_charset;
+  gdbarch_auto_wide_charset_ftype *auto_wide_charset;
 };
 
 
@@ -397,6 +399,8 @@ struct gdbarch startup_gdbarch =
   default_has_shared_address_space,  /* has_shared_address_space */
   default_fast_tracepoint_valid_at,  /* fast_tracepoint_valid_at */
   0,  /* qsupported */
+  default_auto_charset,  /* auto_charset */
+  default_auto_wide_charset,  /* auto_wide_charset */
   /* startup_gdbarch() */
 };
 
@@ -483,6 +487,8 @@ gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->target_signal_to_host = default_target_signal_to_host;
   gdbarch->has_shared_address_space = default_has_shared_address_space;
   gdbarch->fast_tracepoint_valid_at = default_fast_tracepoint_valid_at;
+  gdbarch->auto_charset = default_auto_charset;
+  gdbarch->auto_wide_charset = default_auto_wide_charset;
   /* gdbarch_alloc() */
 
   return gdbarch;
@@ -664,6 +670,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of has_shared_address_space, invalid_p == 0 */
   /* Skip verify of fast_tracepoint_valid_at, invalid_p == 0 */
   /* Skip verify of qsupported, invalid_p == 0 */
+  /* Skip verify of auto_charset, invalid_p == 0 */
+  /* Skip verify of auto_wide_charset, invalid_p == 0 */
   buf = ui_file_xstrdup (log, &length);
   make_cleanup (xfree, buf);
   if (length > 0)
@@ -720,6 +728,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: adjust_breakpoint_address = <%s>\n",
                       host_address_to_string (gdbarch->adjust_breakpoint_address));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: auto_charset = <%s>\n",
+                      host_address_to_string (gdbarch->auto_charset));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: auto_wide_charset = <%s>\n",
+                      host_address_to_string (gdbarch->auto_wide_charset));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: believe_pcc_promotion = %s\n",
                       plongest (gdbarch->believe_pcc_promotion));
   fprintf_unfiltered (file,
@@ -3599,6 +3613,40 @@ set_gdbarch_qsupported (struct gdbarch *gdbarch,
   gdbarch->qsupported = qsupported;
 }
 
+const char *
+gdbarch_auto_charset (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->auto_charset != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_auto_charset called\n");
+  return gdbarch->auto_charset ();
+}
+
+void
+set_gdbarch_auto_charset (struct gdbarch *gdbarch,
+                          gdbarch_auto_charset_ftype auto_charset)
+{
+  gdbarch->auto_charset = auto_charset;
+}
+
+const char *
+gdbarch_auto_wide_charset (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->auto_wide_charset != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_auto_wide_charset called\n");
+  return gdbarch->auto_wide_charset ();
+}
+
+void
+set_gdbarch_auto_wide_charset (struct gdbarch *gdbarch,
+                               gdbarch_auto_wide_charset_ftype auto_wide_charset)
+{
+  gdbarch->auto_wide_charset = auto_wide_charset;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
index 1353ab1..83281f4 100644 (file)
@@ -928,6 +928,18 @@ extern void set_gdbarch_fast_tracepoint_valid_at (struct gdbarch *gdbarch, gdbar
 extern const char * gdbarch_qsupported (struct gdbarch *gdbarch);
 extern void set_gdbarch_qsupported (struct gdbarch *gdbarch, const char * qsupported);
 
+/* Return the "auto" target charset. */
+
+typedef const char * (gdbarch_auto_charset_ftype) (void);
+extern const char * gdbarch_auto_charset (struct gdbarch *gdbarch);
+extern void set_gdbarch_auto_charset (struct gdbarch *gdbarch, gdbarch_auto_charset_ftype *auto_charset);
+
+/* Return the "auto" target wide charset. */
+
+typedef const char * (gdbarch_auto_wide_charset_ftype) (void);
+extern const char * gdbarch_auto_wide_charset (struct gdbarch *gdbarch);
+extern void set_gdbarch_auto_wide_charset (struct gdbarch *gdbarch, gdbarch_auto_wide_charset_ftype *auto_wide_charset);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
index 0eaa0ef..441c515 100755 (executable)
@@ -769,6 +769,11 @@ m:int:fast_tracepoint_valid_at:CORE_ADDR addr, int *isize, char **msg:addr, isiz
 
 # Not NULL if a target has additonal field for qSupported.
 v:const char *:qsupported:::0:0::0:gdbarch->qsupported
+
+# Return the "auto" target charset.
+f:const char *:auto_charset:void::default_auto_charset:default_auto_charset::0
+# Return the "auto" target wide charset.
+f:const char *:auto_wide_charset:void::default_auto_wide_charset:default_auto_wide_charset::0
 EOF
 }
 
index f0d8d4b..ef24670 100644 (file)
@@ -205,6 +205,12 @@ i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   return i386_pe_skip_trampoline_code (frame, pc, NULL);
 }
 
+static const char *
+i386_cygwin_auto_wide_charset (void)
+{
+  return "UTF-16";
+}
+
 static void
 i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -227,6 +233,8 @@ i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
     (gdbarch, i386_windows_regset_from_core_section);
   set_gdbarch_core_xfer_shared_libraries
     (gdbarch, windows_core_xfer_shared_libraries);
+
+  set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
 }
 
 static enum gdb_osabi
index f91e5bd..a904c32 100644 (file)
@@ -898,7 +898,7 @@ yylex (void)
       lexptr++;
       c = *lexptr++;
       if (c == '\\')
-       c = parse_escape (&lexptr);
+       c = parse_escape (parse_gdbarch, &lexptr);
       else if (c == '\'')
        error (_("Empty character constant"));
 
@@ -1061,7 +1061,7 @@ yylex (void)
            break;
          case '\\':
            tokptr++;
-           c = parse_escape (&tokptr);
+           c = parse_escape (parse_gdbarch, &tokptr);
            if (c == -1)
              {
                continue;
index 8548b67..c3f5eeb 100644 (file)
 #include "defs.h"
 #include "mi-cmds.h"
 #include "mi-parse.h"
+#include "charset.h"
 
 #include <ctype.h>
 #include "gdb_string.h"
 
+/* Like parse_escape, but leave the results as a host char, not a
+   target char.  */
+
+static int
+mi_parse_escape (char **string_ptr)
+{
+  int c = *(*string_ptr)++;
+  switch (c)
+    {
+      case '\n':
+       return -2;
+      case 0:
+       (*string_ptr)--;
+       return 0;
+
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+       {
+         int i = host_hex_value (c);
+         int count = 0;
+         while (++count < 3)
+           {
+             c = (**string_ptr);
+             if (isdigit (c) && c != '8' && c != '9')
+               {
+                 (*string_ptr)++;
+                 i *= 8;
+                 i += host_hex_value (c);
+               }
+             else
+               {
+                 break;
+               }
+           }
+         return i;
+       }
+
+    case 'a':
+      c = '\a';
+      break;
+    case 'b':
+      c = '\b';
+      break;
+    case 'f':
+      c = '\f';
+      break;
+    case 'n':
+      c = '\n';
+      break;
+    case 'r':
+      c = '\r';
+      break;
+    case 't':
+      c = '\t';
+      break;
+    case 'v':
+      c = '\v';
+      break;
+
+    default:
+      break;
+    }
+
+  return c;
+}
+
 static void
 mi_parse_argv (char *args, struct mi_parse *parse)
 {
@@ -60,7 +133,7 @@ mi_parse_argv (char *args, struct mi_parse *parse)
                if (*chp == '\\')
                  {
                    chp++;
-                   if (parse_escape (&chp) <= 0)
+                   if (mi_parse_escape (&chp) <= 0)
                      {
                        /* Do not allow split lines or "\000" */
                        freeargv (argv);
@@ -93,7 +166,7 @@ mi_parse_argv (char *args, struct mi_parse *parse)
                if (*chp == '\\')
                  {
                    chp++;
-                   arg[len] = parse_escape (&chp);
+                   arg[len] = mi_parse_escape (&chp);
                  }
                else
                  arg[len] = *chp++;
index 9994ca2..888bd20 100644 (file)
@@ -1276,7 +1276,7 @@ yylex ()
       lexptr++;
       c = *lexptr++;
       if (c == '\\')
-       c = parse_escape (&lexptr);
+       c = parse_escape (parse_gdbarch, &lexptr);
       else if (c == '\'')
        error ("Empty character constant.");
 
@@ -1506,7 +1506,7 @@ yylex ()
            break;
          case '\\':
            tokptr++;
-           c = parse_escape (&tokptr);
+           c = parse_escape (parse_gdbarch, &tokptr);
            if (c == -1)
              {
                continue;
index 481624a..c034fbb 100644 (file)
@@ -1138,7 +1138,7 @@ yylex ()
       lexptr++;
       c = *lexptr++;
       if (c == '\\')
-       c = parse_escape (&lexptr);
+       c = parse_escape (parse_gdbarch, &lexptr);
       else if (c == '\'')
        error ("Empty character constant.");
 
@@ -1303,7 +1303,7 @@ yylex ()
            break;
          case '\\':
            tokptr++;
-           c = parse_escape (&tokptr);
+           c = parse_escape (parse_gdbarch, &tokptr);
            if (c == -1)
              {
                continue;
index 346c2e2..bfe8479 100644 (file)
@@ -2372,7 +2372,7 @@ printf_command (char *arg, int from_tty)
              obstack_init (&output);
              inner_cleanup = make_cleanup_obstack_free (&output);
 
-             convert_between_encodings (target_wide_charset (byte_order),
+             convert_between_encodings (target_wide_charset (gdbarch),
                                         host_charset (),
                                         str, j, wcwidth,
                                         &output, translit_char);
@@ -2404,7 +2404,7 @@ printf_command (char *arg, int from_tty)
              obstack_init (&output);
              inner_cleanup = make_cleanup_obstack_free (&output);
 
-             convert_between_encodings (target_wide_charset (byte_order),
+             convert_between_encodings (target_wide_charset (gdbarch),
                                         host_charset (),
                                         bytes, TYPE_LENGTH (valtype),
                                         TYPE_LENGTH (valtype),
index 4ccf97f..aed8fff 100644 (file)
@@ -129,7 +129,8 @@ unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
 char *
 unicode_to_target_string (PyObject *unicode_str)
 {
-  return unicode_to_encoded_string (unicode_str, target_charset ());
+  return unicode_to_encoded_string (unicode_str,
+                                   target_charset (python_gdbarch));
 }
 
 /* Returns a PyObject with the contents of the given unicode string
@@ -139,7 +140,8 @@ unicode_to_target_string (PyObject *unicode_str)
 PyObject *
 unicode_to_target_python_string (PyObject *unicode_str)
 {
-  return unicode_to_encoded_python_string (unicode_str, target_charset ());
+  return unicode_to_encoded_python_string (unicode_str,
+                                          target_charset (python_gdbarch));
 }
 
 /* Converts a python string (8-bit or unicode) to a target string in
@@ -208,7 +210,7 @@ target_string_to_unicode (const gdb_byte *str, int length)
   if (length == -1)
     length = strlen (str);
 
-  return PyUnicode_Decode (str, length, target_charset (), NULL);
+  return PyUnicode_Decode (str, length, target_charset (python_gdbarch), NULL);
 }
 
 /* Return true if OBJ is a Python string or unicode object, false
index 3d38de6..9a89eed 100644 (file)
@@ -283,6 +283,24 @@ gdbpy_parameter (PyObject *self, PyObject *args)
   return parameter_to_python (cmd);
 }
 
+/* Wrapper for target_charset.  */
+
+static PyObject *
+gdbpy_target_charset (PyObject *self, PyObject *args)
+{
+  const char *cset = target_charset (python_gdbarch);
+  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
+}
+
+/* Wrapper for target_wide_charset.  */
+
+static PyObject *
+gdbpy_target_wide_charset (PyObject *self, PyObject *args)
+{
+  const char *cset = target_wide_charset (python_gdbarch);
+  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
+}
+
 /* A Python function which evaluates a string using the gdb CLI.  */
 
 static PyObject *
@@ -740,6 +758,13 @@ a boolean indicating if name is a field of the current implied argument\n\
 Parse String as an expression, evaluate it, and return the result as a Value."
   },
 
+  { "target_charset", gdbpy_target_charset, METH_NOARGS,
+    "target_charset () -> string.\n\
+Return the name of the current target charset." },
+  { "target_wide_charset", gdbpy_target_wide_charset, METH_NOARGS,
+    "target_wide_charset () -> string.\n\
+Return the name of the current target wide charset." },
+
   { "write", gdbpy_write, METH_VARARGS,
     "Write a string using gdb's filtered stream." },
   { "flush", gdbpy_flush, METH_NOARGS,
index b5e4c98..3efd2be 100644 (file)
@@ -1,3 +1,9 @@
+2010-03-05  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.python/py-prettyprint.py (pp_nullstr.to_string): Use
+       gdb.target_charset.
+       (pp_ns.to_string): Likewise.
+
 2010-03-04  Keith Seitz  <keiths@redhat.com>
 
        * gdb.cp/overload.exp: Test that the filename portion of a linespec
index 9a0d107..979d4ad 100644 (file)
@@ -97,7 +97,7 @@ class pp_nullstr:
         self.val = val
 
     def to_string(self):
-        return self.val['s'].string(gdb.parameter('target-charset'))
+        return self.val['s'].string(gdb.target_charset())
 
 class pp_ns:
     "Print a std::basic_string of some kind"
@@ -107,7 +107,7 @@ class pp_ns:
 
     def to_string(self):
         len = self.val['length']
-        return self.val['null_str'].string (gdb.parameter ('target-charset'), length = len)
+        return self.val['null_str'].string (gdb.target_charset(), length = len)
 
     def display_hint (self):
         return 'string'
index 0b74e2b..8054f03 100644 (file)
@@ -1653,7 +1653,7 @@ query (const char *ctlstr, ...)
    function returns 1.  Otherwise, the function returns 0.  */
 
 static int
-host_char_to_target (int c, int *target_c)
+host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
 {
   struct obstack host_data;
   char the_char = c;
@@ -1663,7 +1663,7 @@ host_char_to_target (int c, int *target_c)
   obstack_init (&host_data);
   cleanups = make_cleanup_obstack_free (&host_data);
 
-  convert_between_encodings (target_charset (), host_charset (),
+  convert_between_encodings (target_charset (gdbarch), host_charset (),
                             &the_char, 1, 1, &host_data, translit_none);
 
   if (obstack_object_size (&host_data) == 1)
@@ -1692,7 +1692,7 @@ host_char_to_target (int c, int *target_c)
    after the zeros.  A value of 0 does not mean end of string.  */
 
 int
-parse_escape (char **string_ptr)
+parse_escape (struct gdbarch *gdbarch, char **string_ptr)
 {
   int target_char = -2;        /* initialize to avoid GCC warnings */
   int c = *(*string_ptr)++;
@@ -1758,11 +1758,11 @@ parse_escape (char **string_ptr)
       break;
     }
 
-  if (!host_char_to_target (c, &target_char))
+  if (!host_char_to_target (gdbarch, c, &target_char))
     error
       ("The escape sequence `\%c' is equivalent to plain `%c', which"
        " has no equivalent\n" "in the `%s' character set.", c, c,
-       target_charset ());
+       target_charset (gdbarch));
   return target_char;
 }
 \f