2009-07-10 Phil Muldoon <pmuldoon@redhat.com>
authorPhil Muldoon <pmuldoon@redhat.com>
Fri, 10 Jul 2009 10:35:17 +0000 (10:35 +0000)
committerPhil Muldoon <pmuldoon@redhat.com>
Fri, 10 Jul 2009 10:35:17 +0000 (10:35 +0000)
* 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.

16 files changed:
gdb/ChangeLog
gdb/c-lang.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/language.h
gdb/python/python-internal.h
gdb/python/python-prettyprint.c
gdb/python/python-utils.c
gdb/python/python-value.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/python-prettyprint.c
gdb/testsuite/gdb.python/python-prettyprint.exp
gdb/testsuite/gdb.python/python-prettyprint.py
gdb/testsuite/gdb.python/python-value.c
gdb/testsuite/gdb.python/python-value.exp
gdb/varobj.c

index dfd6c44ae1f774faf6941f7259307971286c1ab0..ed7c6d5a4bc585c2c70b1e93ba38c0d38531cca8 100644 (file)
@@ -1,3 +1,23 @@
+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-09  Doug Evans  <dje@google.com>
 
        * i386-tdep.c (i386_displaced_step_fixup): Fix order of arguments
index 5cbecd26b5c941e4550cdc0488a2b0b1c431601e..4ba81ba86aa637bfa643d0da31766e4dce44da65 100644 (file)
@@ -604,18 +604,17 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
 }
 
 /* Obtain a C string from the inferior storing it in a newly allocated
-   buffer in BUFFER, which should be freed by the caller.  The string is
-   read until a null character is found. If VALUE is an array with known
-   length, the function will not read past the end of the array.  LENGTH
-   will contain the size of the string in bytes (not counting the null
-   character).
-
-   Assumes strings are terminated by a null character.  The size of a character
-   is determined by the length of the target type of the pointer or array.
-   This means that a null byte present in a multi-byte character will not
-   terminate the string unless the whole character is null.
-
-   CHARSET is always set to the target charset.  */
+   buffer in BUFFER, which should be freed by the caller.   If the
+   in- and out-parameter *LENGTH is specified at -1, the string is read
+   until a null character of the appropriate width is found, otherwise
+   the string is read to the length of characters specified.
+   The size of a character is determined by the length of the target
+   type of the pointer or  array.  If VALUE is an array with a known
+   length, the function will  not read past the end of the array.
+   On completion, *LENGTH will be set to the size of the string read in
+   characters.  (If a length of -1 is specified, the length returned
+   will not include the null character).  CHARSET is always set to the
+   target charset.  */
 
 void
 c_get_string (struct value *value, gdb_byte **buffer, int *length,
@@ -625,6 +624,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
   unsigned int fetchlimit;
   struct type *type = check_typedef (value_type (value));
   struct type *element_type = TYPE_TARGET_TYPE (type);
+  int req_length = *length;
   enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
 
   if (element_type == NULL)
@@ -661,7 +661,7 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
 
   width = TYPE_LENGTH (element_type);
 
-  /* If the string lives in GDB's memory intead of the inferior's, then we
+  /* If the string lives in GDB's memory instead of the inferior's, then we
      just need to copy it to BUFFER.  Also, since such strings are arrays
      with known size, FETCHLIMIT will hold the size of the array.  */
   if ((VALUE_LVAL (value) == not_lval
@@ -671,13 +671,18 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
       int i;
       const gdb_byte *contents = value_contents (value);
 
-      /* Look for a null character.  */
-      for (i = 0; i < fetchlimit; i++)
-       if (extract_unsigned_integer (contents + i * width, width,
-                                     byte_order) == 0)
-         break;
-
-      /* I is now either the number of non-null characters, or FETCHLIMIT.  */
+      /* If a length is specified, use that.  */
+      if (*length >= 0)
+       i  = *length;
+      else
+       /* Otherwise, look for a null character.  */
+       for (i = 0; i < fetchlimit; i++)
+         if (extract_unsigned_integer (contents + i * width, width,
+                                       byte_order) == 0)
+           break;
+  
+      /* I is now either a user-defined length, the number of non-null
+        characters, or FETCHLIMIT.  */
       *length = i * width;
       *buffer = xmalloc (*length);
       memcpy (*buffer, contents, *length);
@@ -685,8 +690,8 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
     }
   else
     {
-      err = read_string (value_as_address (value), -1, width, fetchlimit,
-                        byte_order, buffer, length);
+      err = read_string (value_as_address (value), *length, width, fetchlimit,
+                        byte_order, buffer, length);
       if (err)
        {
          xfree (*buffer);
@@ -695,11 +700,22 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
        }
     }
 
-  /* If the last character is null, subtract it from LENGTH.  */
-  if (*length > 0
-      && extract_unsigned_integer (*buffer + *length - width, width,
-                                  byte_order) == 0)
-    *length -= width;
+  /* If the LENGTH is specified at -1, we want to return the string
+     length up to the terminating null character.  If an actual length
+     was specified, we want to return the length of exactly what was
+     read.  */
+  if (req_length == -1)
+    /* If the last character is null, subtract it from LENGTH.  */
+    if (*length > 0
+       && extract_unsigned_integer (*buffer + *length - width, width,
+                                    byte_order) == 0)
+      *length -= width;
+  
+  /* The read_string function will return the number of bytes read.
+     If length returned from read_string was > 0, return the number of
+     characters read by dividing the number of bytes by width.  */
+  if (*length != 0)
+     *length = *length / width;
 
   *charset = target_charset ();
 
index fd70a89b023a9463dbbc45f862e4649077c7146a..ff5bff653a964dd98139217b3960eee09b3ba14b 100644 (file)
@@ -1,3 +1,8 @@
+2009-07-10  Phil Muldoon  <pmuldoon@redhat.com>
+
+       * gdb.texinfo (Values From Inferior): Add length parameter
+       description.
+
 2009-07-04  Chris Genly  <chris@genly.us>
 
        * gdb.texinfo (GDB/MI Variable Objects): Document child definition
index ab36fa64fbdc226faf06269b9c37067faa241945..0a59f980219f4c6d58fb7d1cf8a82036287a5462 100644 (file)
@@ -18894,7 +18894,7 @@ The result @code{bar} will be a @code{gdb.Value} object holding the
 value pointed to by @code{foo}.
 @end defmethod
 
-@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]}
+@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]} @r{[}length@r{]}
 If this @code{gdb.Value} represents a string, then this method
 converts the contents to a Python string.  Otherwise, this method will
 throw an exception.
