2009-02-04  Tom Tromey  <tromey@redhat.com>
	    Thiago Jung Bauermann  <bauerman@br.ibm.com>
	    Phil Muldoon  <pmuldoon@redhat.com>

	* python/python-internal.h (gdbpy_get_value_from_history): Rename
	prototype to gdbpy_history.
	(gdbpy_is_string): Declare.
	(python_string_to_host_string): Declare.
	* python/python-utils.c (gdbpy_is_string): New function.
	(unicode_to_encoded_string): New function.
	(unicode_to_target_string): Use it.
	(python_string_to_host_string): New function.
	* python/python-value.c (valpy_address): New function.
	(convert_value_from_python): Use gdbpy_is_string.  Change to throw
	Python exception instead of a GDB exception on error.  Properly check
	Python booleans.
	(valpy_getitem): Convert field name to host string.  Handle array
	accesses.  Adapt to new behaviour of convert_value_from_python.
	(valpy_new): Adapt to new behaviour of convert_value_from_python.
	(enum valpy_opcode) <VALPY_LSH, VALPY_RSH, VALPY_BITAND,
	VALPY_BITXOR, VALPY_BITOR>: New constants.
	(valpy_binop): Update.  Adapt to new behaviour of
	convert_value_from_python.
	(valpy_invert): New function.
	(valpy_lsh): Likewise.
	(valpy_rsh): Likewise.
	(valpy_and): Likewise.
	(valpy_or): Likewise.
	(valpy_xor): Likewise.
	(valpy_richcompare): Call convert_value_from_python instead of doing
	conversions itself.
	(is_intlike, valpy_int, valpy_long, valpy_float): New functions.
	(gdbpy_get_value_from_history): Rename
	function to gdbpy_history.
	(gdbpy_initialize_values): Don't set tp_new.
	(value_object_type): Add valpy_new.
	(value_object_methods): Add `address' entry.
	(value_object_as_number): Update for new methods.
	* python/python.c (GdbMethods): Rename entry from
	`get_value_from_history' to `history'.

gdb/doc/
2009-02-04  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Basic Python): Document gdb.history.

gdb/testsuite/
2009-02-04  Tom Tromey  <tromey@redhat.com>
	    Thiago Jung Bauermann  <bauerman@br.ibm.com>

	* gdb.python/python-value.exp: Use `gdb.history' instead of
	`gdb.value_from_history'.
	(test_value_numeric_ops): Add test for conversion of enum constant.
	* gdb.python/python-value.c (enum e): New type.
	(evalue): New global.
	(main): Use argv.
This commit is contained in:
Thiago Jung Bauermann 2009-02-04 21:55:40 +00:00
parent 20261af84c
commit 08c637dee2
10 changed files with 436 additions and 117 deletions

View file

@ -1,3 +1,44 @@
2009-02-04 Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
Phil Muldoon <pmuldoon@redhat.com>
* python/python-internal.h (gdbpy_get_value_from_history): Rename
prototype to gdbpy_history.
(gdbpy_is_string): Declare.
(python_string_to_host_string): Declare.
* python/python-utils.c (gdbpy_is_string): New function.
(unicode_to_encoded_string): New function.
(unicode_to_target_string): Use it.
(python_string_to_host_string): New function.
* python/python-value.c (valpy_address): New function.
(convert_value_from_python): Use gdbpy_is_string. Change to throw
Python exception instead of a GDB exception on error. Properly check
Python booleans.
(valpy_getitem): Convert field name to host string. Handle array
accesses. Adapt to new behaviour of convert_value_from_python.
(valpy_new): Adapt to new behaviour of convert_value_from_python.
(enum valpy_opcode) <VALPY_LSH, VALPY_RSH, VALPY_BITAND,
VALPY_BITXOR, VALPY_BITOR>: New constants.
(valpy_binop): Update. Adapt to new behaviour of
convert_value_from_python.
(valpy_invert): New function.
(valpy_lsh): Likewise.
(valpy_rsh): Likewise.
(valpy_and): Likewise.
(valpy_or): Likewise.
(valpy_xor): Likewise.
(valpy_richcompare): Call convert_value_from_python instead of doing
conversions itself.
(is_intlike, valpy_int, valpy_long, valpy_float): New functions.
(gdbpy_get_value_from_history): Rename
function to gdbpy_history.
(gdbpy_initialize_values): Don't set tp_new.
(value_object_type): Add valpy_new.
(value_object_methods): Add `address' entry.
(value_object_as_number): Update for new methods.
* python/python.c (GdbMethods): Rename entry from
`get_value_from_history' to `history'.
2009-02-04 Jerome Guitton <guitton@adacore.com> 2009-02-04 Jerome Guitton <guitton@adacore.com>
* ada-lang.c (ada_template_to_fixed_record_type_1): Check size * ada-lang.c (ada_template_to_fixed_record_type_1): Check size

