PR python/10664:
	* language.h (struct language_defn) <la_get_string>: Add
	'char_type' argument.
	(LA_GET_STRING): Likewise.
	(default_get_string, c_get_string): Update.
	* language.c (default_get_string): Add 'char_type' argument.
	* c-valprint.c (c_textual_element_type): Rename from
	textual_element_type.  No longer static.  Update callers.
	* c-lang.h (c_textual_element_type): Declare.
	* c-lang.c (c_get_string): Add 'char_type' argument.
gdb/testsuite
	PR python/10664:
	* gdb.base/charset.exp: Test utf-16 strings with Python.
This commit is contained in:
Tom Tromey 2009-09-25 21:39:53 +00:00
parent b8899f2b68
commit 96c07c5b96
9 changed files with 65 additions and 23 deletions

View file

@ -1,3 +1,16 @@
2009-09-25 Tom Tromey <tromey@redhat.com>
PR python/10664:
* language.h (struct language_defn) <la_get_string>: Add
'char_type' argument.
(LA_GET_STRING): Likewise.
(default_get_string, c_get_string): Update.
* language.c (default_get_string): Add 'char_type' argument.
* c-valprint.c (c_textual_element_type): Rename from
textual_element_type. No longer static. Update callers.
* c-lang.h (c_textual_element_type): Declare.
* c-lang.c (c_get_string): Add 'char_type' argument.
2009-09-25 Tom Tromey <tromey@redhat.com> 2009-09-25 Tom Tromey <tromey@redhat.com>
* charset.c (iconv_open): Use UTF-16 and UTF-32, not UCS-2 and * charset.c (iconv_open): Use UTF-16 and UTF-32, not UCS-2 and

View file

