2009-07-10 Phil Muldoon <pmuldoon@redhat.com>

* python/python-internal.h (apply_varobj_pretty_printer): Update
	definition.
	(python_string_to_target_python_string): Add definition.
	* python/python-utils.c (unicode_to_encoded_python_string)
	(unicode_to_target_python_string)
	(python_string_to_target_python_string): New Functions.
	* python/python-prettyprint.c (pretty_print_one_value): Likewise.
	(print_string_repr): Refactor to logic to account for PyObject
	returned strings.
	(apply_varobj_pretty_printer): Likewise.
	* python/python-value.c (valpy_string): Parse length keyword. Use
	length keyword in LA_GET_STRING.
	* varobj.c (value_get_print_value): Refactor logic to account for
	PyObject returned strings.
	* c-lang.c (c_get_string): If the length parameter is specified,
	use that. Return value in characters. Update comments.
	* language.h: Update c_get_string prototype comments.

2009-07-10  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.texinfo (Values From Inferior): Add length parameter
	description.

2009-07-10 Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python/python-prettyprint.c: Add counted null string
	structure.
	* gdb.python/python-prettyprint.exp: Print null string. Test for
	embedded nulls.
	* gdb.python/python-prettyprint.py (pp_ns): New Function.
	* gdb.python/python-value.exp (test_value_in_inferior): Add
	variable length string fetch tests.
	* gdb.python/python-value.c (main): Add strings for string fetch tests.
This commit is contained in:
Phil Muldoon 2009-07-10 10:35:17 +00:00
parent 041de40dc8
commit fbb8f2990c
16 changed files with 267 additions and 83 deletions

View file

@ -113,14 +113,15 @@ void gdbpy_print_stack (void);
PyObject *python_string_to_unicode (PyObject *obj);
char *unicode_to_target_string (PyObject *unicode_str);
char *python_string_to_target_string (PyObject *obj);
PyObject *python_string_to_target_python_string (PyObject *obj);
char *python_string_to_host_string (PyObject *obj);
PyObject *target_string_to_unicode (const gdb_byte *str, int length);
int gdbpy_is_string (PyObject *obj);
/* Note that these are declared here, and not in python.h with the
other pretty-printer functions, because they refer to PyObject. */
char *apply_varobj_pretty_printer (PyObject *print_obj,
struct value **replacement);
PyObject *apply_varobj_pretty_printer (PyObject *print_obj,
struct value **replacement);
PyObject *gdbpy_get_varobj_pretty_printer (struct value *value);
char *gdbpy_get_display_hint (PyObject *printer);
PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args);

View file