View file

@ -1,3 +1,7 @@
2009-02-04 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Basic Python): Document gdb.history.
2009-01-30 Vladimir Prus <vladimir@codesourcery.com> 2009-01-30 Vladimir Prus <vladimir@codesourcery.com>
* gdb.texinfo (GDB/MI Thread Commands): Document the * gdb.texinfo (GDB/MI Thread Commands): Document the

View file

@ -18097,6 +18097,21 @@ If the named parameter does not exist, this function throws a
a Python value of the appropriate type, and returned. a Python value of the appropriate type, and returned.
@end defun @end defun
@findex gdb.history
@defun history number
Return a value from @value{GDBN}'s value history (@pxref{Value
History}). @var{number} indicates which history element to return.
If @var{number} is negative, then @value{GDBN} will take its absolute value
and count backward from the last element (i.e., the most recent element) to
find the value to return. If @var{number} is zero, then @value{GDBN} will
return the most recent element. If the element specified by @value{number}
doesn't exist in the value history, a @code{RuntimeError} exception will be
raised.
If no exception is raised, the return value is always an instance of
@code{gdb.Value} (@pxref{Values From Inferior}).
@end defun
@findex gdb.write @findex gdb.write
@defun write string @defun write string
Print a string to @value{GDBN}'s paginated standard output stream. Print a string to @value{GDBN}'s paginated standard output stream.

View file

@ -63,7 +63,7 @@ struct value;
extern PyObject *gdb_module; extern PyObject *gdb_module;
extern PyTypeObject value_object_type; extern PyTypeObject value_object_type;
PyObject *gdbpy_get_value_from_history (PyObject *self, PyObject *args); PyObject *gdbpy_history (PyObject *self, PyObject *args);
PyObject *value_to_value_object (struct value *v); PyObject *value_to_value_object (struct value *v);
@ -90,5 +90,7 @@ void gdbpy_print_stack (void);
PyObject *python_string_to_unicode (PyObject *obj); PyObject *python_string_to_unicode (PyObject *obj);
char *unicode_to_target_string (PyObject *unicode_str); char *unicode_to_target_string (PyObject *unicode_str);
char *python_string_to_target_string (PyObject *obj); char *python_string_to_target_string (PyObject *obj);
char *python_string_to_host_string (PyObject *obj);
int gdbpy_is_string (PyObject *obj);
#endif /* GDB_PYTHON_INTERNAL_H */ #endif /* GDB_PYTHON_INTERNAL_H */

View file