@ -618,7 +618,7 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
void void
c_get_string (struct value *value, gdb_byte **buffer, int *length, c_get_string (struct value *value, gdb_byte **buffer, int *length,
const char **charset) struct type **char_type, const char **charset)
{ {
int err, width; int err, width;
unsigned int fetchlimit; unsigned int fetchlimit;
@ -626,6 +626,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
struct type *element_type = TYPE_TARGET_TYPE (type); struct type *element_type = TYPE_TARGET_TYPE (type);
int req_length = *length; int req_length = *length;
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
enum c_string_type kind;
if (element_type == NULL) if (element_type == NULL)
goto error; goto error;
@ -652,13 +653,11 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
/* We work only with arrays and pointers. */ /* We work only with arrays and pointers. */
goto error; goto error;
element_type = check_typedef (element_type); if (! c_textual_element_type (element_type, 0))
if (TYPE_CODE (element_type) != TYPE_CODE_INT
&& TYPE_CODE (element_type) != TYPE_CODE_CHAR)
/* If the elements are not integers or characters, we don't consider it
a string. */
goto error; goto error;
kind = classify_type (element_type,
gdbarch_byte_order (get_type_arch (element_type)),
charset);
width = TYPE_LENGTH (element_type); width = TYPE_LENGTH (element_type);
/* If the string lives in GDB's memory instead of the inferior's, then we /* If the string lives in GDB's memory instead of the inferior's, then we
@ -717,7 +716,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
if (*length != 0) if (*length != 0)
*length = *length / width; *length = *length / width;
*charset = target_charset (); *char_type = element_type;
return; return;

View file

@ -106,5 +106,9 @@ extern int cp_is_vtbl_ptr_type (struct type *);
extern int cp_is_vtbl_member (struct type *); extern int cp_is_vtbl_member (struct type *);
/* These are in c-valprint.c. */
extern int c_textual_element_type (struct type *, char);
#endif /* !defined (C_LANG_H) */ #endif /* !defined (C_LANG_H) */

View file

@ -54,7 +54,7 @@ print_function_pointer_address (struct gdbarch *gdbarch, CORE_ADDR address,
} }
/* A helper for textual_element_type. This checks the name of the /* A helper for c_textual_element_type. This checks the name of the
typedef. This is bogus but it isn't apparent that the compiler typedef. This is bogus but it isn't apparent that the compiler
provides us the help we may need. */ provides us the help we may need. */
@ -77,8 +77,8 @@ textual_name (const char *name)
vector types is not. The user can override this by using the /s vector types is not. The user can override this by using the /s
format letter. */ format letter. */
static int int
textual_element_type (struct type *type, char format) c_textual_element_type (struct type *type, char format)
{ {
struct type *true_type, *iter_type; struct type *true_type, *iter_type;
@ -178,7 +178,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
} }
/* Print arrays of textual chars with a string syntax. */ /* Print arrays of textual chars with a string syntax. */
if (textual_element_type (unresolved_elttype, options->format)) if (c_textual_element_type (unresolved_elttype, options->format))
{ {
/* If requested, look for the first null char and only print /* If requested, look for the first null char and only print
elements up to it. */ elements up to it. */
@ -278,7 +278,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
/* For a pointer to a textual type, also print the string /* For a pointer to a textual type, also print the string
pointed to, unless pointer is null. */ pointed to, unless pointer is null. */
if (textual_element_type (unresolved_elttype, options->format) if (c_textual_element_type (unresolved_elttype, options->format)
&& addr != 0) && addr != 0)
{ {
i = val_print_string (unresolved_elttype, addr, -1, stream, i = val_print_string (unresolved_elttype, addr, -1, stream,
@ -491,7 +491,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
Since we don't know whether the value is really intended to Since we don't know whether the value is really intended to
be used as an integer or a character, print the character be used as an integer or a character, print the character
equivalent as well. */ equivalent as well. */
if (textual_element_type (unresolved_type, options->format)) if (c_textual_element_type (unresolved_type, options->format))
{ {
fputs_filtered (" ", stream); fputs_filtered (" ", stream);
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset),
@ -613,7 +613,7 @@ c_value_print (struct value *val, struct ui_file *stream,
{ {
/* Hack: remove (char *) for char strings. Their /* Hack: remove (char *) for char strings. Their
type is indicated by the quoted string anyway. type is indicated by the quoted string anyway.
(Don't use textual_element_type here; quoted strings (Don't use c_textual_element_type here; quoted strings
are always exactly (char *), (wchar_t *), or the like. */ are always exactly (char *), (wchar_t *), or the like. */
if (TYPE_CODE (val_type) == TYPE_CODE_PTR if (TYPE_CODE (val_type) == TYPE_CODE_PTR
&& TYPE_NAME (val_type) == NULL && TYPE_NAME (val_type) == NULL

View file

@ -1045,7 +1045,7 @@ default_print_array_index (struct value *index_value, struct ui_file *stream,
void void
default_get_string (struct value *value, gdb_byte **buffer, int *length, default_get_string (struct value *value, gdb_byte **buffer, int *length,
const char **charset) struct type **char_type, const char **charset)
{ {
error (_("Getting a string is unsupported in this language.")); error (_("Getting a string is unsupported in this language."));
} }

View file

@ -294,7 +294,7 @@ struct language_defn
Otherwise *LENGTH will include all characters - including any nulls. Otherwise *LENGTH will include all characters - including any nulls.
CHARSET will hold the encoding used in the string. */ CHARSET will hold the encoding used in the string. */
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length, void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
const char **charset); struct type **chartype, const char **charset);
/* Add fields above this point, so the magic number is always last. */ /* Add fields above this point, so the magic number is always last. */
/* Magic number for compat checking */ /* Magic number for compat checking */
@ -394,8 +394,8 @@ extern enum language set_language (enum language);
force_ellipses,options)) force_ellipses,options))
#define LA_EMIT_CHAR(ch, type, stream, quoter) \ #define LA_EMIT_CHAR(ch, type, stream, quoter) \
(current_language->la_emitchar(ch, type, stream, quoter)) (current_language->la_emitchar(ch, type, stream, quoter))
#define LA_GET_STRING(value, buffer, length, encoding) \ #define LA_GET_STRING(value, buffer, length, chartype, encoding) \
(current_language->la_get_string(value, buffer, length, encoding)) (current_language->la_get_string(value, buffer, length, chartype, encoding))
#define LA_PRINT_ARRAY_INDEX(index_value, stream, optins) \ #define LA_PRINT_ARRAY_INDEX(index_value, stream, optins) \
(current_language->la_print_array_index(index_value, stream, options)) (current_language->la_print_array_index(index_value, stream, options))
@ -497,9 +497,9 @@ void default_print_typedef (struct type *type, struct symbol *new_symbol,
struct ui_file *stream); struct ui_file *stream);
void default_get_string (struct value *value, gdb_byte **buffer, int *length, void default_get_string (struct value *value, gdb_byte **buffer, int *length,
const char **charset); struct type **char_type, const char **charset);
void c_get_string (struct value *value, gdb_byte **buffer, int *length, void c_get_string (struct value *value, gdb_byte **buffer, int *length,
const char **charset); struct type **char_type, const char **charset);
#endif /* defined (LANGUAGE_H) */ #endif /* defined (LANGUAGE_H) */

View file

@ -238,6 +238,7 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
const char *errors = NULL; const char *errors = NULL;
const char *user_encoding = NULL; const char *user_encoding = NULL;
const char *la_encoding = NULL; const char *la_encoding = NULL;
struct type *char_type;
static char *keywords[] = { "encoding", "errors", "length" }; static char *keywords[] = { "encoding", "errors", "length" };
if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords, if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
@ -246,12 +247,13 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
LA_GET_STRING (value, &buffer, &length, &la_encoding); LA_GET_STRING (value, &buffer, &length, &char_type, &la_encoding);
} }
GDB_PY_HANDLE_EXCEPTION (except); GDB_PY_HANDLE_EXCEPTION (except);
encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding; encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
unicode = PyUnicode_Decode (buffer, length, encoding, errors); unicode = PyUnicode_Decode (buffer, length * TYPE_LENGTH (char_type),
encoding, errors);
xfree (buffer); xfree (buffer);
return unicode; return unicode;

View file

@ -1,3 +1,7 @@
2009-09-25 Tom Tromey <tromey@redhat.com>
* gdb.base/charset.exp: Test utf-16 strings with Python.
2009-09-25 Tom Tromey <tromey@redhat.com> 2009-09-25 Tom Tromey <tromey@redhat.com>
* gdb.base/charset.exp: Use UTF-16 and UTF-32, not UCS-2 and * gdb.base/charset.exp: Use UTF-16 and UTF-32, not UCS-2 and

View file

@ -610,6 +610,26 @@ if {$ucs2_ok && $ucs4_ok} {
test_combination u UTF-16 U UTF-32 test_combination u UTF-16 U UTF-32
} }
if {$ucs2_ok} {
set go 1
gdb_test_multiple "python print 'hello, world!'" \
"verify python support for charset tests" {
-re "not supported.*$gdb_prompt $" {
unsupported "python support is disabled"
set go 0
}
-re "$gdb_prompt $" {}
}
if {$go} {
gdb_test "print u\"abcdef\"" " = u\"abcdef\"" \
"set up for python printing of utf-16 string"
gdb_test "python print gdb.history(0).string()" "abcdef" \
"extract utf-16 string using python"
}
}
# Regression test for a cleanup bug in the charset code. # Regression test for a cleanup bug in the charset code.
gdb_test "print 'a' == 'a' || 'b' == 'b'" \ gdb_test "print 'a' == 'a' || 'b' == 'b'" \
".* = 1" \ ".* = 1" \