@@ -18905,7 +18905,9 @@ language.
 
 For C-like languages, a value is a string if it is a pointer to or an
 array of characters or ints.  The string is assumed to be terminated
-by a zero of the appropriate width.
+by a zero of the appropriate width.  However if the optional length
+argument is given, the string will be converted to that given length,
+ignoring any embedded zeros that the string may contain.
 
 If the optional @var{encoding} argument is given, it must be a string
 naming the encoding of the string in the @code{gdb.Value}, such as
@@ -18919,6 +18921,9 @@ will be used, if the current language is able to supply one.
 
 The optional @var{errors} argument is the same as the corresponding
 argument to Python's @code{string.decode} method.
+
+If the optional @var{length} argument is given, the string will be
+fetched and converted to the given length.
 @end defmethod
 @end table
 
index e5f80abfd71b71ab29207f99af9012aa87ae4c54..ba37faa33790a6d9dac9463d8000c392e397d3fe 100644 (file)
@@ -284,10 +284,15 @@ struct language_defn
     int (*la_pass_by_reference) (struct type *type);
 
     /* Obtain a string from the inferior, storing it in a newly allocated
-       buffer in BUFFER, which should be freed by the caller.  LENGTH will
-       hold the size in bytes of the string (only actual characters, excluding
-       an eventual terminating null character).  CHARSET will hold the encoding
-       used in the string.  */
+       buffer in BUFFER, which should be freed by the caller.  If the
+       in- and out-parameter *LENGTH is specified at -1, the string is
+       read until a null character of the appropriate width is found -
+       otherwise the string is read to the length of characters specified.
+       On completion, *LENGTH will hold the size of the string in characters.
+       If a *LENGTH of -1 was specified it will count only actual
+       characters, excluding any eventual terminating null character.
+       Otherwise *LENGTH will include all characters - including any nulls.
+       CHARSET will hold the encoding used in the string.  */
     void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
                          const char **charset);
 