@ -94,6 +94,29 @@ python_string_to_unicode (PyObject *obj)
return unicode_str; return unicode_str;
} }
/* Returns a newly allocated string with the contents of the given unicode
string object converted to CHARSET. If an error occurs during the
conversion, NULL will be returned and a python exception will be set.
The caller is responsible for xfree'ing the string. */
static char *
unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
{
char *result;
PyObject *string;
/* Translate string to named charset. */
string = PyUnicode_AsEncodedString (unicode_str, charset, NULL);
if (string == NULL)
return NULL;
result = xstrdup (PyString_AsString (string));
Py_DECREF (string);
return result;
}
/* Returns a newly allocated string with the contents of the given unicode /* 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 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. the conversion, NULL will be returned and a python exception will be set.
@ -102,19 +125,7 @@ python_string_to_unicode (PyObject *obj)
char * char *
unicode_to_target_string (PyObject *unicode_str) unicode_to_target_string (PyObject *unicode_str)
{ {
char *target_string; return unicode_to_encoded_string (unicode_str, target_charset ());
PyObject *string;
/* Translate string to target's charset. */
string = PyUnicode_AsEncodedString (unicode_str, target_charset (), NULL);
if (string == NULL)
return NULL;
target_string = xstrdup (PyString_AsString (string));
Py_DECREF (string);
return target_string;
} }
/* Converts a python string (8-bit or unicode) to a target string in /* Converts a python string (8-bit or unicode) to a target string in
@ -132,3 +143,28 @@ python_string_to_target_string (PyObject *obj)
return unicode_to_target_string (str); return unicode_to_target_string (str);
} }
/* 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.
The caller is responsible for xfree'ing the string. */
char *
python_string_to_host_string (PyObject *obj)
{
PyObject *str;
str = python_string_to_unicode (obj);
if (str == NULL)
return NULL;
return unicode_to_encoded_string (str, host_charset ());
}
/* Return true if OBJ is a Python string or unicode object, false
otherwise. */
int
gdbpy_is_string (PyObject *obj)
{
return PyString_Check (obj) || PyUnicode_Check (obj);
}

View file

