From: Phil Muldoon <pmuldoon@redhat.com>
To: Project Archer <archer@sourceware.org>
Subject: [python][patch] Add options length parameter to value.string(...)
Date: Mon, 06 Apr 2009 16:54:00 -0000 [thread overview]
Message-ID: <49DA33CE.9070803@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 869 bytes --]
This patch adds an optional length parameter to the value.string()
method. This allows partial string fetches, and string fetches that
ignore embedded null characters in the C/C++ string case. If the length
parameter is omitted, the method will maintain the existing behaviour of
fetching a string until a terminating null in the C/C++ case.
Regards
Phil
ChangeLog
2009-04-06 Phil Muldoon <pmuldoon@redhat.com>
* python/python-value.c (valpy_string): Parse length keyword. Use
length keyword in LA_GET_STRING.
* c-lang.c (c_get_string): If the length parameter is specified,
use that.
testsuite/ChangeLog
2009-04-06 Phil Muldoon <pmuldoon@redhat.com>
* 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.
[-- Attachment #2: valpy_variable_string_fetch.patch --]
[-- Type: text/x-patch, Size: 4957 bytes --]
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 8b5410f..344c836 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -249,12 +249,17 @@ 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) == 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) == 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);
@@ -262,7 +267,10 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
}
else
{
- err = read_string (value_as_address (value), -1, width, fetchlimit,
+ /* Copy length to orig_len, as read_string will write the number
+ of characters 'read' to length. */
+ int orig_len = *length;
+ err = read_string (value_as_address (value), orig_len, width, fetchlimit,
buffer, length);
if (err)
{
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index b55463c..a308a7a 100644
--- a/gdb/python/python-value.c
+++ b/gdb/python/python-value.c
@@ -179,7 +179,7 @@ valpy_type (PyObject *self, PyObject *args)
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;
@@ -188,10 +188,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)
@@ -957,7 +957,7 @@ static PyMethodDef value_object_methods[] = {
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
{ "type", valpy_type, METH_NOARGS, "Return type of 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 */
};
diff --git a/gdb/testsuite/gdb.python/python-value.c b/gdb/testsuite/gdb.python/python-value.c
index 092c520..f3d6284 100644
--- a/gdb/testsuite/gdb.python/python-value.c
+++ b/gdb/testsuite/gdb.python/python-value.c
@@ -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;
diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp
index cbcf91f..9169fc7 100644
--- a/gdb/testsuite/gdb.python/python-value.exp
+++ b/gdb/testsuite/gdb.python/python-value.exp
@@ -234,6 +234,23 @@ 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"
+
+ # 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'"
}
proc test_value_after_death {} {
next reply other threads:[~2009-04-06 16:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-06 16:54 Phil Muldoon [this message]
2009-04-06 22:14 ` Tom Tromey
2009-04-06 22:33 ` Thiago Jung Bauermann
2009-04-09 9:58 ` Phil Muldoon
2009-04-09 16:08 ` Thiago Jung Bauermann
2009-04-09 16:28 ` Phil Muldoon
2009-04-09 18:46 ` Thiago Jung Bauermann
2009-04-09 20:28 ` Phil Muldoon
2009-04-09 20:39 ` Thiago Jung Bauermann
2009-04-09 16:12 ` Phil Muldoon
2009-04-09 20:39 ` Thiago Jung Bauermann
2009-04-09 21:29 ` Phil Muldoon
2009-04-13 22:08 ` Tom Tromey
2009-04-15 9:13 ` Phil Muldoon
2009-04-15 9:37 ` Phil Muldoon
2009-04-15 12:37 ` Tom Tromey
2009-04-15 14:52 ` Phil Muldoon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49DA33CE.9070803@redhat.com \
--to=pmuldoon@redhat.com \
--cc=archer@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).