mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-06 14:21:43 +08:00
gdb
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:
parent
78e2826bcc
commit
f870a310ee
@ -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
|
||||
|
6
gdb/NEWS
6
gdb/NEWS
@ -13,8 +13,10 @@
|
||||
|
||||
* 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
|
||||
|
||||
|
@ -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
|
||||
|
27
gdb/c-lang.c
27
gdb/c-lang.c
@ -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)
|
||||
|
124
gdb/charset.c
124
gdb/charset.c
@ -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;
|
||||
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
|
||||
|
||||
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."), _("\
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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>
|
||||
|
||||
* gdb.texinfo (Data): Link to pretty-printing.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
@ -719,6 +727,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
fprintf_unfiltered (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));
|
||||
@ -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. */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -23,10 +23,83 @@
|
||||
#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++;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
10
gdb/utils.c
10
gdb/utils.c
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user