@ -121,34 +121,35 @@ find_pretty_printer (PyObject *value)
return function;
}
/* Pretty-print a single value, via the printer object PRINTER. If
the function returns a string, an xmalloc()d copy is returned.
Otherwise, if the function returns a value, a *OUT_VALUE is set to
the value, and NULL is returned. On error, *OUT_VALUE is set to
NULL and NULL is returned. */
static char *
/* Pretty-print a single value, via the printer object PRINTER.
If the function returns a string, a PyObject containing the string
is returned. Otherwise, if the function returns a value,
*OUT_VALUE is set to the value, and NULL is returned. On error,
*OUT_VALUE is set to NULL, and NULL is returned. */
static PyObject *
pretty_print_one_value (PyObject *printer, struct value **out_value)
{
char *output = NULL;
volatile struct gdb_exception except;
PyObject *result = NULL;
*out_value = NULL;
TRY_CATCH (except, RETURN_MASK_ALL)
{
PyObject *result;
result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL);
if (result)
{
if (gdbpy_is_string (result))
output = python_string_to_host_string (result);
else
*out_value = convert_value_from_python (result);
Py_DECREF (result);
if (! gdbpy_is_string (result))
{
*out_value = convert_value_from_python (result);
if (PyErr_Occurred ())
*out_value = NULL;
Py_DECREF (result);
result = NULL;
}
}
}
return output;
return result;
}
/* Return the display hint for the object printer, PRINTER. Return
@ -184,19 +185,28 @@ print_string_repr (PyObject *printer, const char *hint,
const struct language_defn *language,
struct gdbarch *gdbarch)
{
char *output;
struct value *replacement = NULL;
PyObject *py_str = NULL;
output = pretty_print_one_value (printer, &replacement);
if (output)
py_str = pretty_print_one_value (printer, &replacement);
if (py_str)
{
if (hint && !strcmp (hint, "string"))
LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char,
(gdb_byte *) output, strlen (output),
0, options);
PyObject *string = python_string_to_target_python_string (py_str);
if (string)
{
gdb_byte *output = PyString_AsString (string);
int len = PyString_Size (string);
if (hint && !strcmp (hint, "string"))
LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char,
output, len, 0, options);
else
fputs_filtered (output, stream);
Py_DECREF (string);
}
else
fputs_filtered (output, stream);
xfree (output);
gdbpy_print_stack ();
Py_DECREF (py_str);
}
else if (replacement)
common_val_print (replacement, stream, recurse, options, language);
@ -511,26 +521,30 @@ apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
return result;
}
/* Apply a pretty-printer for the varobj code. PRINTER_OBJ is the
print object. It must have a 'to_string' method (but this is
checked by varobj, not here) which takes no arguments and
returns a string. This function returns an xmalloc()d string if
the printer returns a string. The printer may return a replacement
value instead; in this case *REPLACEMENT is set to the replacement
value, and this function returns NULL. On error, *REPLACEMENT is
set to NULL and this function also returns NULL. */
char *
returns a string. The printer will return a value and in the case
of a Python string being returned, this function will return a
PyObject containing the string. For any other type, *REPLACEMENT is
set to the replacement value and this function returns NULL. On
error, *REPLACEMENT is set to NULL and this function also returns
NULL. */
PyObject *
apply_varobj_pretty_printer (PyObject *printer_obj,
struct value **replacement)
{
char *result;
int size = 0;
PyObject *py_str = NULL;
*replacement = NULL;
result = pretty_print_one_value (printer_obj, replacement);
if (result == NULL);
py_str = pretty_print_one_value (printer_obj, replacement);
if (*replacement == NULL && py_str == NULL)
gdbpy_print_stack ();
return result;
return py_str;
}
/* Find a pretty-printer object for the varobj module. Returns a new

View file

@ -104,6 +104,23 @@ unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
return result;
}
/* Returns a PyObject with the contents of the given unicode string
object converted to a named charset. If an error occurs during
the conversion, NULL will be returned and a python exception will
be set. */
static PyObject *
unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
{
PyObject *string;
/* Translate string to named charset. */
string = PyUnicode_AsEncodedString (unicode_str, charset, NULL);
if (string == NULL)
return NULL;
return string;
}
/* Returns a newly allocated string with the contents of the given unicode
string object converted to the target's charset. If an error occurs during
the conversion, NULL will be returned and a python exception will be set.
@ -115,6 +132,16 @@ unicode_to_target_string (PyObject *unicode_str)
return unicode_to_encoded_string (unicode_str, target_charset ());
}
/* Returns a PyObject with the contents of the given unicode string
object converted to the target's charset. If an error occurs
during the conversion, NULL will be returned and a python exception
will be set. */
PyObject *
unicode_to_target_python_string (PyObject *unicode_str)
{
return unicode_to_encoded_python_string (unicode_str, target_charset ());
}
/* Converts a python string (8-bit or unicode) to a target string in
the target's charset. Returns NULL on error, with a python exception set.
@ -134,6 +161,24 @@ python_string_to_target_string (PyObject *obj)
return result;
}
/* Converts a python string (8-bit or unicode) to a target string in the
target's charset. Returns NULL on error, with a python exception
set. */
PyObject *
python_string_to_target_python_string (PyObject *obj)
{
PyObject *str;
PyObject *result;
str = python_string_to_unicode (obj);
if (str == NULL)
return NULL;
result = unicode_to_target_python_string (str);
Py_DECREF (str);
return result;
}
/* Converts a python string (8-bit or unicode) to a target string in
the host's charset. Returns NULL on error, with a python exception set.

View file

@ -189,13 +189,16 @@ valpy_get_type (PyObject *self, void *closure)
return obj->type;
}
/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string
Return Unicode string with value contents. If ENCODING is not given,
the string is assumed to be encoded in the target's charset. */
/* Implementation of gdb.Value.string ([encoding] [, errors]
[, length]) -> string. Return Unicode string with value contents.
If ENCODING is not given, the string is assumed to be encoded in
the target's charset. If LENGTH is provided, only fetch string to
the length provided. */
static PyObject *
valpy_string (PyObject *self, PyObject *args, PyObject *kw)
{
int length, ret = 0;
int length = -1, ret = 0;
gdb_byte *buffer;
struct value *value = ((value_object *) self)->value;
volatile struct gdb_exception except;
@ -204,10 +207,10 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
const char *errors = NULL;
const char *user_encoding = NULL;
const char *la_encoding = NULL;
static char *keywords[] = { "encoding", "errors" };
static char *keywords[] = { "encoding", "errors", "length" };
if (!PyArg_ParseTupleAndKeywords (args, kw, "|ss", keywords,
&user_encoding, &errors))
if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
&user_encoding, &errors, &length))
return NULL;
TRY_CATCH (except, RETURN_MASK_ALL)
@ -937,7 +940,7 @@ static PyMethodDef value_object_methods[] = {
{ "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
{ "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
"string ([encoding] [, errors]) -> string\n\
"string ([encoding] [, errors] [, length]) -> string\n\
Return Unicode string representation of the value." },
{NULL} /* Sentinel */
};