index 39d37e11eeec1b7ced898ea9125267db16afeb9e..67a78af083e1fb86bde248ef846e8d540c99c08d 100644 (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);
index 57e517a14ed84ad48dae935f36c3628e4a0328a2..5d696c86d3df08b8ae4e5bb157323bfa4165e8ea 100644 (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
index 9f6fe076792a806296aa88cbb8e9dea6c524c6e4..49c0437c13880242f1bc95ff5148faa1e3c020ae 100644 (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.
 
index a0bf2db6204a027996117dff33fa01b08c8f364e..dd3c919786cf02b69ba3ff2125f32abd748f4679 100644 (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 */
 };
index 340900267377bc16799e6701e803d27a811b927d..d1ac5a46cbebd0c1442436e5c1de5c7abc66d92c 100644 (file)
@@ -1,3 +1,14 @@
+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.
+
 2009-07-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.base/dump.exp (inaccessible memory is reported): New test.
index 399be23c3a15013c4656ba598e1ff963df6b0273..3cafc48200764c3fdfd93eef00275451ddd0e75d 100644 (file)
@@ -27,6 +27,11 @@ struct ss
   struct s b;
 };
 
+struct ns {
+  const char *null_str;
+  int length;
+};
+
 #ifdef __cplusplus
 struct S : public s {
   int zs;
@@ -156,6 +161,10 @@ main ()
   init_ss(ssa+0, 3, 4);
   init_ss(ssa+1, 5, 6);
 
+  struct ns  ns;
+  ns.null_str = "embedded\0null\0string";
+  ns.length = 20;
+
 #ifdef __cplusplus
   S cps;
 
index f83b1cdccd0ebfda63fcdd07b13f81d57acfd5a6..01d4a06c89f4550f08f4db22f4974537039dc6b3 100644 (file)
@@ -78,6 +78,7 @@ proc run_lang_tests {lang} {
        gdb_test "print ref" "= a=<15> b=< a=<8> b=<$hex>>"
        gdb_test "print derived" \
            " = \{.*<Vbase1> = pp class name: Vbase1.*<Vbase2> = \{.*<VirtualTest> = pp value variable is: 1,.*members of Vbase2:.*_vptr.Vbase2 = $hex.*<Vbase3> = \{.*members of Vbase3.*members of Derived:.*value = 2.*"
+       gdb_test "print ns " "\"embedded\\\\000null\\\\000string\""
     }
 
     gdb_test "print x" " = $hex \"this is x\""
index 493cf29312cf98706c3777d722b88492556a5849..bf009a1e6c177c374e024bc07c1b6c9eb515f521 100644 (file)
@@ -92,6 +92,19 @@ class pp_vbase1:
     def to_string (self):
         return "pp class name: " + self.val.type.tag
 
+class pp_ns:
+    "Print a std::basic_string of some kind"
+
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        len = self.val['length']
+        return self.val['null_str'].string (gdb.parameter ('target-charset'), length = len)
+
+    def display_hint (self):
+        return 'string'
+
 def lookup_function (val):
     "Look-up and return a pretty-printer that can print val."
 
@@ -145,6 +158,8 @@ def register_pretty_printers ():
     pretty_printers_dict[re.compile ('^string_repr$')] = string_print
     pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter
     
+    pretty_printers_dict[re.compile ('^struct ns$')]  = pp_ns
+    pretty_printers_dict[re.compile ('^ns$')]  = pp_ns
 pretty_printers_dict = {}
 
 register_pretty_printers ()
index 092c520743359c31fc0c608920e94189e6c1c49b..f3d62845369ea0a534d8792ec0ec17638c0ccf18 100644 (file)
@@ -44,6 +44,8 @@ main (int argc, char *argv[])
   struct s s;
   union u u;
   PTR x = &s;
+  char st[17] = "divide et impera";
+  char nullst[17] = "divide\0et\0impera";
 
   s.a = 3;
   s.b = 5;
index 20333f6cd67260bddcbc1c0747382ecb2e6f864b..19cabeb6c7e14e416907b3915e3130b1a2d2ecde 100644 (file)
@@ -234,6 +234,25 @@ proc test_value_in_inferior {} {
 
   # Test address attribute
   gdb_test "python print 'result =', arg0.address" "= 0x\[\[:xdigit:\]\]+" "Test address attribute"
+
+  # Test string fetches,  both partial and whole.
+  gdb_test "print st" "\"divide et impera\""
+  gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value from history" 1
+  gdb_test "python print st.string ()"  "divide et impera"  "Test string with no length"
+  gdb_test "python print st.string (length = -1)" "divide et impera" "Test string (length = -1) is all of the string"
+  gdb_test "python print st.string (length = 6)" "divide"
+  gdb_test "python print \"---\"+st.string (length = 0)+\"---\"" "------" "Test string (length = 0) is empty"
+  gdb_test "python print len(st.string (length = 0))" "0" "Test length is 0"
+
+
+  # Fetch a string that has embedded nulls.
+  gdb_test "print nullst" "\"divide\\\\000et\\\\000impera\".*"
+  gdb_py_test_silent_cmd "python nullst = gdb.history (0)" "get value from history" 1
+  gdb_test "python print nullst.string ()" "divide" "Test string to first null"
+  # Python cannot print strings that contain the null (\0) character.
+  # For the purposes of this test, use repr()
+  gdb_py_test_silent_cmd "python nullst = nullst.string (length = 9)" "get string beyond null" 1
+  gdb_test "python print repr(nullst)" "u'divide\\\\x00et'"
 }
 
 # A few objfile tests.
index dac0413ecb98c4d027e63412a53d08a097b96020..5d6974306c753f8958c4a99d86f3f229259f6ce5 100644 (file)
@@ -2221,8 +2221,9 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
   long dummy;
   struct ui_file *stb;
   struct cleanup *old_chain;
-  char *thevalue = NULL;
+  gdb_byte *thevalue = NULL;
   struct value_print_options opts;
+  int len = 0;
 
   if (value == NULL)
     return NULL;
@@ -2238,6 +2239,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
        char *hint;
        struct value *replacement;
        int string_print = 0;
+       PyObject *output = NULL;
 
        hint = gdbpy_get_display_hint (value_formatter);
        if (hint)
@@ -2247,8 +2249,20 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
            xfree (hint);
          }
 
-       thevalue = apply_varobj_pretty_printer (value_formatter,
-                                               &replacement);
+       output = apply_varobj_pretty_printer (value_formatter,
+                                             &replacement);
+       if (output)
+         {
+           PyObject *py_str = python_string_to_target_python_string (output);
+           if (py_str)
+             {
+               char *s = PyString_AsString (py_str);
+               len = PyString_Size (py_str);
+               thevalue = xmemdup (s, len + 1, len + 1);
+               Py_DECREF (py_str);
+             }
+           Py_DECREF (output);
+         }
        if (thevalue && !string_print)
          {
            do_cleanups (back_to);
@@ -2272,8 +2286,7 @@ value_get_print_value (struct value *value, enum varobj_display_formats format,
       struct gdbarch *gdbarch = get_type_arch (value_type (value));
       make_cleanup (xfree, thevalue);
       LA_PRINT_STRING (stb, builtin_type (gdbarch)->builtin_char,
-                      (gdb_byte *) thevalue, strlen (thevalue),
-                      0, &opts);
+                      thevalue, len, 0, &opts);
     }
   else
     common_val_print (value, stb, 0, &opts, current_language);
This page took 0.091009 seconds and 4 git commands to generate.