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.
This commit is contained in:
Tom Tromey 2010-03-05 20:18:19 +00:00
parent 78e2826bcc
commit f870a310ee
25 changed files with 397 additions and 72 deletions

View 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> 2010-03-05 Ulrich Weigand <uweigand@de.ibm.com>
* symfile.c (build_section_addr_info_from_objfile): Do not mask * symfile.c (build_section_addr_info_from_objfile): Do not mask

View file

@ -13,8 +13,10 @@
* Python scripting * Python scripting
The GDB Python API now has access to symbols, symbol tables, and ** The GDB Python API now has access to symbols, symbol tables, and
frame's code blocks. frame's code blocks.
** New methods gdb.target_charset and gdb.target_wide_charset.
* New targets * New targets

View file

@ -162,4 +162,7 @@ extern int default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
extern void default_remote_breakpoint_from_pc (struct gdbarch *, extern void default_remote_breakpoint_from_pc (struct gdbarch *,
CORE_ADDR *pcptr, int *kindptr); CORE_ADDR *pcptr, int *kindptr);
extern const char *default_auto_charset (void);
extern const char *default_auto_wide_charset (void);
#endif #endif

View file

@ -43,23 +43,23 @@ extern void _initialize_c_language (void);
static const char * static const char *
charset_for_string_type (enum c_string_type str_type, charset_for_string_type (enum c_string_type str_type,
enum bfd_endian byte_order) struct gdbarch *gdbarch)
{ {
switch (str_type & ~C_CHAR) switch (str_type & ~C_CHAR)
{ {
case C_STRING: case C_STRING:
return target_charset (); return target_charset (gdbarch);
case C_WIDE_STRING: case C_WIDE_STRING:
return target_wide_charset (byte_order); return target_wide_charset (gdbarch);
case C_STRING_16: case C_STRING_16:
/* FIXME: UTF-16 is not always correct. */ /* FIXME: UTF-16 is not always correct. */
if (byte_order == BFD_ENDIAN_BIG) if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
return "UTF-16BE"; return "UTF-16BE";
else else
return "UTF-16LE"; return "UTF-16LE";
case C_STRING_32: case C_STRING_32:
/* FIXME: UTF-32 is not always correct. */ /* FIXME: UTF-32 is not always correct. */
if (byte_order == BFD_ENDIAN_BIG) if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
return "UTF-32BE"; return "UTF-32BE";
else else
return "UTF-32LE"; 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. */ characters of this type in target BYTE_ORDER to the host character set. */
static enum c_string_type 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) const char **encoding)
{ {
struct type *saved_type; struct type *saved_type;
@ -134,7 +134,7 @@ classify_type (struct type *elttype, enum bfd_endian byte_order,
done: done:
if (encoding) if (encoding)
*encoding = charset_for_string_type (result, byte_order); *encoding = charset_for_string_type (result, gdbarch);
return result; return result;
} }
@ -264,7 +264,7 @@ c_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
struct wchar_iterator *iter; struct wchar_iterator *iter;
int need_escape = 0; int need_escape = 0;
classify_type (type, byte_order, &encoding); classify_type (type, get_type_arch (type), &encoding);
buf = alloca (TYPE_LENGTH (type)); buf = alloca (TYPE_LENGTH (type));
pack_long (buf, type, c); 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; 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) switch (str_type)
{ {
case C_CHAR: case C_CHAR:
@ -396,7 +396,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
width, byte_order) == 0)) width, byte_order) == 0))
length--; 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) switch (str_type)
{ {
case C_STRING: 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)) if (! c_textual_element_type (element_type, 0))
goto error; goto error;
kind = classify_type (element_type, kind = classify_type (element_type,
gdbarch_byte_order (get_type_arch (element_type)), get_type_arch (element_type),
charset); charset);
width = TYPE_LENGTH (element_type); width = TYPE_LENGTH (element_type);
@ -942,7 +943,6 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
struct value *result; struct value *result;
enum c_string_type dest_type; enum c_string_type dest_type;
const char *dest_charset; const char *dest_charset;
enum bfd_endian byte_order;
obstack_init (&output); obstack_init (&output);
cleanup = make_cleanup_obstack_free (&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. */ /* Ensure TYPE_LENGTH is valid for TYPE. */
check_typedef (type); check_typedef (type);
byte_order = gdbarch_byte_order (exp->gdbarch); dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
dest_charset = charset_for_string_type (dest_type, byte_order);
++*pos; ++*pos;
while (*pos < limit) while (*pos < limit)

View file

@ -27,6 +27,7 @@
#include "charset-list.h" #include "charset-list.h"
#include "vec.h" #include "vec.h"
#include "environ.h" #include "environ.h"
#include "arch-utils.h"
#include <stddef.h> #include <stddef.h>
#include "gdb_string.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); 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 static void
show_target_charset_name (struct ui_file *file, int from_tty, show_target_charset_name (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value) struct cmd_list_element *c, const char *value)
{ {
fprintf_filtered (file, _("The target character set is \"%s\".\n"), if (!strcmp (value, "auto"))
value); 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 static void
show_target_wide_charset_name (struct ui_file *file, int from_tty, show_target_wide_charset_name (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value) struct cmd_list_element *c, const char *value)
{ {
fprintf_filtered (file, _("The target wide character set is \"%s\".\n"), if (!strcmp (value, "auto"))
value); 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[] = 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_be_name;
static const char *target_wide_charset_le_name; static const char *target_wide_charset_le_name;
/* A helper function for validate which sets the target wide big- and /* The architecture for which the BE- and LE-names are valid. */
little-endian character set names, if possible. */ 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 static void
set_be_le_names (void) set_be_le_names (struct gdbarch *gdbarch)
{ {
int i, len; 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_le_name = NULL;
target_wide_charset_be_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) 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; continue;
if ((charset_enum[i][len] == 'B' if ((charset_enum[i][len] == 'B'
|| charset_enum[i][len] == 'L') || charset_enum[i][len] == 'L')
@ -278,24 +303,29 @@ set_be_le_names (void)
target-wide-charset', 'set charset' sfunc's. */ target-wide-charset', 'set charset' sfunc's. */
static void static void
validate (void) validate (struct gdbarch *gdbarch)
{ {
iconv_t desc; iconv_t desc;
const char *host_cset = host_charset (); 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) 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_charset_name, host_cset); target_wide_cset, host_cset);
iconv_close (desc); iconv_close (desc);
desc = iconv_open (target_charset_name, host_cset); desc = iconv_open (target_cset, host_cset);
if (desc == (iconv_t) -1) if (desc == (iconv_t) -1)
error ("Cannot convert between character sets `%s' and `%s'", error ("Cannot convert between character sets `%s' and `%s'",
target_charset_name, host_cset); target_cset, host_cset);
iconv_close (desc); iconv_close (desc);
set_be_le_names (); /* Clear the cache. */
be_le_arch = NULL;
} }
/* This is the sfunc for the 'set charset' command. */ /* 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. */ /* CAREFUL: set the target charset here as well. */
target_charset_name = host_charset_name; target_charset_name = host_charset_name;
validate (); validate (get_current_arch ());
} }
/* 'set host-charset' command sfunc. We need a wrapper here because /* '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, set_host_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c) struct cmd_list_element *c)
{ {
validate (); validate (get_current_arch ());
} }
/* Wrapper for the 'set target-charset' command. */ /* Wrapper for the 'set target-charset' command. */
@ -321,7 +351,7 @@ static void
set_target_charset_sfunc (char *charset, int from_tty, set_target_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c) struct cmd_list_element *c)
{ {
validate (); validate (get_current_arch ());
} }
/* Wrapper for the 'set target-wide-charset' command. */ /* Wrapper for the 'set target-wide-charset' command. */
@ -329,7 +359,7 @@ static void
set_target_wide_charset_sfunc (char *charset, int from_tty, set_target_wide_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c) struct cmd_list_element *c)
{ {
validate (); validate (get_current_arch ());
} }
/* sfunc for the 'show charset' command. */ /* sfunc for the 'show charset' command. */
@ -354,14 +384,19 @@ host_charset (void)
} }
const char * 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; return target_charset_name;
} }
const char * 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 (byte_order == BFD_ENDIAN_BIG)
{ {
if (target_wide_charset_be_name) if (target_wide_charset_be_name)
@ -373,6 +408,9 @@ target_wide_charset (enum bfd_endian byte_order)
return target_wide_charset_le_name; return target_wide_charset_le_name;
} }
if (!strcmp (target_wide_charset_name, "auto"))
return gdbarch_auto_wide_charset (gdbarch);
return target_wide_charset_name; return target_wide_charset_name;
} }
@ -851,13 +889,27 @@ find_charset_names (void)
#endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */ #endif /* HAVE_ICONVLIST || HAVE_LIBICONVLIST */
#endif /* PHONY_ICONV */ #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 void
_initialize_charset (void) _initialize_charset (void)
{ {
struct cmd_list_element *new_cmd; struct cmd_list_element *new_cmd;
/* The first element is always "auto"; then we skip it for the /* The first element is always "auto". */
commands where it is not allowed. */
VEC_safe_push (char_ptr, charsets, xstrdup ("auto")); VEC_safe_push (char_ptr, charsets, xstrdup ("auto"));
find_charset_names (); find_charset_names ();
@ -868,20 +920,30 @@ _initialize_charset (void)
#ifndef PHONY_ICONV #ifndef PHONY_ICONV
#ifdef HAVE_LANGINFO_CODESET #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 /* Solaris will return `646' here -- but the Solaris iconv then
does not accept this. Darwin (and maybe FreeBSD) may return "" here, does not accept this. Darwin (and maybe FreeBSD) may return "" here,
which GNU libiconv doesn't like (infinite loop). */ which GNU libiconv doesn't like (infinite loop). */
if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name) if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
auto_host_charset_name = "ASCII"; auto_host_charset_name = "ASCII";
target_charset_name = auto_host_charset_name; auto_target_charset_name = auto_host_charset_name;
#elif defined (USE_WIN32API)
{
static w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
set_be_le_names (); 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
#endif #endif
add_setshow_enum_cmd ("charset", class_support, 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."), _("\ Set the host and target character sets."), _("\
Show 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\ 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); &setlist, &showlist);
add_setshow_enum_cmd ("target-charset", class_support, add_setshow_enum_cmd ("target-charset", class_support,
&charset_enum[1], &target_charset_name, _("\ charset_enum, &target_charset_name, _("\
Set the target character set."), _("\ Set the target character set."), _("\
Show the target character set."), _("\ Show the target character set."), _("\
The `target character set' is the one used by the program being debugged.\n\ 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); &setlist, &showlist);
add_setshow_enum_cmd ("target-wide-charset", class_support, 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."), _("\ Set the target wide character set."), _("\
Show the target wide character set."), _("\ Show the target wide character set."), _("\

View file

@ -33,8 +33,8 @@
result is owned by the charset module; the caller should not free result is owned by the charset module; the caller should not free
it. */ it. */
const char *host_charset (void); const char *host_charset (void);
const char *target_charset (void); const char *target_charset (struct gdbarch *gdbarch);
const char *target_wide_charset (enum bfd_endian byte_order); const char *target_wide_charset (struct gdbarch *gdbarch);
/* These values are used to specify the type of transliteration done /* These values are used to specify the type of transliteration done
by convert_between_encodings. */ by convert_between_encodings. */

View file

@ -618,7 +618,7 @@ echo_command (char *text, int from_tty)
if (*p == 0) if (*p == 0)
return; return;
c = parse_escape (&p); c = parse_escape (get_current_arch (), &p);
if (c >= 0) if (c >= 0)
printf_filtered ("%c", c); printf_filtered ("%c", c);
} }

View file

@ -21,6 +21,7 @@
#include "value.h" #include "value.h"
#include <ctype.h> #include <ctype.h>
#include "gdb_string.h" #include "gdb_string.h"
#include "arch-utils.h"
#include "ui-out.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. */ right before a newline. */
if (*p == 0) if (*p == 0)
break; break;
ch = parse_escape (&p); ch = parse_escape (get_current_arch (), &p);
if (ch == 0) if (ch == 0)
break; /* C loses */ break; /* C loses */
else if (ch > 0) else if (ch > 0)

View 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, ...) extern int xsnprintf (char *str, size_t size, const char *format, ...)
ATTR_FORMAT (printf, 3, 4); 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. */ /* Message to be printed before the error message, when an error occurs. */

View file

@ -1,3 +1,8 @@
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> 2010-03-05 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Data): Link to pretty-printing. * gdb.texinfo (Data): Link to pretty-printing.

View file

@ -19634,6 +19634,21 @@ Flush @value{GDBN}'s paginated standard output stream. Flushing
function. function.
@end defun @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 @node Exception Handling
@subsubsection Exception Handling @subsubsection Exception Handling
@cindex python exceptions @cindex python exceptions

View file

@ -253,6 +253,8 @@ struct gdbarch
gdbarch_has_shared_address_space_ftype *has_shared_address_space; gdbarch_has_shared_address_space_ftype *has_shared_address_space;
gdbarch_fast_tracepoint_valid_at_ftype *fast_tracepoint_valid_at; gdbarch_fast_tracepoint_valid_at_ftype *fast_tracepoint_valid_at;
const char * qsupported; 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_has_shared_address_space, /* has_shared_address_space */
default_fast_tracepoint_valid_at, /* fast_tracepoint_valid_at */ default_fast_tracepoint_valid_at, /* fast_tracepoint_valid_at */
0, /* qsupported */ 0, /* qsupported */
default_auto_charset, /* auto_charset */
default_auto_wide_charset, /* auto_wide_charset */
/* startup_gdbarch() */ /* startup_gdbarch() */
}; };
@ -483,6 +487,8 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->target_signal_to_host = default_target_signal_to_host; gdbarch->target_signal_to_host = default_target_signal_to_host;
gdbarch->has_shared_address_space = default_has_shared_address_space; gdbarch->has_shared_address_space = default_has_shared_address_space;
gdbarch->fast_tracepoint_valid_at = default_fast_tracepoint_valid_at; 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() */ /* gdbarch_alloc() */
return gdbarch; return gdbarch;
@ -664,6 +670,8 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of has_shared_address_space, invalid_p == 0 */ /* Skip verify of has_shared_address_space, invalid_p == 0 */
/* Skip verify of fast_tracepoint_valid_at, invalid_p == 0 */ /* Skip verify of fast_tracepoint_valid_at, invalid_p == 0 */
/* Skip verify of qsupported, 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); buf = ui_file_xstrdup (log, &length);
make_cleanup (xfree, buf); make_cleanup (xfree, buf);
if (length > 0) if (length > 0)
@ -719,6 +727,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file, fprintf_unfiltered (file,
"gdbarch_dump: adjust_breakpoint_address = <%s>\n", "gdbarch_dump: adjust_breakpoint_address = <%s>\n",
host_address_to_string (gdbarch->adjust_breakpoint_address)); 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, fprintf_unfiltered (file,
"gdbarch_dump: believe_pcc_promotion = %s\n", "gdbarch_dump: believe_pcc_promotion = %s\n",
plongest (gdbarch->believe_pcc_promotion)); plongest (gdbarch->believe_pcc_promotion));
@ -3599,6 +3613,40 @@ set_gdbarch_qsupported (struct gdbarch *gdbarch,
gdbarch->qsupported = qsupported; 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 /* Keep a registry of per-architecture data-pointers required by GDB
modules. */ modules. */

View 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 const char * gdbarch_qsupported (struct gdbarch *gdbarch);
extern void set_gdbarch_qsupported (struct gdbarch *gdbarch, const char * qsupported); 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. */ /* Definition for an unknown syscall, used basically in error-cases. */
#define UNKNOWN_SYSCALL (-1) #define UNKNOWN_SYSCALL (-1)

View file

@ -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. # Not NULL if a target has additonal field for qSupported.
v:const char *:qsupported:::0:0::0:gdbarch->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 EOF
} }

View 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); return i386_pe_skip_trampoline_code (frame, pc, NULL);
} }
static const char *
i386_cygwin_auto_wide_charset (void)
{
return "UTF-16";
}
static void static void
i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 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); (gdbarch, i386_windows_regset_from_core_section);
set_gdbarch_core_xfer_shared_libraries set_gdbarch_core_xfer_shared_libraries
(gdbarch, windows_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 static enum gdb_osabi

View file

@ -898,7 +898,7 @@ yylex (void)
lexptr++; lexptr++;
c = *lexptr++; c = *lexptr++;
if (c == '\\') if (c == '\\')
c = parse_escape (&lexptr); c = parse_escape (parse_gdbarch, &lexptr);
else if (c == '\'') else if (c == '\'')
error (_("Empty character constant")); error (_("Empty character constant"));
@ -1061,7 +1061,7 @@ yylex (void)
break; break;
case '\\': case '\\':
tokptr++; tokptr++;
c = parse_escape (&tokptr); c = parse_escape (parse_gdbarch, &tokptr);
if (c == -1) if (c == -1)
{ {
continue; continue;

View file

@ -23,10 +23,83 @@
#include "defs.h" #include "defs.h"
#include "mi-cmds.h" #include "mi-cmds.h"
#include "mi-parse.h" #include "mi-parse.h"
#include "charset.h"
#include <ctype.h> #include <ctype.h>
#include "gdb_string.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 static void
mi_parse_argv (char *args, struct mi_parse *parse) mi_parse_argv (char *args, struct mi_parse *parse)
{ {
@ -60,7 +133,7 @@ mi_parse_argv (char *args, struct mi_parse *parse)
if (*chp == '\\') if (*chp == '\\')
{ {
chp++; chp++;
if (parse_escape (&chp) <= 0) if (mi_parse_escape (&chp) <= 0)
{ {
/* Do not allow split lines or "\000" */ /* Do not allow split lines or "\000" */
freeargv (argv); freeargv (argv);
@ -93,7 +166,7 @@ mi_parse_argv (char *args, struct mi_parse *parse)
if (*chp == '\\') if (*chp == '\\')
{ {
chp++; chp++;
arg[len] = parse_escape (&chp); arg[len] = mi_parse_escape (&chp);
} }
else else
arg[len] = *chp++; arg[len] = *chp++;

View file

@ -1276,7 +1276,7 @@ yylex ()
lexptr++; lexptr++;
c = *lexptr++; c = *lexptr++;
if (c == '\\') if (c == '\\')
c = parse_escape (&lexptr); c = parse_escape (parse_gdbarch, &lexptr);
else if (c == '\'') else if (c == '\'')
error ("Empty character constant."); error ("Empty character constant.");
@ -1506,7 +1506,7 @@ yylex ()
break; break;
case '\\': case '\\':
tokptr++; tokptr++;
c = parse_escape (&tokptr); c = parse_escape (parse_gdbarch, &tokptr);
if (c == -1) if (c == -1)
{ {
continue; continue;

View file

@ -1138,7 +1138,7 @@ yylex ()
lexptr++; lexptr++;
c = *lexptr++; c = *lexptr++;
if (c == '\\') if (c == '\\')
c = parse_escape (&lexptr); c = parse_escape (parse_gdbarch, &lexptr);
else if (c == '\'') else if (c == '\'')
error ("Empty character constant."); error ("Empty character constant.");
@ -1303,7 +1303,7 @@ yylex ()
break; break;
case '\\': case '\\':
tokptr++; tokptr++;
c = parse_escape (&tokptr); c = parse_escape (parse_gdbarch, &tokptr);
if (c == -1) if (c == -1)
{ {
continue; continue;

View file

@ -2372,7 +2372,7 @@ printf_command (char *arg, int from_tty)
obstack_init (&output); obstack_init (&output);
inner_cleanup = make_cleanup_obstack_free (&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 (), host_charset (),
str, j, wcwidth, str, j, wcwidth,
&output, translit_char); &output, translit_char);
@ -2404,7 +2404,7 @@ printf_command (char *arg, int from_tty)
obstack_init (&output); obstack_init (&output);
inner_cleanup = make_cleanup_obstack_free (&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 (), host_charset (),
bytes, TYPE_LENGTH (valtype), bytes, TYPE_LENGTH (valtype),
TYPE_LENGTH (valtype), TYPE_LENGTH (valtype),

View file

@ -129,7 +129,8 @@ unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
char * char *
unicode_to_target_string (PyObject *unicode_str) 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 /* Returns a PyObject with the contents of the given unicode string
@ -139,7 +140,8 @@ unicode_to_target_string (PyObject *unicode_str)
PyObject * PyObject *
unicode_to_target_python_string (PyObject *unicode_str) 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 /* 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) if (length == -1)
length = strlen (str); 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 /* Return true if OBJ is a Python string or unicode object, false

View file

@ -283,6 +283,24 @@ gdbpy_parameter (PyObject *self, PyObject *args)
return parameter_to_python (cmd); 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. */ /* A Python function which evaluates a string using the gdb CLI. */
static PyObject * 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." 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", gdbpy_write, METH_VARARGS,
"Write a string using gdb's filtered stream." }, "Write a string using gdb's filtered stream." },
{ "flush", gdbpy_flush, METH_NOARGS, { "flush", gdbpy_flush, METH_NOARGS,

View 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> 2010-03-04 Keith Seitz <keiths@redhat.com>
* gdb.cp/overload.exp: Test that the filename portion of a linespec * gdb.cp/overload.exp: Test that the filename portion of a linespec

View file

@ -97,7 +97,7 @@ class pp_nullstr:
self.val = val self.val = val
def to_string(self): def to_string(self):
return self.val['s'].string(gdb.parameter('target-charset')) return self.val['s'].string(gdb.target_charset())
class pp_ns: class pp_ns:
"Print a std::basic_string of some kind" "Print a std::basic_string of some kind"
@ -107,7 +107,7 @@ class pp_ns:
def to_string(self): def to_string(self):
len = self.val['length'] 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): def display_hint (self):
return 'string' return 'string'

View file

@ -1653,7 +1653,7 @@ query (const char *ctlstr, ...)
function returns 1. Otherwise, the function returns 0. */ function returns 1. Otherwise, the function returns 0. */
static int 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; struct obstack host_data;
char the_char = c; char the_char = c;
@ -1663,7 +1663,7 @@ host_char_to_target (int c, int *target_c)
obstack_init (&host_data); obstack_init (&host_data);
cleanups = make_cleanup_obstack_free (&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); &the_char, 1, 1, &host_data, translit_none);
if (obstack_object_size (&host_data) == 1) 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. */ after the zeros. A value of 0 does not mean end of string. */
int int
parse_escape (char **string_ptr) parse_escape (struct gdbarch *gdbarch, char **string_ptr)
{ {
int target_char = -2; /* initialize to avoid GCC warnings */ int target_char = -2; /* initialize to avoid GCC warnings */
int c = *(*string_ptr)++; int c = *(*string_ptr)++;
@ -1758,11 +1758,11 @@ parse_escape (char **string_ptr)
break; break;
} }
if (!host_char_to_target (c, &target_char)) if (!host_char_to_target (gdbarch, c, &target_char))
error error
("The escape sequence `\%c' is equivalent to plain `%c', which" ("The escape sequence `\%c' is equivalent to plain `%c', which"
" has no equivalent\n" "in the `%s' character set.", c, c, " has no equivalent\n" "in the `%s' character set.", c, c,
target_charset ()); target_charset (gdbarch));
return target_char; return target_char;
} }