@ -18,6 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h" #include "defs.h"
#include "gdb_assert.h"
#include "charset.h" #include "charset.h"
#include "value.h" #include "value.h"
#include "exceptions.h" #include "exceptions.h"
@ -79,7 +80,6 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
{ {
struct value *value = NULL; /* Initialize to appease gcc warning. */ struct value *value = NULL; /* Initialize to appease gcc warning. */
value_object *value_obj; value_object *value_obj;
volatile struct gdb_exception except;
if (PyTuple_Size (args) != 1) if (PyTuple_Size (args) != 1)
{ {
@ -96,16 +96,11 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
return NULL; return NULL;
} }
TRY_CATCH (except, RETURN_MASK_ALL) value = convert_value_from_python (PyTuple_GetItem (args, 0));
{ if (value == NULL)
value = convert_value_from_python (PyTuple_GetItem (args, 0));
}
if (except.reason < 0)
{ {
subtype->tp_free (value_obj); subtype->tp_free (value_obj);
return PyErr_Format (except.reason == RETURN_QUIT return NULL;
? PyExc_KeyboardInterrupt : PyExc_TypeError,
"%s", except.message);
} }
value_obj->value = value; value_obj->value = value;
@ -132,6 +127,22 @@ valpy_dereference (PyObject *self, PyObject *args)
return value_to_value_object (res_val); return value_to_value_object (res_val);
} }
/* Return "&value". */
static PyObject *
valpy_address (PyObject *self, PyObject *args)
{
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
volatile struct gdb_exception except;
TRY_CATCH (except, RETURN_MASK_ALL)
{
res_val = value_addr (((value_object *) self)->value);
}
GDB_PY_HANDLE_EXCEPTION (except);
return value_to_value_object (res_val);
}
static Py_ssize_t static Py_ssize_t
valpy_length (PyObject *self) valpy_length (PyObject *self)
{ {
@ -147,25 +158,39 @@ static PyObject *
valpy_getitem (PyObject *self, PyObject *key) valpy_getitem (PyObject *self, PyObject *key)
{ {
value_object *self_value = (value_object *) self; value_object *self_value = (value_object *) self;
char *field; char *field = NULL;
struct value *idx = NULL;
struct value *res_val = NULL; /* Initialize to appease gcc warning. */ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
struct cleanup *old;
volatile struct gdb_exception except; volatile struct gdb_exception except;
field = python_string_to_target_string (key); if (gdbpy_is_string (key))
if (field == NULL) {
return NULL; field = python_string_to_host_string (key);
if (field == NULL)
old = make_cleanup (xfree, field); return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
struct value *tmp = self_value->value; struct value *tmp = self_value->value;
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
}
GDB_PY_HANDLE_EXCEPTION (except);
do_cleanups (old); if (field)
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
else
{
/* Assume we are attempting an array access, and let the
value code throw an exception if the index has an invalid
type. */
struct value *idx = convert_value_from_python (key);
if (idx == NULL)
return NULL;
res_val = value_subscript (tmp, idx);
}
}
if (field)
xfree (field);
GDB_PY_HANDLE_EXCEPTION (except);
return value_to_value_object (res_val); return value_to_value_object (res_val);
} }
@ -220,7 +245,12 @@ enum valpy_opcode
VALPY_MUL, VALPY_MUL,
VALPY_DIV, VALPY_DIV,
VALPY_REM, VALPY_REM,
VALPY_POW VALPY_POW,
VALPY_LSH,
VALPY_RSH,
VALPY_BITAND,
VALPY_BITOR,
VALPY_BITXOR
}; };
/* If TYPE is a reference, return the target; otherwise return TYPE. */ /* If TYPE is a reference, return the target; otherwise return TYPE. */
@ -244,7 +274,12 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
kind of object, altogether. Because of this, we can't assume self is kind of object, altogether. Because of this, we can't assume self is
a gdb.Value object and need to convert it from python as well. */ a gdb.Value object and need to convert it from python as well. */
arg1 = convert_value_from_python (self); arg1 = convert_value_from_python (self);
if (arg1 == NULL)
return NULL;
arg2 = convert_value_from_python (other); arg2 = convert_value_from_python (other);
if (arg2 == NULL)
return NULL;
switch (opcode) switch (opcode)
{ {
@ -302,6 +337,21 @@ valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
case VALPY_POW: case VALPY_POW:
res_val = value_binop (arg1, arg2, BINOP_EXP); res_val = value_binop (arg1, arg2, BINOP_EXP);
break; break;
case VALPY_LSH:
res_val = value_binop (arg1, arg2, BINOP_LSH);
break;
case VALPY_RSH:
res_val = value_binop (arg1, arg2, BINOP_RSH);
break;
case VALPY_BITAND:
res_val = value_binop (arg1, arg2, BINOP_BITWISE_AND);
break;
case VALPY_BITOR:
res_val = value_binop (arg1, arg2, BINOP_BITWISE_IOR);
break;
case VALPY_BITXOR:
res_val = value_binop (arg1, arg2, BINOP_BITWISE_XOR);
break;
} }
} }
GDB_PY_HANDLE_EXCEPTION (except); GDB_PY_HANDLE_EXCEPTION (except);
@ -412,45 +462,66 @@ valpy_nonzero (PyObject *self)
} }
} }
/* Implements ~ for value objects. */
static PyObject *
valpy_invert (PyObject *self)
{
struct value *val = NULL;
volatile struct gdb_exception except;
TRY_CATCH (except, RETURN_MASK_ALL)
{
val = value_complement (((value_object *) self)->value);
}
GDB_PY_HANDLE_EXCEPTION (except);
return value_to_value_object (val);
}
/* Implements left shift for value objects. */
static PyObject *
valpy_lsh (PyObject *self, PyObject *other)
{
return valpy_binop (VALPY_LSH, self, other);
}
/* Implements right shift for value objects. */
static PyObject *
valpy_rsh (PyObject *self, PyObject *other)
{
return valpy_binop (VALPY_RSH, self, other);
}
/* Implements bitwise and for value objects. */
static PyObject *
valpy_and (PyObject *self, PyObject *other)
{
return valpy_binop (VALPY_BITAND, self, other);
}
/* Implements bitwise or for value objects. */
static PyObject *
valpy_or (PyObject *self, PyObject *other)
{
return valpy_binop (VALPY_BITOR, self, other);
}
/* Implements bitwise xor for value objects. */
static PyObject *
valpy_xor (PyObject *self, PyObject *other)
{
return valpy_binop (VALPY_BITXOR, self, other);
}
/* Implements comparison operations for value objects. */ /* Implements comparison operations for value objects. */
static PyObject * static PyObject *
valpy_richcompare (PyObject *self, PyObject *other, int op) valpy_richcompare (PyObject *self, PyObject *other, int op)
{ {
int result = 0; int result = 0;
struct value *value_self, *value_other; struct value *value_other;
volatile struct gdb_exception except; volatile struct gdb_exception except;
if (PyObject_TypeCheck (other, &value_object_type)) if (other == Py_None)
value_other = ((value_object *) other)->value;
else if (PyInt_Check (other))
{
LONGEST l;
l = PyInt_AsLong (other);
if (PyErr_Occurred ())
return NULL;
value_other = value_from_longest (builtin_type_pyint, l);
}
else if (PyFloat_Check (other))
{
DOUBLEST d;
d = PyFloat_AsDouble (other);
if (PyErr_Occurred ())
return NULL;
value_other = value_from_double (builtin_type_pyfloat, d);
}
else if (PyString_Check (other) || PyUnicode_Check (other))
{
char *str;
str = python_string_to_target_string (other);
value_other = value_from_string (str);
xfree (str);
}
else if (other == Py_None)
/* Comparing with None is special. From what I can tell, in Python /* Comparing with None is special. From what I can tell, in Python
None is smaller than anything else. */ None is smaller than anything else. */
switch (op) { switch (op) {
@ -468,15 +539,13 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
"Invalid operation on gdb.Value."); "Invalid operation on gdb.Value.");
return NULL; return NULL;
} }
else
{
PyErr_SetString (PyExc_NotImplementedError,
"Operation not supported on gdb.Value of this type.");
return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL) TRY_CATCH (except, RETURN_MASK_ALL)
{ {
value_other = convert_value_from_python (other);
if (value_other == NULL)
return NULL;
switch (op) { switch (op) {
case Py_LT: case Py_LT:
result = value_less (((value_object *) self)->value, value_other); result = value_less (((value_object *) self)->value, value_other);
@ -513,6 +582,92 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }
/* Helper function to determine if a type is "int-like". */
static int
is_intlike (struct type *type, int ptr_ok)
{
CHECK_TYPEDEF (type);
return (TYPE_CODE (type) == TYPE_CODE_INT
|| TYPE_CODE (type) == TYPE_CODE_ENUM
|| TYPE_CODE (type) == TYPE_CODE_BOOL
|| TYPE_CODE (type) == TYPE_CODE_CHAR
|| (ptr_ok && TYPE_CODE (type) == TYPE_CODE_PTR));
}
/* Implements conversion to int. */
static PyObject *
valpy_int (PyObject *self)
{
struct value *value = ((value_object *) self)->value;
struct type *type = value_type (value);
LONGEST l = 0;
volatile struct gdb_exception except;
CHECK_TYPEDEF (type);
if (!is_intlike (type, 0))
{
PyErr_SetString (PyExc_RuntimeError, "cannot convert value to int");
return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL)
{
l = value_as_long (value);
}
GDB_PY_HANDLE_EXCEPTION (except);
return PyInt_FromLong (l);
}
/* Implements conversion to long. */
static PyObject *
valpy_long (PyObject *self)
{
struct value *value = ((value_object *) self)->value;
struct type *type = value_type (value);
LONGEST l = 0;
volatile struct gdb_exception except;
if (!is_intlike (type, 1))
{
PyErr_SetString (PyExc_RuntimeError, "cannot convert value to long");
return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL)
{
l = value_as_long (value);
}
GDB_PY_HANDLE_EXCEPTION (except);
return PyLong_FromLong (l);
}
/* Implements conversion to float. */
static PyObject *
valpy_float (PyObject *self)
{
struct value *value = ((value_object *) self)->value;
struct type *type = value_type (value);
double d = 0;
volatile struct gdb_exception except;
CHECK_TYPEDEF (type);
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
PyErr_SetString (PyExc_RuntimeError, "cannot convert value to float");
return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL)
{
d = value_as_double (value);
}
GDB_PY_HANDLE_EXCEPTION (except);
return PyFloat_FromDouble (d);
}
/* Returns an object for a value which is released from the all_values chain, /* Returns an object for a value which is released from the all_values chain,
so its lifetime is not bound to the execution of a command. */ so its lifetime is not bound to the execution of a command. */
PyObject * PyObject *
@ -533,7 +688,7 @@ value_to_value_object (struct value *val)
} }
/* Try to convert a Python value to a gdb value. If the value cannot /* Try to convert a Python value to a gdb value. If the value cannot
be converted, throw a gdb exception. */ be converted, set a Python exception and return NULL. */
struct value * struct value *
convert_value_from_python (PyObject *obj) convert_value_from_python (PyObject *obj)
@ -541,53 +696,72 @@ convert_value_from_python (PyObject *obj)
struct value *value = NULL; /* -Wall */ struct value *value = NULL; /* -Wall */
PyObject *target_str, *unicode_str; PyObject *target_str, *unicode_str;
struct cleanup *old; struct cleanup *old;
volatile struct gdb_exception except;
int cmp;
if (! obj) gdb_assert (obj != NULL);
error (_("Internal error while converting Python value."));
if (PyBool_Check (obj)) TRY_CATCH (except, RETURN_MASK_ALL)
value = value_from_longest (builtin_type_pybool, obj == Py_True);
else if (PyInt_Check (obj))
value = value_from_longest (builtin_type_pyint, PyInt_AsLong (obj));
else if (PyLong_Check (obj))
{ {
LONGEST l = PyLong_AsLongLong (obj); if (PyBool_Check (obj))
if (! PyErr_Occurred ()) {
value = value_from_longest (builtin_type_pylong, l); cmp = PyObject_IsTrue (obj);
if (cmp >= 0)
value = value_from_longest (builtin_type_pybool, cmp);
}
else if (PyInt_Check (obj))
{
long l = PyInt_AsLong (obj);
if (! PyErr_Occurred ())
value = value_from_longest (builtin_type_pyint, l);
}
else if (PyLong_Check (obj))
{
LONGEST l = PyLong_AsLongLong (obj);
if (! PyErr_Occurred ())
value = value_from_longest (builtin_type_pylong, l);
}
else if (PyFloat_Check (obj))
{
double d = PyFloat_AsDouble (obj);
if (! PyErr_Occurred ())
value = value_from_double (builtin_type_pyfloat, d);
}
else if (gdbpy_is_string (obj))
{
char *s;
s = python_string_to_target_string (obj);
if (s != NULL)
{
old = make_cleanup (xfree, s);
value = value_from_string (s);
do_cleanups (old);
}
}
else if (PyObject_TypeCheck (obj, &value_object_type))
value = ((value_object *) obj)->value;
else
PyErr_Format (PyExc_TypeError, _("Could not convert Python object: %s"),
PyString_AsString (PyObject_Str (obj)));
} }
else if (PyFloat_Check (obj)) if (except.reason < 0)
{ {
double d = PyFloat_AsDouble (obj); PyErr_Format (except.reason == RETURN_QUIT
if (! PyErr_Occurred ()) ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
value = value_from_double (builtin_type_pyfloat, d); "%s", except.message);
return NULL;
} }
else if (PyString_Check (obj) || PyUnicode_Check (obj))
{
char *s;
s = python_string_to_target_string (obj);
if (s == NULL)
return NULL;
old = make_cleanup (xfree, s);
value = value_from_string (s);
do_cleanups (old);
}
else if (PyObject_TypeCheck (obj, &value_object_type))
value = ((value_object *) obj)->value;
else
error (_("Could not convert Python object: %s"),
PyString_AsString (PyObject_Str (obj)));
if (PyErr_Occurred ())
error (_("Error converting Python value."));
return value; return value;
} }
/* Returns value object in the ARGth position in GDB's history. */ /* Returns value object in the ARGth position in GDB's history. */
PyObject * PyObject *
gdbpy_get_value_from_history (PyObject *self, PyObject *args) gdbpy_history (PyObject *self, PyObject *args)
{ {
int i; int i;
struct value *res_val = NULL; /* Initialize to appease gcc warning. */ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
@ -608,7 +782,6 @@ gdbpy_get_value_from_history (PyObject *self, PyObject *args)
void void
gdbpy_initialize_values (void) gdbpy_initialize_values (void)
{ {
value_object_type.tp_new = valpy_new;
if (PyType_Ready (&value_object_type) < 0) if (PyType_Ready (&value_object_type) < 0)
return; return;
@ -619,6 +792,7 @@ gdbpy_initialize_values (void)
} }
static PyMethodDef value_object_methods[] = { static PyMethodDef value_object_methods[] = {
{ "address", valpy_address, METH_NOARGS, "Return the address of the value." },
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
@ -634,7 +808,19 @@ static PyNumberMethods value_object_as_number = {
valpy_negative, /* nb_negative */ valpy_negative, /* nb_negative */
valpy_positive, /* nb_positive */ valpy_positive, /* nb_positive */
valpy_absolute, /* nb_absolute */ valpy_absolute, /* nb_absolute */
valpy_nonzero /* nb_nonzero */ valpy_nonzero, /* nb_nonzero */
valpy_invert, /* nb_invert */
valpy_lsh, /* nb_lshift */
valpy_rsh, /* nb_rshift */
valpy_and, /* nb_and */
valpy_xor, /* nb_xor */
valpy_or, /* nb_or */
NULL, /* nb_coerce */
valpy_int, /* nb_int */
valpy_long, /* nb_long */
valpy_float, /* nb_float */
NULL, /* nb_oct */
NULL /* nb_hex */
}; };
static PyMappingMethods value_object_as_mapping = { static PyMappingMethods value_object_as_mapping = {
@ -672,7 +858,17 @@ PyTypeObject value_object_type = {
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
value_object_methods /* tp_methods */ value_object_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
valpy_new /* tp_new */
}; };
#endif /* HAVE_PYTHON */ #endif /* HAVE_PYTHON */

View file

@ -52,7 +52,7 @@ static PyObject *gdbpy_flush (PyObject *, PyObject *);
static PyMethodDef GdbMethods[] = static PyMethodDef GdbMethods[] =
{ {
{ "get_value_from_history", gdbpy_get_value_from_history, METH_VARARGS, { "history", gdbpy_history, METH_VARARGS,
"Get a value from history" }, "Get a value from history" },
{ "execute", execute_gdb_command, METH_VARARGS, { "execute", execute_gdb_command, METH_VARARGS,
"Execute a gdb command" }, "Execute a gdb command" },

View file

@ -1,3 +1,13 @@
2009-02-04 Tom Tromey <tromey@redhat.com>
Thiago Jung Bauermann <bauerman@br.ibm.com>
* gdb.python/python-value.exp: Use `gdb.history' instead of
`gdb.value_from_history'.
(test_value_numeric_ops): Add test for conversion of enum constant.
* gdb.python/python-value.c (enum e): New type.
(evalue): New global.
(main): Use argv.
2009-02-04 Jerome Guitton <guitton@adacore.com> 2009-02-04 Jerome Guitton <guitton@adacore.com>
* gdb.ada/uninitialized_vars: New test program. * gdb.ada/uninitialized_vars: New test program.

View file

@ -27,6 +27,14 @@ union u
float b; float b;
}; };
enum e
{
ONE = 1,
TWO = 2
};
enum e evalue = TWO;
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@ -37,5 +45,7 @@ main (int argc, char *argv[])
s.b = 5; s.b = 5;
u.a = 7; u.a = 7;
argv[0][0] = 'a'; /* Just to avoid getting argv optimized out. */
return 0; /* break to inspect struct and union */ return 0; /* break to inspect struct and union */
} }

View file

@ -111,13 +111,18 @@ proc test_value_numeric_ops {} {
gdb_test "python print 'result = ' + str(1-i)" " = -4" "subtract python integer from integer value" gdb_test "python print 'result = ' + str(1-i)" " = -4" "subtract python integer from integer value"
gdb_test "python print 'result = ' + str(1.5+f)" " = 2.75" "add python float with double value" gdb_test "python print 'result = ' + str(1.5+f)" " = 2.75" "add python float with double value"
# Conversion test.
gdb_test "print evalue" " = TWO"
gdb_test "python evalue = gdb.history (0)" ""
gdb_test "python print int (evalue)" "2"
# Test pointer arithmethic # Test pointer arithmethic
# First, obtain the pointers # First, obtain the pointers
gdb_test "print (void *) 2" "" "" gdb_test "print (void *) 2" "" ""
gdb_test "python a = gdb.get_value_from_history (0)" "" "" gdb_test "python a = gdb.history (0)" "" ""
gdb_test "print (void *) 5" "" "" gdb_test "print (void *) 5" "" ""
gdb_test "python b = gdb.get_value_from_history (0)" "" "" gdb_test "python b = gdb.history (0)" "" ""
gdb_test "python print 'result = ' + str(a+5)" " = 0x7" "add pointer value with python integer" gdb_test "python print 'result = ' + str(a+5)" " = 0x7" "add pointer value with python integer"
gdb_test "python print 'result = ' + str(b-2)" " = 0x3" "subtract python integer from pointer value" gdb_test "python print 'result = ' + str(b-2)" " = 0x3" "subtract python integer from pointer value"
@ -205,7 +210,7 @@ proc test_value_in_inferior {} {
# Just get inferior variable s in the value history, available to python. # Just get inferior variable s in the value history, available to python.
gdb_test "print s" " = {a = 3, b = 5}" "" gdb_test "print s" " = {a = 3, b = 5}" ""
gdb_py_test_silent_cmd "python s = gdb.get_value_from_history (0)" "get value from history" 1 gdb_py_test_silent_cmd "python s = gdb.history (0)" "get value from history" 1
gdb_test "python print 'result = ' + str(s\['a'\])" " = 3" "access element inside struct using 8-bit string name" gdb_test "python print 'result = ' + str(s\['a'\])" " = 3" "access element inside struct using 8-bit string name"
gdb_test "python print 'result = ' + str(s\[u'a'\])" " = 3" "access element inside struct using unicode name" gdb_test "python print 'result = ' + str(s\[u'a'\])" " = 3" "access element inside struct using unicode name"
@ -215,7 +220,7 @@ proc test_value_in_inferior {} {
# Just get inferior variable argv the value history, available to python. # Just get inferior variable argv the value history, available to python.
gdb_test "print argv" " = \\(char \\*\\*\\) 0x.*" "" gdb_test "print argv" " = \\(char \\*\\*\\) 0x.*" ""
gdb_py_test_silent_cmd "python argv = gdb.get_value_from_history (0)" "" 0 gdb_py_test_silent_cmd "python argv = gdb.history (0)" "" 0
gdb_py_test_silent_cmd "python arg0 = argv.dereference ()" "dereference value" 1 gdb_py_test_silent_cmd "python arg0 = argv.dereference ()" "dereference value" 1
# Check that the dereferenced value is sane # Check that the dereferenced value is sane