URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/gnu-old/gdb-7.1/gdb/python
- from Rev 834 to Rev 842
- ↔ Reverse comparison
Rev 834 → Rev 842
/py-frame.c
0,0 → 1,539
/* Python interface to stack frames |
|
Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. |
|
This file is part of GDB. |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
#include "defs.h" |
#include "charset.h" |
#include "block.h" |
#include "frame.h" |
#include "exceptions.h" |
#include "symtab.h" |
#include "stack.h" |
#include "value.h" |
#include "python-internal.h" |
|
typedef struct { |
PyObject_HEAD |
struct frame_id frame_id; |
struct gdbarch *gdbarch; |
|
/* Marks that the FRAME_ID member actually holds the ID of the frame next |
to this, and not this frames' ID itself. This is a hack to permit Python |
frame objects which represent invalid frames (i.e., the last frame_info |
in a corrupt stack). The problem arises from the fact that this code |
relies on FRAME_ID to uniquely identify a frame, which is not always true |
for the last "frame" in a corrupt stack (it can have a null ID, or the same |
ID as the previous frame). Whenever get_prev_frame returns NULL, we |
record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */ |
int frame_id_is_next; |
} frame_object; |
|
/* Require a valid frame. This must be called inside a TRY_CATCH, or |
another context in which a gdb exception is allowed. */ |
#define FRAPY_REQUIRE_VALID(frame_obj, frame) \ |
do { \ |
frame = frame_object_to_frame_info (frame_obj); \ |
if (frame == NULL) \ |
error ("Frame is invalid."); \ |
} while (0) |
|
static PyTypeObject frame_object_type; |
|
/* Returns the frame_info object corresponding to the given Python Frame |
object. If the frame doesn't exist anymore (the frame id doesn't |
correspond to any frame in the inferior), returns NULL. */ |
|
static struct frame_info * |
frame_object_to_frame_info (frame_object *frame_obj) |
{ |
struct frame_info *frame; |
|
frame = frame_find_by_id (frame_obj->frame_id); |
if (frame == NULL) |
return NULL; |
|
if (frame_obj->frame_id_is_next) |
frame = get_prev_frame (frame); |
|
return frame; |
} |
|
/* Called by the Python interpreter to obtain string representation |
of the object. */ |
|
static PyObject * |
frapy_str (PyObject *self) |
{ |
char *s; |
PyObject *result; |
struct ui_file *strfile; |
|
strfile = mem_fileopen (); |
fprint_frame_id (strfile, ((frame_object *) self)->frame_id); |
s = ui_file_xstrdup (strfile, NULL); |
result = PyString_FromString (s); |
xfree (s); |
|
return result; |
} |
|
/* Implementation of gdb.Frame.is_valid (self) -> Boolean. |
Returns True if the frame corresponding to the frame_id of this |
object still exists in the inferior. */ |
|
static PyObject * |
frapy_is_valid (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame; |
|
frame = frame_object_to_frame_info ((frame_object *) self); |
if (frame == NULL) |
Py_RETURN_FALSE; |
|
Py_RETURN_TRUE; |
} |
|
/* Implementation of gdb.Frame.name (self) -> String. |
Returns the name of the function corresponding to this frame. */ |
|
static PyObject * |
frapy_name (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame; |
char *name; |
enum language lang; |
PyObject *result; |
volatile struct gdb_exception except; |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
find_frame_funname (frame, &name, &lang); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
if (name) |
result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL); |
else |
{ |
result = Py_None; |
Py_INCREF (Py_None); |
} |
|
return result; |
} |
|
/* Implementation of gdb.Frame.type (self) -> Integer. |
Returns the frame type, namely one of the gdb.*_FRAME constants. */ |
|
static PyObject * |
frapy_type (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame; |
enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */ |
volatile struct gdb_exception except; |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
type = get_frame_type (frame); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
return PyInt_FromLong (type); |
} |
|
/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer. |
Returns one of the gdb.FRAME_UNWIND_* constants. */ |
|
static PyObject * |
frapy_unwind_stop_reason (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */ |
volatile struct gdb_exception except; |
enum unwind_stop_reason stop_reason; |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
stop_reason = get_frame_unwind_stop_reason (frame); |
|
return PyInt_FromLong (stop_reason); |
} |
|
/* Implementation of gdb.Frame.pc (self) -> Long. |
Returns the frame's resume address. */ |
|
static PyObject * |
frapy_pc (PyObject *self, PyObject *args) |
{ |
CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */ |
struct frame_info *frame; |
volatile struct gdb_exception except; |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
pc = get_frame_pc (frame); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
return PyLong_FromUnsignedLongLong (pc); |
} |
|
/* Convert a frame_info struct to a Python Frame object. |
Sets a Python exception and returns NULL on error. */ |
|
static frame_object * |
frame_info_to_frame_object (struct frame_info *frame) |
{ |
frame_object *frame_obj; |
|
frame_obj = PyObject_New (frame_object, &frame_object_type); |
if (frame_obj == NULL) |
{ |
PyErr_SetString (PyExc_MemoryError, "Could not allocate frame object."); |
return NULL; |
} |
|
/* Try to get the previous frame, to determine if this is the last frame |
in a corrupt stack. If so, we need to store the frame_id of the next |
frame and not of this one (which is possibly invalid). */ |
if (get_prev_frame (frame) == NULL |
&& get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON |
&& get_next_frame (frame) != NULL) |
{ |
frame_obj->frame_id = get_frame_id (get_next_frame (frame)); |
frame_obj->frame_id_is_next = 1; |
} |
else |
{ |
frame_obj->frame_id = get_frame_id (frame); |
frame_obj->frame_id_is_next = 0; |
} |
|
frame_obj->gdbarch = get_frame_arch (frame); |
|
return frame_obj; |
} |
|
/* Implementation of gdb.Frame.older (self) -> gdb.Frame. |
Returns the frame immediately older (outer) to this frame, or None if |
there isn't one. */ |
|
static PyObject * |
frapy_older (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame, *prev; |
volatile struct gdb_exception except; |
PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */ |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
prev = get_prev_frame (frame); |
if (prev) |
prev_obj = (PyObject *) frame_info_to_frame_object (prev); |
else |
{ |
Py_INCREF (Py_None); |
prev_obj = Py_None; |
} |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
return prev_obj; |
} |
|
/* Implementation of gdb.Frame.newer (self) -> gdb.Frame. |
Returns the frame immediately newer (inner) to this frame, or None if |
there isn't one. */ |
|
static PyObject * |
frapy_newer (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame, *next; |
volatile struct gdb_exception except; |
PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */ |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
next = get_next_frame (frame); |
if (next) |
next_obj = (PyObject *) frame_info_to_frame_object (next); |
else |
{ |
Py_INCREF (Py_None); |
next_obj = Py_None; |
} |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
return next_obj; |
} |
|
/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value. |
Returns the value of the given variable in this frame. The argument must be |
a string. Returns None if GDB can't find the specified variable. */ |
|
static PyObject * |
frapy_read_var (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame; |
PyObject *sym_obj; |
struct symbol *var = NULL; /* gcc-4.3.2 false warning. */ |
struct value *val = NULL; |
volatile struct gdb_exception except; |
|
if (!PyArg_ParseTuple (args, "O", &sym_obj)) |
return NULL; |
|
if (gdbpy_is_string (sym_obj)) |
{ |
char *var_name; |
struct block *block = NULL; |
struct cleanup *cleanup; |
volatile struct gdb_exception except; |
|
var_name = python_string_to_target_string (sym_obj); |
if (!var_name) |
return NULL; |
cleanup = make_cleanup (xfree, var_name); |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
block = block_for_pc (get_frame_address_in_block (frame)); |
var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
if (!var) |
{ |
PyErr_Format (PyExc_ValueError, |
_("variable '%s' not found"), var_name); |
do_cleanups (cleanup); |
|
return NULL; |
} |
|
do_cleanups (cleanup); |
} |
else |
{ |
PyErr_SetString (PyExc_TypeError, |
_("argument must be a symbol or string")); |
return NULL; |
} |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
FRAPY_REQUIRE_VALID ((frame_object *) self, frame); |
|
val = read_var_value (var, frame); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
if (val) |
return value_to_value_object (val); |
|
Py_RETURN_NONE; |
} |
|
/* Implementation of gdb.selected_frame () -> gdb.Frame. |
Returns the selected frame object. */ |
|
PyObject * |
gdbpy_selected_frame (PyObject *self, PyObject *args) |
{ |
struct frame_info *frame; |
frame_object *frame_obj = NULL; /* Initialize to appease gcc warning. */ |
volatile struct gdb_exception except; |
|
TRY_CATCH (except, RETURN_MASK_ALL) |
{ |
frame = get_selected_frame ("No frame is currently selected."); |
frame_obj = frame_info_to_frame_object (frame); |
} |
GDB_PY_HANDLE_EXCEPTION (except); |
|
return (PyObject *) frame_obj; |
} |
|
/* Implementation of gdb.stop_reason_string (Integer) -> String. |
Return a string explaining the unwind stop reason. */ |
|
PyObject * |
gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args) |
{ |
int reason; |
const char *str; |
|
if (!PyArg_ParseTuple (args, "i", &reason)) |
return NULL; |
|
if (reason < 0 || reason > UNWIND_NO_SAVED_PC) |
{ |
PyErr_SetString (PyExc_ValueError, "Invalid frame stop reason."); |
return NULL; |
} |
|
str = frame_stop_reason_string (reason); |
return PyUnicode_Decode (str, strlen (str), host_charset (), NULL); |
} |
|
/* Implements the equality comparison for Frame objects. |
All other comparison operators will throw a TypeError Python exception, |
as they aren't valid for frames. */ |
|
static PyObject * |
frapy_richcompare (PyObject *self, PyObject *other, int op) |
{ |
int result; |
|
if (!PyObject_TypeCheck (other, &frame_object_type) |
|| (op != Py_EQ && op != Py_NE)) |
{ |
Py_INCREF (Py_NotImplemented); |
return Py_NotImplemented; |
} |
|
if (frame_id_eq (((frame_object *) self)->frame_id, |
((frame_object *) other)->frame_id)) |
result = Py_EQ; |
else |
result = Py_NE; |
|
if (op == result) |
Py_RETURN_TRUE; |
Py_RETURN_FALSE; |
} |
|
/* Sets up the Frame API in the gdb module. */ |
|
void |
gdbpy_initialize_frames (void) |
{ |
if (PyType_Ready (&frame_object_type) < 0) |
return; |
|
/* Note: These would probably be best exposed as class attributes of Frame, |
but I don't know how to do it except by messing with the type's dictionary. |
That seems too messy. */ |
PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME); |
PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME); |
PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME", SIGTRAMP_FRAME); |
PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME", SENTINEL_FRAME); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_NO_REASON", UNWIND_NO_REASON); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_NULL_ID", UNWIND_NULL_ID); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_FIRST_ERROR", UNWIND_FIRST_ERROR); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_INNER_ID", UNWIND_INNER_ID); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_SAME_ID", UNWIND_SAME_ID); |
PyModule_AddIntConstant (gdb_module, |
"FRAME_UNWIND_NO_SAVED_PC", UNWIND_NO_SAVED_PC); |
|
Py_INCREF (&frame_object_type); |
PyModule_AddObject (gdb_module, "Frame", (PyObject *) &frame_object_type); |
} |
|
|
|
static PyMethodDef frame_object_methods[] = { |
{ "is_valid", frapy_is_valid, METH_NOARGS, |
"is_valid () -> Boolean.\n\ |
Return true if this frame is valid, false if not." }, |
{ "name", frapy_name, METH_NOARGS, |
"name () -> String.\n\ |
Return the function name of the frame, or None if it can't be determined." }, |
{ "type", frapy_type, METH_NOARGS, |
"type () -> Integer.\n\ |
Return the type of the frame." }, |
{ "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS, |
"unwind_stop_reason () -> Integer.\n\ |
Return the reason why it's not possible to find frames older than this." }, |
{ "pc", frapy_pc, METH_NOARGS, |
"pc () -> Long.\n\ |
Return the frame's resume address." }, |
{ "older", frapy_older, METH_NOARGS, |
"older () -> gdb.Frame.\n\ |
Return the frame that called this frame." }, |
{ "newer", frapy_newer, METH_NOARGS, |
"newer () -> gdb.Frame.\n\ |
Return the frame called by this frame." }, |
{ "read_var", frapy_read_var, METH_VARARGS, |
"read_var (variable) -> gdb.Value.\n\ |
Return the value of the variable in this frame." }, |
{NULL} /* Sentinel */ |
}; |
|
static PyTypeObject frame_object_type = { |
PyObject_HEAD_INIT (NULL) |
0, /* ob_size */ |
"gdb.Frame", /* tp_name */ |
sizeof (frame_object), /* tp_basicsize */ |
0, /* tp_itemsize */ |
0, /* tp_dealloc */ |
0, /* tp_print */ |
0, /* tp_getattr */ |
0, /* tp_setattr */ |
0, /* tp_compare */ |
0, /* tp_repr */ |
0, /* tp_as_number */ |
0, /* tp_as_sequence */ |
0, /* tp_as_mapping */ |
0, /* tp_hash */ |
0, /* tp_call */ |
frapy_str, /* tp_str */ |
0, /* tp_getattro */ |
0, /* tp_setattro */ |
0, /* tp_as_buffer */ |
Py_TPFLAGS_DEFAULT, /* tp_flags */ |
"GDB frame object", /* tp_doc */ |
0, /* tp_traverse */ |
0, /* tp_clear */ |
frapy_richcompare, /* tp_richcompare */ |
0, /* tp_weaklistoffset */ |
0, /* tp_iter */ |
0, /* tp_iternext */ |
frame_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 */ |
PyType_GenericNew /* tp_new */ |
}; |
py-frame.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-objfile.c
===================================================================
--- py-objfile.c (nonexistent)
+++ py-objfile.c (revision 842)
@@ -0,0 +1,230 @@
+/* Python interface to objfiles.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct
+{
+ PyObject_HEAD
+
+ /* The corresponding objfile. */
+ struct objfile *objfile;
+
+ /* The pretty-printer list of functions. */
+ PyObject *printers;
+} objfile_object;
+
+static PyTypeObject objfile_object_type;
+
+static const struct objfile_data *objfpy_objfile_data_key;
+
+
+
+/* An Objfile method which returns the objfile's file name, or None. */
+static PyObject *
+objfpy_get_filename (PyObject *self, void *closure)
+{
+ objfile_object *obj = (objfile_object *) self;
+ if (obj->objfile && obj->objfile->name)
+ return PyString_Decode (obj->objfile->name, strlen (obj->objfile->name),
+ host_charset (), NULL);
+ Py_RETURN_NONE;
+}
+
+static void
+objfpy_dealloc (PyObject *o)
+{
+ objfile_object *self = (objfile_object *) o;
+ Py_XDECREF (self->printers);
+ self->ob_type->tp_free ((PyObject *) self);
+}
+
+static PyObject *
+objfpy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
+{
+ objfile_object *self = (objfile_object *) type->tp_alloc (type, 0);
+ if (self)
+ {
+ self->objfile = NULL;
+
+ self->printers = PyList_New (0);
+ if (!self->printers)
+ {
+ Py_DECREF (self);
+ return NULL;
+ }
+ }
+ return (PyObject *) self;
+}
+
+PyObject *
+objfpy_get_printers (PyObject *o, void *ignore)
+{
+ objfile_object *self = (objfile_object *) o;
+ Py_INCREF (self->printers);
+ return self->printers;
+}
+
+static int
+objfpy_set_printers (PyObject *o, PyObject *value, void *ignore)
+{
+ PyObject *tmp;
+ objfile_object *self = (objfile_object *) o;
+ if (! value)
+ {
+ PyErr_SetString (PyExc_TypeError,
+ "cannot delete the pretty_printers attribute");
+ return -1;
+ }
+
+ if (! PyList_Check (value))
+ {
+ PyErr_SetString (PyExc_TypeError,
+ "the pretty_printers attribute must be a list");
+ return -1;
+ }
+
+ /* Take care in case the LHS and RHS are related somehow. */
+ tmp = self->printers;
+ Py_INCREF (value);
+ self->printers = value;
+ Py_XDECREF (tmp);
+
+ return 0;
+}
+
+
+
+/* Clear the OBJFILE pointer in an Objfile object and remove the
+ reference. */
+static void
+py_free_objfile (struct objfile *objfile, void *datum)
+{
+ struct cleanup *cleanup;
+ objfile_object *object = datum;
+
+ cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
+ object->objfile = NULL;
+ Py_DECREF ((PyObject *) object);
+ do_cleanups (cleanup);
+}
+
+/* Return a borrowed reference to the Python object of type Objfile
+ representing OBJFILE. If the object has already been created,
+ return it. Otherwise, create it. Return NULL and set the Python
+ error on failure. */
+PyObject *
+objfile_to_objfile_object (struct objfile *objfile)
+{
+ objfile_object *object;
+
+ object = objfile_data (objfile, objfpy_objfile_data_key);
+ if (!object)
+ {
+ object = PyObject_New (objfile_object, &objfile_object_type);
+ if (object)
+ {
+ PyObject *dict;
+
+ object->objfile = objfile;
+
+ object->printers = PyList_New (0);
+ if (!object->printers)
+ {
+ Py_DECREF (object);
+ return NULL;
+ }
+
+ set_objfile_data (objfile, objfpy_objfile_data_key, object);
+ }
+ }
+
+ return (PyObject *) object;
+}
+
+void
+gdbpy_initialize_objfile (void)
+{
+ objfpy_objfile_data_key
+ = register_objfile_data_with_cleanup (NULL, py_free_objfile);
+
+ if (PyType_Ready (&objfile_object_type) < 0)
+ return;
+
+ Py_INCREF (&objfile_object_type);
+ PyModule_AddObject (gdb_module, "Objfile", (PyObject *) &objfile_object_type);
+}
+
+
+
+static PyGetSetDef objfile_getset[] =
+{
+ { "filename", objfpy_get_filename, NULL,
+ "The objfile's filename, or None.", NULL },
+ { "pretty_printers", objfpy_get_printers, objfpy_set_printers,
+ "Pretty printers.", NULL },
+ { NULL }
+};
+
+static PyTypeObject objfile_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Objfile", /*tp_name*/
+ sizeof (objfile_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ objfpy_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ "GDB objfile object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ objfile_getset, /* 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 */
+ objfpy_new, /* tp_new */
+};
py-objfile.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: python-internal.h
===================================================================
--- python-internal.h (nonexistent)
+++ python-internal.h (revision 842)
@@ -0,0 +1,141 @@
+/* Gdb/Python header for private use by Python module.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#ifndef GDB_PYTHON_INTERNAL_H
+#define GDB_PYTHON_INTERNAL_H
+
+/* Python 2.4 doesn't include stdint.h soon enough to get {u,}intptr_t
+ needed by pyport.h. */
+#include
+
+/* /usr/include/features.h on linux systems will define _POSIX_C_SOURCE
+ if it sees _GNU_SOURCE (which config.h will define).
+ pyconfig.h defines _POSIX_C_SOURCE to a different value than
+ /usr/include/features.h does causing compilation to fail.
+ To work around this, undef _POSIX_C_SOURCE before we include Python.h. */
+#undef _POSIX_C_SOURCE
+
+#if HAVE_LIBPYTHON2_4
+#include "python2.4/Python.h"
+#include "python2.4/frameobject.h"
+/* Py_ssize_t is not defined until 2.5.
+ Logical type for Py_ssize_t is Py_intptr_t, but that fails in 64-bit
+ compilation due to several apparent mistakes in python2.4 API, so we
+ use 'int' instead. */
+typedef int Py_ssize_t;
+#elif HAVE_LIBPYTHON2_5
+#include "python2.5/Python.h"
+#include "python2.5/frameobject.h"
+#elif HAVE_LIBPYTHON2_6
+#include "python2.6/Python.h"
+#include "python2.6/frameobject.h"
+#else
+#error "Unable to find usable Python.h"
+#endif
+
+/* If Python.h does not define WITH_THREAD, then the various
+ GIL-related functions will not be defined. However,
+ PyGILState_STATE will be. */
+#ifndef WITH_THREAD
+#define PyGILState_Ensure() ((PyGILState_STATE) 0)
+#define PyGILState_Release(ARG) ((void)(ARG))
+#define PyEval_InitThreads() 0
+#define PyThreadState_Swap(ARG) ((void)(ARG))
+#define PyEval_InitThreads() 0
+#define PyEval_ReleaseLock() 0
+#endif
+
+struct value;
+struct language_defn;
+
+extern PyObject *gdb_module;
+extern PyTypeObject value_object_type;
+
+PyObject *gdbpy_history (PyObject *self, PyObject *args);
+PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
+PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
+PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
+PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
+ const char *encoding, struct type *type);
+
+PyObject *value_to_value_object (struct value *v);
+PyObject *type_to_type_object (struct type *);
+PyObject *objfile_to_objfile_object (struct objfile *);
+
+PyObject *objfpy_get_printers (PyObject *, void *);
+
+struct value *value_object_to_value (PyObject *self);
+struct value *convert_value_from_python (PyObject *obj);
+struct type *type_object_to_type (PyObject *obj);
+
+void gdbpy_initialize_values (void);
+void gdbpy_initialize_frames (void);
+void gdbpy_initialize_commands (void);
+void gdbpy_initialize_types (void);
+void gdbpy_initialize_functions (void);
+void gdbpy_initialize_objfile (void);
+void gdbpy_initialize_lazy_string (void);
+
+struct cleanup *make_cleanup_py_decref (PyObject *py);
+
+struct cleanup *ensure_python_env (struct gdbarch *gdbarch,
+ const struct language_defn *language);
+
+extern struct gdbarch *python_gdbarch;
+extern const struct language_defn *python_language;
+
+/* Use this after a TRY_EXCEPT to throw the appropriate Python
+ exception. */
+#define GDB_PY_HANDLE_EXCEPTION(Exception) \
+ do { \
+ if (Exception.reason < 0) \
+ return PyErr_Format (Exception.reason == RETURN_QUIT \
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
+ "%s", Exception.message); \
+ } while (0)
+
+
+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);
+int gdbpy_is_lazy_string (PyObject *result);
+gdb_byte *gdbpy_extract_lazy_string (PyObject *string,
+ struct type **str_type,
+ long *length, char **encoding);
+
+/* Note that these are declared here, and not in python.h with the
+ other pretty-printer functions, because they refer to PyObject. */
+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);
+
+extern PyObject *gdbpy_doc_cst;
+extern PyObject *gdbpy_children_cst;
+extern PyObject *gdbpy_to_string_cst;
+extern PyObject *gdbpy_display_hint_cst;
+
+#endif /* GDB_PYTHON_INTERNAL_H */
python-internal.h
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: python.c
===================================================================
--- python.c (nonexistent)
+++ python.c (revision 842)
@@ -0,0 +1,741 @@
+/* General python/gdb code
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "command.h"
+#include "ui-out.h"
+#include "cli/cli-script.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "observer.h"
+#include "value.h"
+#include "language.h"
+#include "exceptions.h"
+
+#include
+
+/* True if we should print the stack when catching a Python error,
+ false otherwise. */
+static int gdbpy_should_print_stack = 1;
+
+/* This is true if we should auto-load python code when an objfile is
+ opened, false otherwise. */
+static int gdbpy_auto_load = 1;
+
+#ifdef HAVE_PYTHON
+
+#include "python.h"
+#include "libiberty.h"
+#include "cli/cli-decode.h"
+#include "charset.h"
+#include "top.h"
+#include "python-internal.h"
+#include "version.h"
+#include "target.h"
+#include "gdbthread.h"
+
+static PyMethodDef GdbMethods[];
+
+PyObject *gdb_module;
+
+/* Some string constants we may wish to use. */
+PyObject *gdbpy_to_string_cst;
+PyObject *gdbpy_children_cst;
+PyObject *gdbpy_display_hint_cst;
+PyObject *gdbpy_doc_cst;
+
+
+/* Architecture and language to be used in callbacks from
+ the Python interpreter. */
+struct gdbarch *python_gdbarch;
+const struct language_defn *python_language;
+
+/* Restore global language and architecture and Python GIL state
+ when leaving the Python interpreter. */
+
+struct python_env
+{
+ PyGILState_STATE state;
+ struct gdbarch *gdbarch;
+ const struct language_defn *language;
+};
+
+static void
+restore_python_env (void *p)
+{
+ struct python_env *env = (struct python_env *)p;
+ PyGILState_Release (env->state);
+ python_gdbarch = env->gdbarch;
+ python_language = env->language;
+ xfree (env);
+}
+
+/* Called before entering the Python interpreter to install the
+ current language and architecture to be used for Python values. */
+
+struct cleanup *
+ensure_python_env (struct gdbarch *gdbarch,
+ const struct language_defn *language)
+{
+ struct python_env *env = xmalloc (sizeof *env);
+
+ env->state = PyGILState_Ensure ();
+ env->gdbarch = python_gdbarch;
+ env->language = python_language;
+
+ python_gdbarch = gdbarch;
+ python_language = language;
+
+ return make_cleanup (restore_python_env, env);
+}
+
+
+/* Given a command_line, return a command string suitable for passing
+ to Python. Lines in the string are separated by newlines. The
+ return value is allocated using xmalloc and the caller is
+ responsible for freeing it. */
+
+static char *
+compute_python_string (struct command_line *l)
+{
+ struct command_line *iter;
+ char *script = NULL;
+ int size = 0;
+ int here;
+
+ for (iter = l; iter; iter = iter->next)
+ size += strlen (iter->line) + 1;
+
+ script = xmalloc (size + 1);
+ here = 0;
+ for (iter = l; iter; iter = iter->next)
+ {
+ int len = strlen (iter->line);
+ strcpy (&script[here], iter->line);
+ here += len;
+ script[here++] = '\n';
+ }
+ script[here] = '\0';
+ return script;
+}
+
+/* Take a command line structure representing a 'python' command, and
+ evaluate its body using the Python interpreter. */
+
+void
+eval_python_from_control_command (struct command_line *cmd)
+{
+ int ret;
+ char *script;
+ struct cleanup *cleanup;
+
+ if (cmd->body_count != 1)
+ error (_("Invalid \"python\" block structure."));
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ script = compute_python_string (cmd->body_list[0]);
+ ret = PyRun_SimpleString (script);
+ xfree (script);
+ if (ret)
+ {
+ gdbpy_print_stack ();
+ error (_("Error while executing Python code."));
+ }
+
+ do_cleanups (cleanup);
+}
+
+/* Implementation of the gdb "python" command. */
+
+static void
+python_command (char *arg, int from_tty)
+{
+ struct cleanup *cleanup;
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ while (arg && *arg && isspace (*arg))
+ ++arg;
+ if (arg && *arg)
+ {
+ if (PyRun_SimpleString (arg))
+ {
+ gdbpy_print_stack ();
+ error (_("Error while executing Python code."));
+ }
+ }
+ else
+ {
+ struct command_line *l = get_command_line (python_control, "");
+ make_cleanup_free_command_lines (&l);
+ execute_control_command_untraced (l);
+ }
+
+ do_cleanups (cleanup);
+}
+
+
+
+/* Transform a gdb parameters's value into a Python value. May return
+ NULL (and set a Python exception) on error. Helper function for
+ get_parameter. */
+
+static PyObject *
+parameter_to_python (struct cmd_list_element *cmd)
+{
+ switch (cmd->var_type)
+ {
+ case var_string:
+ case var_string_noescape:
+ case var_optional_filename:
+ case var_filename:
+ case var_enum:
+ {
+ char *str = * (char **) cmd->var;
+ if (! str)
+ str = "";
+ return PyString_Decode (str, strlen (str), host_charset (), NULL);
+ }
+
+ case var_boolean:
+ {
+ if (* (int *) cmd->var)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+
+ case var_auto_boolean:
+ {
+ enum auto_boolean ab = * (enum auto_boolean *) cmd->var;
+ if (ab == AUTO_BOOLEAN_TRUE)
+ Py_RETURN_TRUE;
+ else if (ab == AUTO_BOOLEAN_FALSE)
+ Py_RETURN_FALSE;
+ else
+ Py_RETURN_NONE;
+ }
+
+ case var_integer:
+ if ((* (int *) cmd->var) == INT_MAX)
+ Py_RETURN_NONE;
+ /* Fall through. */
+ case var_zinteger:
+ return PyLong_FromLong (* (int *) cmd->var);
+
+ case var_uinteger:
+ {
+ unsigned int val = * (unsigned int *) cmd->var;
+ if (val == UINT_MAX)
+ Py_RETURN_NONE;
+ return PyLong_FromUnsignedLong (val);
+ }
+ }
+
+ return PyErr_Format (PyExc_RuntimeError, "programmer error: unhandled type");
+}
+
+/* A Python function which returns a gdb parameter's value as a Python
+ value. */
+
+static PyObject *
+gdbpy_parameter (PyObject *self, PyObject *args)
+{
+ struct cmd_list_element *alias, *prefix, *cmd;
+ char *arg, *newarg;
+ int found = -1;
+ volatile struct gdb_exception except;
+
+ if (! PyArg_ParseTuple (args, "s", &arg))
+ return NULL;
+
+ newarg = concat ("show ", arg, (char *) NULL);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
+ }
+ xfree (newarg);
+ GDB_PY_HANDLE_EXCEPTION (except);
+ if (!found)
+ return PyErr_Format (PyExc_RuntimeError,
+ "could not find parameter `%s'", arg);
+
+ if (! cmd->var)
+ return PyErr_Format (PyExc_RuntimeError, "`%s' is not a parameter", arg);
+ return parameter_to_python (cmd);
+}
+
+/* A Python function which evaluates a string using the gdb CLI. */
+
+static PyObject *
+execute_gdb_command (PyObject *self, PyObject *args)
+{
+ struct cmd_list_element *alias, *prefix, *cmd;
+ char *arg, *newarg;
+ PyObject *from_tty_obj = NULL;
+ int from_tty;
+ int cmp;
+ volatile struct gdb_exception except;
+
+ if (! PyArg_ParseTuple (args, "s|O!", &arg, &PyBool_Type, &from_tty_obj))
+ return NULL;
+
+ from_tty = 0;
+ if (from_tty_obj)
+ {
+ cmp = PyObject_IsTrue (from_tty_obj);
+ if (cmp < 0)
+ return NULL;
+ from_tty = cmp;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ /* Copy the argument text in case the command modifies it. */
+ char *copy = xstrdup (arg);
+ struct cleanup *cleanup = make_cleanup (xfree, copy);
+ execute_command (copy, from_tty);
+ do_cleanups (cleanup);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ /* Do any commands attached to breakpoint we stopped at. */
+ bpstat_do_actions ();
+
+ Py_RETURN_NONE;
+}
+
+/* Parse a string and evaluate it as an expression. */
+static PyObject *
+gdbpy_parse_and_eval (PyObject *self, PyObject *args)
+{
+ char *expr_str;
+ struct value *result = NULL;
+ volatile struct gdb_exception except;
+
+ if (!PyArg_ParseTuple (args, "s", &expr_str))
+ return NULL;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ result = parse_and_eval (expr_str);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (result);
+}
+
+/* Read a file as Python code. STREAM is the input file; FILE is the
+ name of the file. */
+
+void
+source_python_script (FILE *stream, char *file)
+{
+ PyGILState_STATE state;
+
+ state = PyGILState_Ensure ();
+
+ PyRun_SimpleFile (stream, file);
+
+ fclose (stream);
+ PyGILState_Release (state);
+}
+
+
+
+/* Printing. */
+
+/* A python function to write a single string using gdb's filtered
+ output stream. */
+static PyObject *
+gdbpy_write (PyObject *self, PyObject *args)
+{
+ char *arg;
+ if (! PyArg_ParseTuple (args, "s", &arg))
+ return NULL;
+ printf_filtered ("%s", arg);
+ Py_RETURN_NONE;
+}
+
+/* A python function to flush gdb's filtered output stream. */
+static PyObject *
+gdbpy_flush (PyObject *self, PyObject *args)
+{
+ gdb_flush (gdb_stdout);
+ Py_RETURN_NONE;
+}
+
+/* Print a python exception trace, or print nothing and clear the
+ python exception, depending on gdbpy_should_print_stack. Only call
+ this if a python exception is set. */
+void
+gdbpy_print_stack (void)
+{
+ if (gdbpy_should_print_stack)
+ PyErr_Print ();
+ else
+ PyErr_Clear ();
+}
+
+
+
+/* The "current" objfile. This is set when gdb detects that a new
+ objfile has been loaded. It is only set for the duration of a call
+ to gdbpy_new_objfile; it is NULL at other times. */
+static struct objfile *gdbpy_current_objfile;
+
+/* The file name we attempt to read. */
+#define GDBPY_AUTO_FILENAME "-gdb.py"
+
+/* This is a new_objfile observer callback which loads python code
+ based on the path to the objfile. */
+static void
+gdbpy_new_objfile (struct objfile *objfile)
+{
+ char *realname;
+ char *filename, *debugfile;
+ int len;
+ FILE *input;
+ struct cleanup *cleanups;
+
+ if (!gdbpy_auto_load || !objfile || !objfile->name)
+ return;
+
+ cleanups = ensure_python_env (get_objfile_arch (objfile), current_language);
+
+ gdbpy_current_objfile = objfile;
+
+ realname = gdb_realpath (objfile->name);
+ len = strlen (realname);
+ filename = xmalloc (len + sizeof (GDBPY_AUTO_FILENAME));
+ memcpy (filename, realname, len);
+ strcpy (filename + len, GDBPY_AUTO_FILENAME);
+
+ input = fopen (filename, "r");
+ debugfile = filename;
+
+ make_cleanup (xfree, filename);
+ make_cleanup (xfree, realname);
+
+ if (!input && debug_file_directory)
+ {
+ /* Also try the same file in the separate debug info directory. */
+ debugfile = xmalloc (strlen (filename)
+ + strlen (debug_file_directory) + 1);
+ strcpy (debugfile, debug_file_directory);
+ /* FILENAME is absolute, so we don't need a "/" here. */
+ strcat (debugfile, filename);
+
+ make_cleanup (xfree, debugfile);
+ input = fopen (debugfile, "r");
+ }
+
+ if (!input && gdb_datadir)
+ {
+ /* Also try the same file in a subdirectory of gdb's data
+ directory. */
+ debugfile = xmalloc (strlen (gdb_datadir) + strlen (filename)
+ + strlen ("/auto-load") + 1);
+ strcpy (debugfile, gdb_datadir);
+ strcat (debugfile, "/auto-load");
+ /* FILENAME is absolute, so we don't need a "/" here. */
+ strcat (debugfile, filename);
+
+ make_cleanup (xfree, debugfile);
+ input = fopen (debugfile, "r");
+ }
+
+ if (input)
+ {
+ /* We don't want to throw an exception here -- but the user
+ would like to know that something went wrong. */
+ if (PyRun_SimpleFile (input, debugfile))
+ gdbpy_print_stack ();
+ fclose (input);
+ }
+
+ do_cleanups (cleanups);
+ gdbpy_current_objfile = NULL;
+}
+
+/* Return the current Objfile, or None if there isn't one. */
+static PyObject *
+gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
+{
+ PyObject *result;
+
+ if (! gdbpy_current_objfile)
+ Py_RETURN_NONE;
+
+ result = objfile_to_objfile_object (gdbpy_current_objfile);
+ if (result)
+ Py_INCREF (result);
+ return result;
+}
+
+/* Return a sequence holding all the Objfiles. */
+static PyObject *
+gdbpy_objfiles (PyObject *unused1, PyObject *unused2)
+{
+ struct objfile *objf;
+ PyObject *list;
+
+ list = PyList_New (0);
+ if (!list)
+ return NULL;
+
+ ALL_OBJFILES (objf)
+ {
+ PyObject *item = objfile_to_objfile_object (objf);
+ if (!item || PyList_Append (list, item) == -1)
+ {
+ Py_DECREF (list);
+ return NULL;
+ }
+ }
+
+ return list;
+}
+
+#else /* HAVE_PYTHON */
+
+/* Dummy implementation of the gdb "python" command. */
+
+static void
+python_command (char *arg, int from_tty)
+{
+ while (arg && *arg && isspace (*arg))
+ ++arg;
+ if (arg && *arg)
+ error (_("Python scripting is not supported in this copy of GDB."));
+ else
+ {
+ struct command_line *l = get_command_line (python_control, "");
+ struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
+ execute_control_command_untraced (l);
+ do_cleanups (cleanups);
+ }
+}
+
+void
+eval_python_from_control_command (struct command_line *cmd)
+{
+ error (_("Python scripting is not supported in this copy of GDB."));
+}
+
+void
+source_python_script (FILE *stream, char *file)
+{
+ fclose (stream);
+ throw_error (UNSUPPORTED_ERROR,
+ _("Python scripting is not supported in this copy of GDB."));
+}
+
+#endif /* HAVE_PYTHON */
+
+
+
+/* Lists for 'maint set python' commands. */
+
+static struct cmd_list_element *set_python_list;
+static struct cmd_list_element *show_python_list;
+
+/* Function for use by 'maint set python' prefix command. */
+
+static void
+set_python (char *args, int from_tty)
+{
+ help_list (set_python_list, "maintenance set python ", -1, gdb_stdout);
+}
+
+/* Function for use by 'maint show python' prefix command. */
+
+static void
+show_python (char *args, int from_tty)
+{
+ cmd_show_list (show_python_list, from_tty, "");
+}
+
+/* Initialize the Python code. */
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_python;
+
+void
+_initialize_python (void)
+{
+ add_com ("python", class_obscure, python_command,
+#ifdef HAVE_PYTHON
+ _("\
+Evaluate a Python command.\n\
+\n\
+The command can be given as an argument, for instance:\n\
+\n\
+ python print 23\n\
+\n\
+If no argument is given, the following lines are read and used\n\
+as the Python commands. Type a line containing \"end\" to indicate\n\
+the end of the command.")
+#else /* HAVE_PYTHON */
+ _("\
+Evaluate a Python command.\n\
+\n\
+Python scripting is not supported in this copy of GDB.\n\
+This command is only a placeholder.")
+#endif /* HAVE_PYTHON */
+ );
+
+ add_prefix_cmd ("python", no_class, show_python,
+ _("Prefix command for python maintenance settings."),
+ &show_python_list, "maintenance show python ", 0,
+ &maintenance_show_cmdlist);
+ add_prefix_cmd ("python", no_class, set_python,
+ _("Prefix command for python maintenance settings."),
+ &set_python_list, "maintenance set python ", 0,
+ &maintenance_set_cmdlist);
+
+ add_setshow_boolean_cmd ("print-stack", class_maintenance,
+ &gdbpy_should_print_stack, _("\
+Enable or disable printing of Python stack dump on error."), _("\
+Show whether Python stack will be printed on error."), _("\
+Enables or disables printing of Python stack traces."),
+ NULL, NULL,
+ &set_python_list,
+ &show_python_list);
+
+ add_setshow_boolean_cmd ("auto-load", class_maintenance,
+ &gdbpy_auto_load, _("\
+Enable or disable auto-loading of Python code when an object is opened."), _("\
+Show whether Python code will be auto-loaded when an object is opened."), _("\
+Enables or disables auto-loading of Python code when an object is opened."),
+ NULL, NULL,
+ &set_python_list,
+ &show_python_list);
+
+#ifdef HAVE_PYTHON
+ Py_Initialize ();
+ PyEval_InitThreads ();
+
+ gdb_module = Py_InitModule ("gdb", GdbMethods);
+
+ /* The casts to (char*) are for python 2.4. */
+ PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version);
+ PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name);
+ PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
+
+ gdbpy_initialize_values ();
+ gdbpy_initialize_frames ();
+ gdbpy_initialize_commands ();
+ gdbpy_initialize_functions ();
+ gdbpy_initialize_types ();
+ gdbpy_initialize_objfile ();
+ gdbpy_initialize_lazy_string ();
+
+ PyRun_SimpleString ("import gdb");
+ PyRun_SimpleString ("gdb.pretty_printers = []");
+
+ observer_attach_new_objfile (gdbpy_new_objfile);
+
+ gdbpy_to_string_cst = PyString_FromString ("to_string");
+ gdbpy_children_cst = PyString_FromString ("children");
+ gdbpy_display_hint_cst = PyString_FromString ("display_hint");
+ gdbpy_doc_cst = PyString_FromString ("__doc__");
+
+ /* Create a couple objects which are used for Python's stdout and
+ stderr. */
+ PyRun_SimpleString ("\
+import sys\n\
+class GdbOutputFile:\n\
+ def close(self):\n\
+ # Do nothing.\n\
+ return None\n\
+\n\
+ def isatty(self):\n\
+ return False\n\
+\n\
+ def write(self, s):\n\
+ gdb.write(s)\n\
+\n\
+ def writelines(self, iterable):\n\
+ for line in iterable:\n\
+ self.write(line)\n\
+\n\
+ def flush(self):\n\
+ gdb.flush()\n\
+\n\
+sys.stderr = GdbOutputFile()\n\
+sys.stdout = GdbOutputFile()\n\
+");
+
+ /* Release the GIL while gdb runs. */
+ PyThreadState_Swap (NULL);
+ PyEval_ReleaseLock ();
+
+#endif /* HAVE_PYTHON */
+}
+
+
+
+#if HAVE_PYTHON
+
+static PyMethodDef GdbMethods[] =
+{
+ { "history", gdbpy_history, METH_VARARGS,
+ "Get a value from history" },
+ { "execute", execute_gdb_command, METH_VARARGS,
+ "Execute a gdb command" },
+ { "parameter", gdbpy_parameter, METH_VARARGS,
+ "Return a gdb parameter's value" },
+
+ { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
+ "Find the default visualizer for a Value." },
+
+ { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
+ "Return the current Objfile being loaded, or None." },
+ { "objfiles", gdbpy_objfiles, METH_NOARGS,
+ "Return a sequence of all loaded objfiles." },
+
+ { "selected_frame", gdbpy_selected_frame, METH_NOARGS,
+ "selected_frame () -> gdb.Frame.\n\
+Return the selected frame object." },
+ { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS,
+ "stop_reason_string (Integer) -> String.\n\
+Return a string explaining unwind stop reason." },
+
+ { "lookup_type", (PyCFunction) gdbpy_lookup_type,
+ METH_VARARGS | METH_KEYWORDS,
+ "lookup_type (name [, block]) -> type\n\
+Return a Type corresponding to the given name." },
+
+ { "parse_and_eval", gdbpy_parse_and_eval, METH_VARARGS,
+ "parse_and_eval (String) -> Value.\n\
+Parse String as an expression, evaluate it, and return the result as a Value."
+ },
+
+ { "write", gdbpy_write, METH_VARARGS,
+ "Write a string using gdb's filtered stream." },
+ { "flush", gdbpy_flush, METH_NOARGS,
+ "Flush gdb's filtered stdout stream." },
+
+ {NULL, NULL, 0, NULL}
+};
+
+#endif /* HAVE_PYTHON */
python.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-value.c
===================================================================
--- py-value.c (nonexistent)
+++ py-value.c (revision 842)
@@ -0,0 +1,1132 @@
+/* Python interface to values.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "gdb_assert.h"
+#include "charset.h"
+#include "value.h"
+#include "exceptions.h"
+#include "language.h"
+#include "dfp.h"
+#include "valprint.h"
+
+#ifdef HAVE_PYTHON
+
+#include "python-internal.h"
+
+/* Even though Python scalar types directly map to host types, we use
+ target types here to remain consistent with the the values system in
+ GDB (which uses target arithmetic). */
+
+/* Python's integer type corresponds to C's long type. */
+#define builtin_type_pyint builtin_type (python_gdbarch)->builtin_long
+
+/* Python's float type corresponds to C's double type. */
+#define builtin_type_pyfloat builtin_type (python_gdbarch)->builtin_double
+
+/* Python's long type corresponds to C's long long type. */
+#define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
+
+#define builtin_type_pybool \
+ language_bool_type (python_language, python_gdbarch)
+
+#define builtin_type_pychar \
+ language_string_char_type (python_language, python_gdbarch)
+
+typedef struct value_object {
+ PyObject_HEAD
+ struct value_object *next;
+ struct value_object *prev;
+ struct value *value;
+ PyObject *address;
+ PyObject *type;
+} value_object;
+
+/* List of all values which are currently exposed to Python. It is
+ maintained so that when an objfile is discarded, preserve_values
+ can copy the values' types if needed. */
+/* This variable is unnecessarily initialized to NULL in order to
+ work around a linker bug on MacOS. */
+static value_object *values_in_python = NULL;
+
+/* Called by the Python interpreter when deallocating a value object. */
+static void
+valpy_dealloc (PyObject *obj)
+{
+ value_object *self = (value_object *) obj;
+
+ /* Remove SELF from the global list. */
+ if (self->prev)
+ self->prev->next = self->next;
+ else
+ {
+ gdb_assert (values_in_python == self);
+ values_in_python = self->next;
+ }
+ if (self->next)
+ self->next->prev = self->prev;
+
+ value_free (self->value);
+
+ if (self->address)
+ /* Use braces to appease gcc warning. *sigh* */
+ {
+ Py_DECREF (self->address);
+ }
+
+ if (self->type)
+ {
+ Py_DECREF (self->type);
+ }
+
+ self->ob_type->tp_free (self);
+}
+
+/* Helper to push a Value object on the global list. */
+static void
+note_value (value_object *value_obj)
+{
+ value_obj->next = values_in_python;
+ if (value_obj->next)
+ value_obj->next->prev = value_obj;
+ value_obj->prev = NULL;
+ values_in_python = value_obj;
+}
+
+/* Called when a new gdb.Value object needs to be allocated. */
+static PyObject *
+valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
+{
+ struct value *value = NULL; /* Initialize to appease gcc warning. */
+ value_object *value_obj;
+
+ if (PyTuple_Size (args) != 1)
+ {
+ PyErr_SetString (PyExc_TypeError, _("Value object creation takes only "
+ "1 argument"));
+ return NULL;
+ }
+
+ value_obj = (value_object *) subtype->tp_alloc (subtype, 1);
+ if (value_obj == NULL)
+ {
+ PyErr_SetString (PyExc_MemoryError, _("Could not allocate memory to "
+ "create Value object."));
+ return NULL;
+ }
+
+ value = convert_value_from_python (PyTuple_GetItem (args, 0));
+ if (value == NULL)
+ {
+ subtype->tp_free (value_obj);
+ return NULL;
+ }
+
+ value_obj->value = value;
+ value_incref (value);
+ value_obj->address = NULL;
+ value_obj->type = NULL;
+ note_value (value_obj);
+
+ return (PyObject *) value_obj;
+}
+
+/* Iterate over all the Value objects, calling preserve_one_value on
+ each. */
+void
+preserve_python_values (struct objfile *objfile, htab_t copied_types)
+{
+ value_object *iter;
+
+ for (iter = values_in_python; iter; iter = iter->next)
+ preserve_one_value (iter->value, objfile, copied_types);
+}
+
+/* Given a value of a pointer type, apply the C unary * operator to it. */
+static PyObject *
+valpy_dereference (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_ind (((value_object *) self)->value);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (res_val);
+}
+
+/* Return "&value". */
+static PyObject *
+valpy_get_address (PyObject *self, void *closure)
+{
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ value_object *val_obj = (value_object *) self;
+ volatile struct gdb_exception except;
+
+ if (!val_obj->address)
+ {
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ res_val = value_addr (val_obj->value);
+ }
+ if (except.reason < 0)
+ {
+ val_obj->address = Py_None;
+ Py_INCREF (Py_None);
+ }
+ else
+ val_obj->address = value_to_value_object (res_val);
+ }
+
+ Py_INCREF (val_obj->address);
+
+ return val_obj->address;
+}
+
+/* Return type of the value. */
+static PyObject *
+valpy_get_type (PyObject *self, void *closure)
+{
+ value_object *obj = (value_object *) self;
+ if (!obj->type)
+ {
+ obj->type = type_to_type_object (value_type (obj->value));
+ if (!obj->type)
+ {
+ obj->type = Py_None;
+ Py_INCREF (obj->type);
+ }
+ }
+ Py_INCREF (obj->type);
+ return obj->type;
+}
+
+/* Implementation of gdb.Value.lazy_string ([encoding] [, length]) ->
+ string. Return a PyObject representing a lazy_string_object type.
+ A lazy string is a pointer to a string with an optional encoding and
+ length. If ENCODING is not given, encoding is set to None. If an
+ ENCODING is provided the encoding parameter is set to ENCODING, but
+ the string is not encoded. If LENGTH is provided then the length
+ parameter is set to LENGTH, otherwise length will be set to -1 (first
+ null of appropriate with). */
+static PyObject *
+valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
+{
+ int length = -1;
+ struct value *value = ((value_object *) self)->value;
+ const char *user_encoding = NULL;
+ static char *keywords[] = { "encoding", "length", NULL };
+ PyObject *str_obj;
+
+ if (!PyArg_ParseTupleAndKeywords (args, kw, "|si", keywords,
+ &user_encoding, &length))
+ return NULL;
+
+ if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
+ value = value_ind (value);
+
+ str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
+ user_encoding, value_type (value));
+
+ return (PyObject *) str_obj;
+}
+
+/* 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 = -1, ret = 0;
+ gdb_byte *buffer;
+ struct value *value = ((value_object *) self)->value;
+ volatile struct gdb_exception except;
+ PyObject *unicode;
+ const char *encoding = NULL;
+ const char *errors = NULL;
+ const char *user_encoding = NULL;
+ const char *la_encoding = NULL;
+ struct type *char_type;
+ static char *keywords[] = { "encoding", "errors", "length", NULL };
+
+ if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
+ &user_encoding, &errors, &length))
+ return NULL;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ LA_GET_STRING (value, &buffer, &length, &char_type, &la_encoding);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
+ unicode = PyUnicode_Decode (buffer, length * TYPE_LENGTH (char_type),
+ encoding, errors);
+ xfree (buffer);
+
+ return unicode;
+}
+
+/* Cast a value to a given type. */
+static PyObject *
+valpy_cast (PyObject *self, PyObject *args)
+{
+ PyObject *type_obj;
+ struct type *type;
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ volatile struct gdb_exception except;
+
+ if (! PyArg_ParseTuple (args, "O", &type_obj))
+ return NULL;
+
+ type = type_object_to_type (type_obj);
+ if (! type)
+ {
+ PyErr_SetString (PyExc_RuntimeError, "argument must be a Type");
+ return NULL;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ res_val = value_cast (type, ((value_object *) self)->value);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (res_val);
+}
+
+static Py_ssize_t
+valpy_length (PyObject *self)
+{
+ /* We don't support getting the number of elements in a struct / class. */
+ PyErr_SetString (PyExc_NotImplementedError,
+ "Invalid operation on gdb.Value.");
+ return -1;
+}
+
+/* Given string name of an element inside structure, return its value
+ object. */
+static PyObject *
+valpy_getitem (PyObject *self, PyObject *key)
+{
+ value_object *self_value = (value_object *) self;
+ char *field = NULL;
+ struct value *res_val = NULL;
+ volatile struct gdb_exception except;
+
+ if (gdbpy_is_string (key))
+ {
+ field = python_string_to_host_string (key);
+ if (field == NULL)
+ return NULL;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct value *tmp = self_value->value;
+
+ 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)
+ {
+ /* Check the value's type is something that can be accessed via
+ a subscript. */
+ struct type *type;
+ tmp = coerce_ref (tmp);
+ type = check_typedef (value_type (tmp));
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_PTR)
+ error( _("Cannot subscript requested type"));
+ else
+ res_val = value_subscript (tmp, value_as_long (idx));
+ }
+ }
+ }
+
+ xfree (field);
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return res_val ? value_to_value_object (res_val) : NULL;
+}
+
+static int
+valpy_setitem (PyObject *self, PyObject *key, PyObject *value)
+{
+ PyErr_Format (PyExc_NotImplementedError,
+ _("Setting of struct elements is not currently supported."));
+ return -1;
+}
+
+/* Called by the Python interpreter to obtain string representation
+ of the object. */
+static PyObject *
+valpy_str (PyObject *self)
+{
+ char *s = NULL;
+ struct ui_file *stb;
+ struct cleanup *old_chain;
+ PyObject *result;
+ struct value_print_options opts;
+ volatile struct gdb_exception except;
+
+ get_user_print_options (&opts);
+ opts.deref_ref = 0;
+
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ common_val_print (((value_object *) self)->value, stb, 0,
+ &opts, python_language);
+ s = ui_file_xstrdup (stb, NULL);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ do_cleanups (old_chain);
+
+ result = PyUnicode_Decode (s, strlen (s), host_charset (), NULL);
+ xfree (s);
+
+ return result;
+}
+
+/* Implements gdb.Value.is_optimized_out. */
+static PyObject *
+valpy_get_is_optimized_out (PyObject *self, void *closure)
+{
+ struct value *value = ((value_object *) self)->value;
+
+ if (value_optimized_out (value))
+ Py_RETURN_TRUE;
+
+ Py_RETURN_FALSE;
+}
+
+enum valpy_opcode
+{
+ VALPY_ADD,
+ VALPY_SUB,
+ VALPY_MUL,
+ VALPY_DIV,
+ VALPY_REM,
+ VALPY_POW,
+ VALPY_LSH,
+ VALPY_RSH,
+ VALPY_BITAND,
+ VALPY_BITOR,
+ VALPY_BITXOR
+};
+
+/* If TYPE is a reference, return the target; otherwise return TYPE. */
+#define STRIP_REFERENCE(TYPE) \
+ ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+
+/* Returns a value object which is the result of applying the operation
+ specified by OPCODE to the given arguments. */
+static PyObject *
+valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
+{
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct value *arg1, *arg2;
+
+ /* If the gdb.Value object is the second operand, then it will be passed
+ to us as the OTHER argument, and SELF will be an entirely different
+ 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. */
+ arg1 = convert_value_from_python (self);
+ if (arg1 == NULL)
+ break;
+
+ arg2 = convert_value_from_python (other);
+ if (arg2 == NULL)
+ break;
+
+ switch (opcode)
+ {
+ case VALPY_ADD:
+ {
+ struct type *ltype = value_type (arg1);
+ struct type *rtype = value_type (arg2);
+
+ CHECK_TYPEDEF (ltype);
+ ltype = STRIP_REFERENCE (ltype);
+ CHECK_TYPEDEF (rtype);
+ rtype = STRIP_REFERENCE (rtype);
+
+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && is_integral_type (rtype))
+ res_val = value_ptradd (arg1, value_as_long (arg2));
+ else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
+ && is_integral_type (ltype))
+ res_val = value_ptradd (arg2, value_as_long (arg1));
+ else
+ res_val = value_binop (arg1, arg2, BINOP_ADD);
+ }
+ break;
+ case VALPY_SUB:
+ {
+ struct type *ltype = value_type (arg1);
+ struct type *rtype = value_type (arg2);
+
+ CHECK_TYPEDEF (ltype);
+ ltype = STRIP_REFERENCE (ltype);
+ CHECK_TYPEDEF (rtype);
+ rtype = STRIP_REFERENCE (rtype);
+
+ if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && TYPE_CODE (rtype) == TYPE_CODE_PTR)
+ /* A ptrdiff_t for the target would be preferable here. */
+ res_val = value_from_longest (builtin_type_pyint,
+ value_ptrdiff (arg1, arg2));
+ else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+ && is_integral_type (rtype))
+ res_val = value_ptradd (arg1, - value_as_long (arg2));
+ else
+ res_val = value_binop (arg1, arg2, BINOP_SUB);
+ }
+ break;
+ case VALPY_MUL:
+ res_val = value_binop (arg1, arg2, BINOP_MUL);
+ break;
+ case VALPY_DIV:
+ res_val = value_binop (arg1, arg2, BINOP_DIV);
+ break;
+ case VALPY_REM:
+ res_val = value_binop (arg1, arg2, BINOP_REM);
+ break;
+ case VALPY_POW:
+ res_val = value_binop (arg1, arg2, BINOP_EXP);
+ 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);
+
+ return res_val ? value_to_value_object (res_val) : NULL;
+}
+
+static PyObject *
+valpy_add (PyObject *self, PyObject *other)
+{
+ return valpy_binop (VALPY_ADD, self, other);
+}
+
+static PyObject *
+valpy_subtract (PyObject *self, PyObject *other)
+{
+ return valpy_binop (VALPY_SUB, self, other);
+}
+
+static PyObject *
+valpy_multiply (PyObject *self, PyObject *other)
+{
+ return valpy_binop (VALPY_MUL, self, other);
+}
+
+static PyObject *
+valpy_divide (PyObject *self, PyObject *other)
+{
+ return valpy_binop (VALPY_DIV, self, other);
+}
+
+static PyObject *
+valpy_remainder (PyObject *self, PyObject *other)
+{
+ return valpy_binop (VALPY_REM, self, other);
+}
+
+static PyObject *
+valpy_power (PyObject *self, PyObject *other, PyObject *unused)
+{
+ /* We don't support the ternary form of pow. I don't know how to express
+ that, so let's just throw NotImplementedError to at least do something
+ about it. */
+ if (unused != Py_None)
+ {
+ PyErr_SetString (PyExc_NotImplementedError,
+ "Invalid operation on gdb.Value.");
+ return NULL;
+ }
+
+ return valpy_binop (VALPY_POW, self, other);
+}
+
+static PyObject *
+valpy_negative (PyObject *self)
+{
+ struct value *val = NULL;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ val = value_neg (((value_object *) self)->value);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (val);
+}
+
+static PyObject *
+valpy_positive (PyObject *self)
+{
+ return value_to_value_object (((value_object *) self)->value);
+}
+
+static PyObject *
+valpy_absolute (PyObject *self)
+{
+ struct value *value = ((value_object *) self)->value;
+ if (value_less (value, value_zero (value_type (value), not_lval)))
+ return valpy_negative (self);
+ else
+ return valpy_positive (self);
+}
+
+/* Implements boolean evaluation of gdb.Value. */
+static int
+valpy_nonzero (PyObject *self)
+{
+ value_object *self_value = (value_object *) self;
+ struct type *type;
+
+ type = check_typedef (value_type (self_value->value));
+
+ if (is_integral_type (type) || TYPE_CODE (type) == TYPE_CODE_PTR)
+ return !!value_as_long (self_value->value);
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ return value_as_double (self_value->value) != 0;
+ else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
+ return !decimal_is_zero (value_contents (self_value->value),
+ TYPE_LENGTH (type),
+ gdbarch_byte_order (get_type_arch (type)));
+ else
+ {
+ PyErr_SetString (PyExc_TypeError, _("Attempted truth testing on invalid "
+ "gdb.Value type."));
+ return 0;
+ }
+}
+
+/* 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. */
+static PyObject *
+valpy_richcompare (PyObject *self, PyObject *other, int op)
+{
+ int result = 0;
+ struct value *value_other;
+ volatile struct gdb_exception except;
+
+ if (other == Py_None)
+ /* Comparing with None is special. From what I can tell, in Python
+ None is smaller than anything else. */
+ switch (op) {
+ case Py_LT:
+ case Py_LE:
+ case Py_EQ:
+ Py_RETURN_FALSE;
+ case Py_NE:
+ case Py_GT:
+ case Py_GE:
+ Py_RETURN_TRUE;
+ default:
+ /* Can't happen. */
+ PyErr_SetString (PyExc_NotImplementedError,
+ "Invalid operation on gdb.Value.");
+ return NULL;
+ }
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ value_other = convert_value_from_python (other);
+ if (value_other == NULL)
+ {
+ result = -1;
+ break;
+ }
+
+ switch (op) {
+ case Py_LT:
+ result = value_less (((value_object *) self)->value, value_other);
+ break;
+ case Py_LE:
+ result = value_less (((value_object *) self)->value, value_other)
+ || value_equal (((value_object *) self)->value, value_other);
+ break;
+ case Py_EQ:
+ result = value_equal (((value_object *) self)->value, value_other);
+ break;
+ case Py_NE:
+ result = !value_equal (((value_object *) self)->value, value_other);
+ break;
+ case Py_GT:
+ result = value_less (value_other, ((value_object *) self)->value);
+ break;
+ case Py_GE:
+ result = value_less (value_other, ((value_object *) self)->value)
+ || value_equal (((value_object *) self)->value, value_other);
+ break;
+ default:
+ /* Can't happen. */
+ PyErr_SetString (PyExc_NotImplementedError,
+ "Invalid operation on gdb.Value.");
+ result = -1;
+ break;
+ }
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ /* In this case, the Python exception has already been set. */
+ if (result < 0)
+ return NULL;
+
+ if (result == 1)
+ Py_RETURN_TRUE;
+
+ 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);
+
+#ifdef HAVE_LONG_LONG /* Defined by Python. */
+ /* If we have 'long long', and the value overflows a 'long', use a
+ Python Long; otherwise use a Python Int. */
+ if (sizeof (l) > sizeof (long) && (l > PyInt_GetMax ()
+ || l < (- (LONGEST) PyInt_GetMax ()) - 1))
+ return PyLong_FromLongLong (l);
+#endif
+ 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);
+
+#ifdef HAVE_LONG_LONG /* Defined by Python. */
+ return PyLong_FromLongLong (l);
+#else
+ return PyLong_FromLong (l);
+#endif
+}
+
+/* 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,
+ so its lifetime is not bound to the execution of a command. */
+PyObject *
+value_to_value_object (struct value *val)
+{
+ value_object *val_obj;
+
+ val_obj = PyObject_New (value_object, &value_object_type);
+ if (val_obj != NULL)
+ {
+ val_obj->value = val;
+ value_incref (val);
+ val_obj->address = NULL;
+ val_obj->type = NULL;
+ note_value (val_obj);
+ }
+
+ return (PyObject *) val_obj;
+}
+
+/* Returns a borrowed reference to the struct value corresponding to
+ the given value object. */
+struct value *
+value_object_to_value (PyObject *self)
+{
+ value_object *real;
+ if (! PyObject_TypeCheck (self, &value_object_type))
+ return NULL;
+ real = (value_object *) self;
+ return real->value;
+}
+
+/* Try to convert a Python value to a gdb value. If the value cannot
+ be converted, set a Python exception and return NULL. Returns a
+ reference to a new value on the all_values chain. */
+
+struct value *
+convert_value_from_python (PyObject *obj)
+{
+ struct value *value = NULL; /* -Wall */
+ PyObject *target_str, *unicode_str;
+ struct cleanup *old;
+ volatile struct gdb_exception except;
+ int cmp;
+
+ gdb_assert (obj != NULL);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ if (PyBool_Check (obj))
+ {
+ 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_cstring (s, strlen (s), builtin_type_pychar);
+ do_cleanups (old);
+ }
+ }
+ else if (PyObject_TypeCheck (obj, &value_object_type))
+ value = value_copy (((value_object *) obj)->value);
+ else if (gdbpy_is_lazy_string (obj))
+ {
+ PyObject *result;
+ PyObject *function = PyString_FromString ("value");
+ result = PyObject_CallMethodObjArgs (obj, function, NULL);
+ value = value_copy (((value_object *) result)->value);
+ }
+ else
+ PyErr_Format (PyExc_TypeError, _("Could not convert Python object: %s"),
+ PyString_AsString (PyObject_Str (obj)));
+ }
+ if (except.reason < 0)
+ {
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return NULL;
+ }
+
+ return value;
+}
+
+/* Returns value object in the ARGth position in GDB's history. */
+PyObject *
+gdbpy_history (PyObject *self, PyObject *args)
+{
+ int i;
+ struct value *res_val = NULL; /* Initialize to appease gcc warning. */
+ volatile struct gdb_exception except;
+
+ if (!PyArg_ParseTuple (args, "i", &i))
+ return NULL;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ res_val = access_value_history (i);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return value_to_value_object (res_val);
+}
+
+void
+gdbpy_initialize_values (void)
+{
+ if (PyType_Ready (&value_object_type) < 0)
+ return;
+
+ Py_INCREF (&value_object_type);
+ PyModule_AddObject (gdb_module, "Value", (PyObject *) &value_object_type);
+
+ values_in_python = NULL;
+}
+
+
+
+static PyGetSetDef value_object_getset[] = {
+ { "address", valpy_get_address, NULL, "The address of the value.",
+ NULL },
+ { "is_optimized_out", valpy_get_is_optimized_out, NULL,
+ "Boolean telling whether the value is optimized out (i.e., not available).",
+ NULL },
+ { "type", valpy_get_type, NULL, "Type of the value.", NULL },
+ {NULL} /* Sentinel */
+};
+
+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." },
+ { "lazy_string", (PyCFunction) valpy_lazy_string, METH_VARARGS | METH_KEYWORDS,
+ "lazy_string ([encoding] [, length]) -> lazy_string\n\
+Return a lazy string representation of the value." },
+ { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
+ "string ([encoding] [, errors] [, length]) -> string\n\
+Return Unicode string representation of the value." },
+ {NULL} /* Sentinel */
+};
+
+static PyNumberMethods value_object_as_number = {
+ valpy_add,
+ valpy_subtract,
+ valpy_multiply,
+ valpy_divide,
+ valpy_remainder,
+ NULL, /* nb_divmod */
+ valpy_power, /* nb_power */
+ valpy_negative, /* nb_negative */
+ valpy_positive, /* nb_positive */
+ valpy_absolute, /* nb_absolute */
+ 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 = {
+ valpy_length,
+ valpy_getitem,
+ valpy_setitem
+};
+
+PyTypeObject value_object_type = {
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Value", /*tp_name*/
+ sizeof (value_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ valpy_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ &value_object_as_number, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &value_object_as_mapping, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ valpy_str, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/
+ "GDB value object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ valpy_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ value_object_methods, /* tp_methods */
+ 0, /* tp_members */
+ value_object_getset, /* 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 */
+};
+
+#else
+
+void
+preserve_python_values (struct objfile *objfile, htab_t copied_types)
+{
+ /* Nothing. */
+}
+
+#endif /* HAVE_PYTHON */
py-value.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-utils.c
===================================================================
--- py-utils.c (nonexistent)
+++ py-utils.c (revision 842)
@@ -0,0 +1,221 @@
+/* General utility routines for GDB/Python.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "charset.h"
+#include "python-internal.h"
+
+
+/* This is a cleanup function which decrements the refcount on a
+ Python object. */
+
+static void
+py_decref (void *p)
+{
+ PyObject *py = p;
+ /* Note that we need the extra braces in this 'if' to avoid a
+ warning from gcc. */
+ if (py)
+ {
+ Py_DECREF (py);
+ }
+}
+
+/* Return a new cleanup which will decrement the Python object's
+ refcount when run. */
+
+struct cleanup *
+make_cleanup_py_decref (PyObject *py)
+{
+ return make_cleanup (py_decref, (void *) py);
+}
+
+/* Converts a Python 8-bit string to a unicode string object. Assumes the
+ 8-bit string is in the host charset. If an error occurs during conversion,
+ returns NULL with a python exception set.
+
+ As an added bonus, the functions accepts a unicode string and returns it
+ right away, so callers don't need to check which kind of string they've
+ got.
+
+ If the given object is not one of the mentioned string types, NULL is
+ returned, with the TypeError python exception set. */
+PyObject *
+python_string_to_unicode (PyObject *obj)
+{
+ PyObject *unicode_str;
+
+ /* If obj is already a unicode string, just return it.
+ I wish life was always that simple... */
+ if (PyUnicode_Check (obj))
+ {
+ unicode_str = obj;
+ Py_INCREF (obj);
+ }
+
+ else if (PyString_Check (obj))
+ unicode_str = PyUnicode_FromEncodedObject (obj, host_charset (), NULL);
+ else
+ {
+ PyErr_SetString (PyExc_TypeError,
+ _("Expected a string or unicode object."));
+ unicode_str = NULL;
+ }
+
+ 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 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.
+
+ The caller is responsible for xfree'ing the string. */
+char *
+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.
+
+ The caller is responsible for xfree'ing the string. */
+char *
+python_string_to_target_string (PyObject *obj)
+{
+ PyObject *str;
+ char *result;
+
+ str = python_string_to_unicode (obj);
+ if (str == NULL)
+ return NULL;
+
+ result = unicode_to_target_string (str);
+ Py_DECREF (str);
+ 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.
+
+ The caller is responsible for xfree'ing the string. */
+char *
+python_string_to_host_string (PyObject *obj)
+{
+ PyObject *str;
+ char *result;
+
+ str = python_string_to_unicode (obj);
+ if (str == NULL)
+ return NULL;
+
+ result = unicode_to_encoded_string (str, host_charset ());
+ Py_DECREF (str);
+ return result;
+}
+
+/* Converts a target string of LENGTH bytes in the target's charset to a
+ Python Unicode string. If LENGTH is -1, convert until a null byte is found.
+
+ Returns NULL on error, with a python exception set. */
+PyObject *
+target_string_to_unicode (const gdb_byte *str, int length)
+{
+ if (length == -1)
+ length = strlen (str);
+
+ return PyUnicode_Decode (str, length, target_charset (), NULL);
+}
+
+/* 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);
+}
py-utils.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: python.h
===================================================================
--- python.h (nonexistent)
+++ python.h (revision 842)
@@ -0,0 +1,37 @@
+/* Python/gdb header for generic use in gdb
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#ifndef GDB_PYTHON_H
+#define GDB_PYTHON_H
+
+#include "value.h"
+
+void eval_python_from_control_command (struct command_line *);
+
+void source_python_script (FILE *stream, char *file);
+
+int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ const struct language_defn *language);
+
+void preserve_python_values (struct objfile *objfile, htab_t copied_types);
+
+#endif /* GDB_PYTHON_H */
python.h
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-type.c
===================================================================
--- py-type.c (nonexistent)
+++ py-type.c (revision 842)
@@ -0,0 +1,875 @@
+/* Python interface to types.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbtypes.h"
+#include "cp-support.h"
+#include "demangle.h"
+#include "objfiles.h"
+#include "language.h"
+
+typedef struct pyty_type_object
+{
+ PyObject_HEAD
+ struct type *type;
+
+ /* If a Type object is associated with an objfile, it is kept on a
+ doubly-linked list, rooted in the objfile. This lets us copy the
+ underlying struct type when the objfile is deleted. */
+ struct pyty_type_object *prev;
+ struct pyty_type_object *next;
+} type_object;
+
+static PyTypeObject type_object_type;
+
+/* A Field object. */
+typedef struct pyty_field_object
+{
+ PyObject_HEAD
+
+ /* Dictionary holding our attributes. */
+ PyObject *dict;
+} field_object;
+
+static PyTypeObject field_object_type;
+
+/* This is used to initialize various gdb.TYPE_ constants. */
+struct pyty_code
+{
+ /* The code. */
+ enum type_code code;
+ /* The name. */
+ const char *name;
+};
+
+#define ENTRY(X) { X, #X }
+
+static struct pyty_code pyty_codes[] =
+{
+ ENTRY (TYPE_CODE_PTR),
+ ENTRY (TYPE_CODE_ARRAY),
+ ENTRY (TYPE_CODE_STRUCT),
+ ENTRY (TYPE_CODE_UNION),
+ ENTRY (TYPE_CODE_ENUM),
+ ENTRY (TYPE_CODE_FLAGS),
+ ENTRY (TYPE_CODE_FUNC),
+ ENTRY (TYPE_CODE_INT),
+ ENTRY (TYPE_CODE_FLT),
+ ENTRY (TYPE_CODE_VOID),
+ ENTRY (TYPE_CODE_SET),
+ ENTRY (TYPE_CODE_RANGE),
+ ENTRY (TYPE_CODE_STRING),
+ ENTRY (TYPE_CODE_BITSTRING),
+ ENTRY (TYPE_CODE_ERROR),
+ ENTRY (TYPE_CODE_METHOD),
+ ENTRY (TYPE_CODE_METHODPTR),
+ ENTRY (TYPE_CODE_MEMBERPTR),
+ ENTRY (TYPE_CODE_REF),
+ ENTRY (TYPE_CODE_CHAR),
+ ENTRY (TYPE_CODE_BOOL),
+ ENTRY (TYPE_CODE_COMPLEX),
+ ENTRY (TYPE_CODE_TYPEDEF),
+ ENTRY (TYPE_CODE_NAMESPACE),
+ ENTRY (TYPE_CODE_DECFLOAT),
+ ENTRY (TYPE_CODE_INTERNAL_FUNCTION),
+ { TYPE_CODE_UNDEF, NULL }
+};
+
+
+
+static void
+field_dealloc (PyObject *obj)
+{
+ field_object *f = (field_object *) obj;
+ Py_XDECREF (f->dict);
+ f->ob_type->tp_free (obj);
+}
+
+static PyObject *
+field_new (void)
+{
+ field_object *result = PyObject_New (field_object, &field_object_type);
+ if (result)
+ {
+ result->dict = PyDict_New ();
+ if (!result->dict)
+ {
+ Py_DECREF (result);
+ result = NULL;
+ }
+ }
+ return (PyObject *) result;
+}
+
+
+
+/* Return the code for this type. */
+static PyObject *
+typy_get_code (PyObject *self, void *closure)
+{
+ struct type *type = ((type_object *) self)->type;
+ return PyInt_FromLong (TYPE_CODE (type));
+}
+
+/* Helper function for typy_fields which converts a single field to a
+ dictionary. Returns NULL on error. */
+static PyObject *
+convert_field (struct type *type, int field)
+{
+ PyObject *result = field_new ();
+ PyObject *arg;
+
+ if (!result)
+ return NULL;
+
+ if (!field_is_static (&TYPE_FIELD (type, field)))
+ {
+ arg = PyLong_FromLong (TYPE_FIELD_BITPOS (type, field));
+ if (!arg)
+ goto fail;
+
+ if (PyObject_SetAttrString (result, "bitpos", arg) < 0)
+ goto failarg;
+ }
+
+ if (TYPE_FIELD_NAME (type, field))
+ arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
+ else
+ {
+ arg = Py_None;
+ Py_INCREF (arg);
+ }
+ if (!arg)
+ goto fail;
+ if (PyObject_SetAttrString (result, "name", arg) < 0)
+ goto failarg;
+
+ arg = TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False;
+ Py_INCREF (arg);
+ if (PyObject_SetAttrString (result, "artificial", arg) < 0)
+ goto failarg;
+
+ if (TYPE_CODE (type) == TYPE_CODE_CLASS)
+ arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False;
+ else
+ arg = Py_False;
+ Py_INCREF (arg);
+ if (PyObject_SetAttrString (result, "is_base_class", arg) < 0)
+ goto failarg;
+
+ arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field));
+ if (!arg)
+ goto fail;
+ if (PyObject_SetAttrString (result, "bitsize", arg) < 0)
+ goto failarg;
+
+ /* A field can have a NULL type in some situations. */
+ if (TYPE_FIELD_TYPE (type, field) == NULL)
+ {
+ arg = Py_None;
+ Py_INCREF (arg);
+ }
+ else
+ arg = type_to_type_object (TYPE_FIELD_TYPE (type, field));
+ if (!arg)
+ goto fail;
+ if (PyObject_SetAttrString (result, "type", arg) < 0)
+ goto failarg;
+
+ return result;
+
+ failarg:
+ Py_DECREF (arg);
+ fail:
+ Py_DECREF (result);
+ return NULL;
+}
+
+/* Return a sequence of all fields. Each field is a dictionary with
+ some pre-defined keys. */
+static PyObject *
+typy_fields (PyObject *self, PyObject *args)
+{
+ PyObject *result;
+ int i;
+ struct type *type = ((type_object *) self)->type;
+
+ /* We would like to make a tuple here, make fields immutable, and
+ then memoize the result (and perhaps make Field.type() lazy).
+ However, that can lead to cycles. */
+ result = PyList_New (0);
+
+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ PyObject *dict = convert_field (type, i);
+ if (!dict)
+ {
+ Py_DECREF (result);
+ return NULL;
+ }
+ if (PyList_Append (result, dict))
+ {
+ Py_DECREF (dict);
+ Py_DECREF (result);
+ return NULL;
+ }
+ }
+
+ return result;
+}
+
+/* Return the type's tag, or None. */
+static PyObject *
+typy_get_tag (PyObject *self, void *closure)
+{
+ struct type *type = ((type_object *) self)->type;
+ if (!TYPE_TAG_NAME (type))
+ Py_RETURN_NONE;
+ return PyString_FromString (TYPE_TAG_NAME (type));
+}
+
+/* Return the type, stripped of typedefs. */
+static PyObject *
+typy_strip_typedefs (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+
+ return type_to_type_object (check_typedef (type));
+}
+
+/* Return a Type object which represents a pointer to SELF. */
+static PyObject *
+typy_pointer (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ type = lookup_pointer_type (type);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return type_to_type_object (type);
+}
+
+/* Return the range of a type represented by SELF. The return type is
+ a tuple. The first element of the tuple contains the low bound,
+ while the second element of the tuple contains the high bound. */
+static PyObject *
+typy_range (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ PyObject *result;
+ PyObject *low_bound = NULL, *high_bound = NULL;
+ /* Initialize these to appease GCC warnings. */
+ LONGEST low = 0, high = 0;
+
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_STRING
+ && TYPE_CODE (type) != TYPE_CODE_RANGE)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ "This type does not have a range.");
+ return NULL;
+ }
+
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRING:
+ low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
+ high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type));
+ break;
+ case TYPE_CODE_RANGE:
+ low = TYPE_LOW_BOUND (type);
+ high = TYPE_HIGH_BOUND (type);
+ break;
+ }
+
+ low_bound = PyLong_FromLong (low);
+ if (!low_bound)
+ goto failarg;
+
+ high_bound = PyLong_FromLong (high);
+ if (!high_bound)
+ goto failarg;
+
+ result = PyTuple_New (2);
+ if (!result)
+ goto failarg;
+
+ if (PyTuple_SetItem (result, 0, low_bound) != 0)
+ {
+ Py_DECREF (result);
+ goto failarg;
+ }
+ if (PyTuple_SetItem (result, 1, high_bound) != 0)
+ {
+ Py_DECREF (high_bound);
+ Py_DECREF (result);
+ return NULL;
+ }
+ return result;
+
+ failarg:
+ Py_XDECREF (high_bound);
+ Py_XDECREF (low_bound);
+ return NULL;
+}
+
+/* Return a Type object which represents a reference to SELF. */
+static PyObject *
+typy_reference (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ type = lookup_reference_type (type);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return type_to_type_object (type);
+}
+
+/* Return a Type object which represents the target type of SELF. */
+static PyObject *
+typy_target (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+
+ if (!TYPE_TARGET_TYPE (type))
+ {
+ PyErr_SetString (PyExc_RuntimeError, "type does not have a target");
+ return NULL;
+ }
+
+ return type_to_type_object (TYPE_TARGET_TYPE (type));
+}
+
+/* Return a const-qualified type variant. */
+static PyObject *
+typy_const (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ type = make_cv_type (1, 0, type, NULL);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return type_to_type_object (type);
+}
+
+/* Return a volatile-qualified type variant. */
+static PyObject *
+typy_volatile (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ type = make_cv_type (0, 1, type, NULL);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return type_to_type_object (type);
+}
+
+/* Return an unqualified type variant. */
+static PyObject *
+typy_unqualified (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ type = make_cv_type (0, 0, type, NULL);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ return type_to_type_object (type);
+}
+
+/* Return the size of the type represented by SELF, in bytes. */
+static PyObject *
+typy_get_sizeof (PyObject *self, void *closure)
+{
+ struct type *type = ((type_object *) self)->type;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ check_typedef (type);
+ }
+ /* Ignore exceptions. */
+
+ return PyLong_FromLong (TYPE_LENGTH (type));
+}
+
+static struct type *
+typy_lookup_typename (char *type_name)
+{
+ struct type *type = NULL;
+ volatile struct gdb_exception except;
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ if (!strncmp (type_name, "struct ", 7))
+ type = lookup_struct (type_name + 7, NULL);
+ else if (!strncmp (type_name, "union ", 6))
+ type = lookup_union (type_name + 6, NULL);
+ else if (!strncmp (type_name, "enum ", 5))
+ type = lookup_enum (type_name + 5, NULL);
+ else
+ type = lookup_typename (python_language, python_gdbarch,
+ type_name, NULL, 0);
+ }
+ if (except.reason < 0)
+ {
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return NULL;
+ }
+
+ return type;
+}
+
+static struct type *
+typy_lookup_type (struct demangle_component *demangled)
+{
+ struct type *type;
+ char *type_name;
+ enum demangle_component_type demangled_type;
+
+ /* Save the type: typy_lookup_type() may (indirectly) overwrite
+ memory pointed by demangled. */
+ demangled_type = demangled->type;
+
+ if (demangled_type == DEMANGLE_COMPONENT_POINTER
+ || demangled_type == DEMANGLE_COMPONENT_REFERENCE
+ || demangled_type == DEMANGLE_COMPONENT_CONST
+ || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
+ {
+ type = typy_lookup_type (demangled->u.s_binary.left);
+ if (! type)
+ return NULL;
+
+ switch (demangled_type)
+ {
+ case DEMANGLE_COMPONENT_REFERENCE:
+ return lookup_reference_type (type);
+ case DEMANGLE_COMPONENT_POINTER:
+ return lookup_pointer_type (type);
+ case DEMANGLE_COMPONENT_CONST:
+ return make_cv_type (1, 0, type, NULL);
+ case DEMANGLE_COMPONENT_VOLATILE:
+ return make_cv_type (0, 1, type, NULL);
+ }
+ }
+
+ type_name = cp_comp_to_string (demangled, 10);
+ type = typy_lookup_typename (type_name);
+ xfree (type_name);
+
+ return type;
+}
+
+static PyObject *
+typy_template_argument (PyObject *self, PyObject *args)
+{
+ int i, argno, n_pointers;
+ struct type *type = ((type_object *) self)->type;
+ struct demangle_component *demangled;
+ const char *err;
+ struct type *argtype;
+
+ if (! PyArg_ParseTuple (args, "i", &argno))
+ return NULL;
+
+ type = check_typedef (type);
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+
+ if (TYPE_NAME (type) == NULL)
+ {
+ PyErr_SetString (PyExc_RuntimeError, "null type name");
+ return NULL;
+ }
+
+ /* Note -- this is not thread-safe. */
+ demangled = cp_demangled_name_to_comp (TYPE_NAME (type), &err);
+ if (! demangled)
+ {
+ PyErr_SetString (PyExc_RuntimeError, err);
+ return NULL;
+ }
+
+ /* Strip off component names. */
+ while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME
+ || demangled->type == DEMANGLE_COMPONENT_LOCAL_NAME)
+ demangled = demangled->u.s_binary.right;
+
+ if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE)
+ {
+ PyErr_SetString (PyExc_RuntimeError, "type is not a template");
+ return NULL;
+ }
+
+ /* Skip from the template to the arguments. */
+ demangled = demangled->u.s_binary.right;
+
+ for (i = 0; demangled && i < argno; ++i)
+ demangled = demangled->u.s_binary.right;
+
+ if (! demangled)
+ {
+ PyErr_Format (PyExc_RuntimeError, "no argument %d in template",
+ argno);
+ return NULL;
+ }
+
+ argtype = typy_lookup_type (demangled->u.s_binary.left);
+ if (! argtype)
+ return NULL;
+
+ return type_to_type_object (argtype);
+}
+
+static PyObject *
+typy_str (PyObject *self)
+{
+ volatile struct gdb_exception except;
+ char *thetype = NULL;
+ long length = 0;
+ PyObject *result;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct cleanup *old_chain;
+ struct ui_file *stb;
+
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
+
+ type_print (type_object_to_type (self), "", stb, -1);
+
+ thetype = ui_file_xstrdup (stb, &length);
+ do_cleanups (old_chain);
+ }
+ if (except.reason < 0)
+ {
+ xfree (thetype);
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+
+ result = PyUnicode_Decode (thetype, length, host_charset (), NULL);
+ xfree (thetype);
+
+ return result;
+}
+
+
+
+static const struct objfile_data *typy_objfile_data_key;
+
+static void
+save_objfile_types (struct objfile *objfile, void *datum)
+{
+ type_object *obj = datum;
+ htab_t copied_types;
+ struct cleanup *cleanup;
+
+ /* This prevents another thread from freeing the objects we're
+ operating on. */
+ cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
+
+ copied_types = create_copied_types_hash (objfile);
+
+ while (obj)
+ {
+ type_object *next = obj->next;
+
+ htab_empty (copied_types);
+
+ obj->type = copy_type_recursive (objfile, obj->type, copied_types);
+
+ obj->next = NULL;
+ obj->prev = NULL;
+
+ obj = next;
+ }
+
+ htab_delete (copied_types);
+
+ do_cleanups (cleanup);
+}
+
+static void
+set_type (type_object *obj, struct type *type)
+{
+ obj->type = type;
+ obj->prev = NULL;
+ if (type && TYPE_OBJFILE (type))
+ {
+ struct objfile *objfile = TYPE_OBJFILE (type);
+
+ obj->next = objfile_data (objfile, typy_objfile_data_key);
+ if (obj->next)
+ obj->next->prev = obj;
+ set_objfile_data (objfile, typy_objfile_data_key, obj);
+ }
+ else
+ obj->next = NULL;
+}
+
+static void
+typy_dealloc (PyObject *obj)
+{
+ type_object *type = (type_object *) obj;
+
+ if (type->prev)
+ type->prev->next = type->next;
+ else if (type->type && TYPE_OBJFILE (type->type))
+ {
+ /* Must reset head of list. */
+ struct objfile *objfile = TYPE_OBJFILE (type->type);
+ if (objfile)
+ set_objfile_data (objfile, typy_objfile_data_key, type->next);
+ }
+ if (type->next)
+ type->next->prev = type->prev;
+
+ type->ob_type->tp_free (type);
+}
+
+/* Create a new Type referring to TYPE. */
+PyObject *
+type_to_type_object (struct type *type)
+{
+ type_object *type_obj;
+
+ type_obj = PyObject_New (type_object, &type_object_type);
+ if (type_obj)
+ set_type (type_obj, type);
+
+ return (PyObject *) type_obj;
+}
+
+struct type *
+type_object_to_type (PyObject *obj)
+{
+ if (! PyObject_TypeCheck (obj, &type_object_type))
+ return NULL;
+ return ((type_object *) obj)->type;
+}
+
+
+
+/* Implementation of gdb.lookup_type. */
+PyObject *
+gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *keywords[] = { "name", NULL };
+ char *type_name = NULL;
+ struct type *type = NULL;
+
+ if (! PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &type_name))
+ return NULL;
+
+ type = typy_lookup_typename (type_name);
+ if (! type)
+ return NULL;
+
+ return (PyObject *) type_to_type_object (type);
+}
+
+void
+gdbpy_initialize_types (void)
+{
+ int i;
+
+ typy_objfile_data_key
+ = register_objfile_data_with_cleanup (save_objfile_types, NULL);
+
+ if (PyType_Ready (&type_object_type) < 0)
+ return;
+ if (PyType_Ready (&field_object_type) < 0)
+ return;
+
+ for (i = 0; pyty_codes[i].name; ++i)
+ {
+ if (PyModule_AddIntConstant (gdb_module,
+ /* Cast needed for Python 2.4. */
+ (char *) pyty_codes[i].name,
+ pyty_codes[i].code) < 0)
+ return;
+ }
+
+ Py_INCREF (&type_object_type);
+ PyModule_AddObject (gdb_module, "Type", (PyObject *) &type_object_type);
+
+ Py_INCREF (&field_object_type);
+ PyModule_AddObject (gdb_module, "Field", (PyObject *) &field_object_type);
+}
+
+
+
+static PyGetSetDef type_object_getset[] =
+{
+ { "code", typy_get_code, NULL,
+ "The code for this type.", NULL },
+ { "sizeof", typy_get_sizeof, NULL,
+ "The size of this type, in bytes.", NULL },
+ { "tag", typy_get_tag, NULL,
+ "The tag name for this type, or None.", NULL },
+ { NULL }
+};
+
+static PyMethodDef type_object_methods[] =
+{
+ { "const", typy_const, METH_NOARGS,
+ "const () -> Type\n\
+Return a const variant of this type." },
+ { "fields", typy_fields, METH_NOARGS,
+ "field () -> list\n\
+Return a sequence holding all the fields of this type.\n\
+Each field is a dictionary." },
+ { "pointer", typy_pointer, METH_NOARGS,
+ "pointer () -> Type\n\
+Return a type of pointer to this type." },
+ { "range", typy_range, METH_NOARGS,
+ "range () -> tuple\n\
+Return a tuple containing the lower and upper range for this type."},
+ { "reference", typy_reference, METH_NOARGS,
+ "reference () -> Type\n\
+Return a type of reference to this type." },
+ { "strip_typedefs", typy_strip_typedefs, METH_NOARGS,
+ "strip_typedefs () -> Type\n\
+Return a type formed by stripping this type of all typedefs."},
+ { "target", typy_target, METH_NOARGS,
+ "target () -> Type\n\
+Return the target type of this type." },
+ { "template_argument", typy_template_argument, METH_VARARGS,
+ "template_argument (arg) -> Type\n\
+Return the type of a template argument." },
+ { "unqualified", typy_unqualified, METH_NOARGS,
+ "unqualified () -> Type\n\
+Return a variant of this type without const or volatile attributes." },
+ { "volatile", typy_volatile, METH_NOARGS,
+ "volatile () -> Type\n\
+Return a volatile variant of this type" },
+ { NULL }
+};
+
+static PyTypeObject type_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Type", /*tp_name*/
+ sizeof (type_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ typy_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ typy_str, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ "GDB type object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ type_object_methods, /* tp_methods */
+ 0, /* tp_members */
+ type_object_getset, /* 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 */
+ 0, /* tp_new */
+};
+
+static PyTypeObject field_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Field", /*tp_name*/
+ sizeof (field_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ field_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
+ "GDB field object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof (field_object, dict), /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
py-type.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-cmd.c
===================================================================
--- py-cmd.c (nonexistent)
+++ py-cmd.c (revision 842)
@@ -0,0 +1,585 @@
+/* gdb commands implemented in Python
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "cli/cli-decode.h"
+#include "completer.h"
+#include "language.h"
+
+/* Struct representing built-in completion types. */
+struct cmdpy_completer
+{
+ /* Python symbol name. */
+ char *name;
+ /* Completion function. */
+ char **(*completer) (struct cmd_list_element *, char *, char *);
+};
+
+static struct cmdpy_completer completers[] =
+{
+ { "COMPLETE_NONE", noop_completer },
+ { "COMPLETE_FILENAME", filename_completer },
+ { "COMPLETE_LOCATION", location_completer },
+ { "COMPLETE_COMMAND", command_completer },
+ { "COMPLETE_SYMBOL", make_symbol_completion_list_fn },
+};
+
+#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))
+
+/* A gdb command. For the time being only ordinary commands (not
+ set/show commands) are allowed. */
+struct cmdpy_object
+{
+ PyObject_HEAD
+
+ /* The corresponding gdb command object, or NULL if the command is
+ no longer installed. */
+ struct cmd_list_element *command;
+
+ /* A prefix command requires storage for a list of its sub-commands.
+ A pointer to this is passed to add_prefix_command, and to add_cmd
+ for sub-commands of that prefix. If this Command is not a prefix
+ command, then this field is unused. */
+ struct cmd_list_element *sub_list;
+};
+
+typedef struct cmdpy_object cmdpy_object;
+
+static PyTypeObject cmdpy_object_type;
+
+
+/* Constants used by this module. */
+static PyObject *invoke_cst;
+static PyObject *complete_cst;
+
+
+
+/* Python function which wraps dont_repeat. */
+static PyObject *
+cmdpy_dont_repeat (PyObject *self, PyObject *args)
+{
+ dont_repeat ();
+ Py_RETURN_NONE;
+}
+
+
+
+/* Called if the gdb cmd_list_element is destroyed. */
+static void
+cmdpy_destroyer (struct cmd_list_element *self, void *context)
+{
+ cmdpy_object *cmd;
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ /* Release our hold on the command object. */
+ cmd = (cmdpy_object *) context;
+ cmd->command = NULL;
+ Py_DECREF (cmd);
+
+ /* We allocated the name, doc string, and perhaps the prefix
+ name. */
+ xfree (self->name);
+ xfree (self->doc);
+ xfree (self->prefixname);
+
+ do_cleanups (cleanup);
+}
+
+/* Called by gdb to invoke the command. */
+static void
+cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
+{
+ cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+ PyObject *argobj, *ttyobj, *result;
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ if (! obj)
+ error (_("Invalid invocation of Python command object."));
+ if (! PyObject_HasAttr ((PyObject *) obj, invoke_cst))
+ {
+ if (obj->command->prefixname)
+ {
+ /* A prefix command does not need an invoke method. */
+ do_cleanups (cleanup);
+ return;
+ }
+ error (_("Python command object missing 'invoke' method."));
+ }
+
+ if (! args)
+ args = "";
+ argobj = PyUnicode_Decode (args, strlen (args), host_charset (), NULL);
+ if (! argobj)
+ error (_("Could not convert arguments to Python string."));
+
+ ttyobj = from_tty ? Py_True : Py_False;
+ Py_INCREF (ttyobj);
+ result = PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst, argobj,
+ ttyobj, NULL);
+ Py_DECREF (argobj);
+ Py_DECREF (ttyobj);
+ if (! result)
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ char *s, *str;
+
+ PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+ if (pvalue && PyString_Check (pvalue))
+ {
+ /* Make a temporary copy of the string data. */
+ char *s = PyString_AsString (pvalue);
+ char *copy = alloca (strlen (s) + 1);
+ strcpy (copy, s);
+
+ PyErr_Restore (ptype, pvalue, ptraceback);
+ gdbpy_print_stack ();
+ error (_("Error occurred in Python command: %s"), copy);
+ }
+ else
+ {
+ PyErr_Restore (ptype, pvalue, ptraceback);
+ gdbpy_print_stack ();
+ error (_("Error occurred in Python command."));
+ }
+ }
+ Py_DECREF (result);
+ do_cleanups (cleanup);
+}
+
+/* Called by gdb for command completion. */
+static char **
+cmdpy_completer (struct cmd_list_element *command, char *text, char *word)
+{
+ cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
+ PyObject *textobj, *wordobj, *resultobj = NULL;
+ char **result = NULL;
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (get_current_arch (), current_language);
+
+ if (! obj)
+ error (_("Invalid invocation of Python command object."));
+ if (! PyObject_HasAttr ((PyObject *) obj, complete_cst))
+ {
+ /* If there is no complete method, don't error -- instead, just
+ say that there are no completions. */
+ goto done;
+ }
+
+ textobj = PyUnicode_Decode (text, strlen (text), host_charset (), NULL);
+ if (! textobj)
+ error (_("Could not convert argument to Python string."));
+ wordobj = PyUnicode_Decode (word, strlen (word), host_charset (), NULL);
+ if (! wordobj)
+ error (_("Could not convert argument to Python string."));
+
+ resultobj = PyObject_CallMethodObjArgs ((PyObject *) obj, complete_cst,
+ textobj, wordobj, NULL);
+ Py_DECREF (textobj);
+ Py_DECREF (wordobj);
+ if (! resultobj)
+ {
+ /* Just swallow errors here. */
+ PyErr_Clear ();
+ goto done;
+ }
+ make_cleanup_py_decref (resultobj);
+
+ result = NULL;
+ if (PySequence_Check (resultobj))
+ {
+ Py_ssize_t i, len = PySequence_Size (resultobj);
+ Py_ssize_t out;
+ if (len < 0)
+ goto done;
+
+ result = (char **) xmalloc ((len + 1) * sizeof (char *));
+ for (i = out = 0; i < len; ++i)
+ {
+ int l;
+ PyObject *elt = PySequence_GetItem (resultobj, i);
+ if (elt == NULL || ! gdbpy_is_string (elt))
+ {
+ /* Skip problem elements. */
+ PyErr_Clear ();
+ continue;
+ }
+ result[out] = python_string_to_host_string (elt);
+ ++out;
+ }
+ result[out] = NULL;
+ }
+ else if (PyInt_Check (resultobj))
+ {
+ /* User code may also return one of the completion constants,
+ thus requesting that sort of completion. */
+ long value = PyInt_AsLong (resultobj);
+ if (value >= 0 && value < (long) N_COMPLETERS)
+ result = completers[value].completer (command, text, word);
+ }
+
+ done:
+
+ do_cleanups (cleanup);
+
+ return result;
+}
+
+/* Helper for cmdpy_init which locates the command list to use and
+ pulls out the command name.
+
+ TEXT is the command name list. The final word in the list is the
+ name of the new command. All earlier words must be existing prefix
+ commands.
+
+ *BASE_LIST is set to the final prefix command's list of
+ *sub-commands.
+
+ This function returns the xmalloc()d name of the new command. On
+ error sets the Python error and returns NULL. */
+static char *
+parse_command_name (char *text, struct cmd_list_element ***base_list)
+{
+ struct cmd_list_element *elt;
+ int len = strlen (text);
+ int i, lastchar;
+ char *prefix_text;
+ char *result;
+
+ /* Skip trailing whitespace. */
+ for (i = len - 1; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+ ;
+ if (i < 0)
+ {
+ PyErr_SetString (PyExc_RuntimeError, _("no command name found"));
+ return NULL;
+ }
+ lastchar = i;
+
+ /* Find first character of the final word. */
+ for (; i > 0 && (isalnum (text[i - 1])
+ || text[i - 1] == '-'
+ || text[i - 1] == '_');
+ --i)
+ ;
+ result = xmalloc (lastchar - i + 2);
+ memcpy (result, &text[i], lastchar - i + 1);
+ result[lastchar - i + 1] = '\0';
+
+ /* Skip whitespace again. */
+ for (--i; i >= 0 && (text[i] == ' ' || text[i] == '\t'); --i)
+ ;
+ if (i < 0)
+ {
+ *base_list = &cmdlist;
+ return result;
+ }
+
+ prefix_text = xmalloc (i + 2);
+ memcpy (prefix_text, text, i + 1);
+ prefix_text[i + 1] = '\0';
+
+ text = prefix_text;
+ elt = lookup_cmd_1 (&text, cmdlist, NULL, 1);
+ if (!elt || elt == (struct cmd_list_element *) -1)
+ {
+ PyErr_Format (PyExc_RuntimeError, _("could not find command prefix %s"),
+ prefix_text);
+ xfree (prefix_text);
+ xfree (result);
+ return NULL;
+ }
+
+ if (elt->prefixlist)
+ {
+ xfree (prefix_text);
+ *base_list = elt->prefixlist;
+ return result;
+ }
+
+ PyErr_Format (PyExc_RuntimeError, _("'%s' is not a prefix command"),
+ prefix_text);
+ xfree (prefix_text);
+ xfree (result);
+ return NULL;
+}
+
+/* Object initializer; sets up gdb-side structures for command.
+
+ Use: __init__(NAME, COMMAND_CLASS [, COMPLETER_CLASS][, PREFIX]]).
+
+ NAME is the name of the command. It may consist of multiple words,
+ in which case the final word is the name of the new command, and
+ earlier words must be prefix commands.
+
+ COMMAND_CLASS is the kind of command. It should be one of the COMMAND_*
+ constants defined in the gdb module.
+
+ COMPLETER_CLASS is the kind of completer. If not given, the
+ "complete" method will be used. Otherwise, it should be one of the
+ COMPLETE_* constants defined in the gdb module.
+
+ If PREFIX is True, then this command is a prefix command.
+
+ The documentation for the command is taken from the doc string for
+ the python class.
+
+*/
+static int
+cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
+{
+ cmdpy_object *obj = (cmdpy_object *) self;
+ char *name;
+ int cmdtype;
+ int completetype = -1;
+ char *docstring = NULL;
+ volatile struct gdb_exception except;
+ struct cmd_list_element **cmd_list;
+ char *cmd_name, *pfx_name;
+ static char *keywords[] = { "name", "command_class", "completer_class",
+ "prefix", NULL };
+ PyObject *is_prefix = NULL;
+ int cmp;
+
+ if (obj->command)
+ {
+ /* Note: this is apparently not documented in Python. We return
+ 0 for success, -1 for failure. */
+ PyErr_Format (PyExc_RuntimeError,
+ _("command object already initialized"));
+ return -1;
+ }
+
+ if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype,
+ &completetype, &is_prefix))
+ return -1;
+
+ if (cmdtype != no_class && cmdtype != class_run
+ && cmdtype != class_vars && cmdtype != class_stack
+ && cmdtype != class_files && cmdtype != class_support
+ && cmdtype != class_info && cmdtype != class_breakpoint
+ && cmdtype != class_trace && cmdtype != class_obscure
+ && cmdtype != class_maintenance)
+ {
+ PyErr_Format (PyExc_RuntimeError, _("invalid command class argument"));
+ return -1;
+ }
+
+ if (completetype < -1 || completetype >= (int) N_COMPLETERS)
+ {
+ PyErr_Format (PyExc_RuntimeError, _("invalid completion type argument"));
+ return -1;
+ }
+
+ cmd_name = parse_command_name (name, &cmd_list);
+ if (! cmd_name)
+ return -1;
+
+ pfx_name = NULL;
+ if (is_prefix != NULL)
+ {
+ cmp = PyObject_IsTrue (is_prefix);
+ if (cmp == 1)
+ {
+ int i, out;
+
+ /* Make a normalized form of the command name. */
+ pfx_name = xmalloc (strlen (name) + 2);
+
+ i = 0;
+ out = 0;
+ while (name[i])
+ {
+ /* Skip whitespace. */
+ while (name[i] == ' ' || name[i] == '\t')
+ ++i;
+ /* Copy non-whitespace characters. */
+ while (name[i] && name[i] != ' ' && name[i] != '\t')
+ pfx_name[out++] = name[i++];
+ /* Add a single space after each word -- including the final
+ word. */
+ pfx_name[out++] = ' ';
+ }
+ pfx_name[out] = '\0';
+ }
+ else if (cmp < 0)
+ return -1;
+ }
+ if (PyObject_HasAttr (self, gdbpy_doc_cst))
+ {
+ PyObject *ds_obj = PyObject_GetAttr (self, gdbpy_doc_cst);
+ if (ds_obj && gdbpy_is_string (ds_obj))
+ docstring = python_string_to_host_string (ds_obj);
+ }
+ if (! docstring)
+ docstring = xstrdup (_("This command is not documented."));
+
+ Py_INCREF (self);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct cmd_list_element *cmd;
+
+ if (pfx_name)
+ {
+ int allow_unknown;
+
+ /* If we have our own "invoke" method, then allow unknown
+ sub-commands. */
+ allow_unknown = PyObject_HasAttr (self, invoke_cst);
+ cmd = add_prefix_cmd (cmd_name, (enum command_class) cmdtype,
+ NULL, docstring, &obj->sub_list,
+ pfx_name, allow_unknown, cmd_list);
+ }
+ else
+ cmd = add_cmd (cmd_name, (enum command_class) cmdtype, NULL,
+ docstring, cmd_list);
+
+ /* There appears to be no API to set this. */
+ cmd->func = cmdpy_function;
+ cmd->destroyer = cmdpy_destroyer;
+
+ obj->command = cmd;
+ set_cmd_context (cmd, self);
+ set_cmd_completer (cmd, ((completetype == -1) ? cmdpy_completer
+ : completers[completetype].completer));
+ }
+ if (except.reason < 0)
+ {
+ xfree (cmd_name);
+ xfree (docstring);
+ xfree (pfx_name);
+ Py_DECREF (self);
+ PyErr_Format (except.reason == RETURN_QUIT
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
+ "%s", except.message);
+ return -1;
+ }
+ return 0;
+}
+
+
+
+/* Initialize the 'commands' code. */
+void
+gdbpy_initialize_commands (void)
+{
+ int i;
+
+ if (PyType_Ready (&cmdpy_object_type) < 0)
+ return;
+
+ /* Note: alias and user are special; pseudo appears to be unused,
+ and there is no reason to expose tui or xdb, I think. */
+ if (PyModule_AddIntConstant (gdb_module, "COMMAND_NONE", no_class) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_RUNNING", class_run) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_DATA", class_vars) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_STACK", class_stack) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_FILES", class_files) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_SUPPORT",
+ class_support) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_STATUS", class_info) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_BREAKPOINTS",
+ class_breakpoint) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_TRACEPOINTS",
+ class_trace) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_OBSCURE",
+ class_obscure) < 0
+ || PyModule_AddIntConstant (gdb_module, "COMMAND_MAINTENANCE",
+ class_maintenance) < 0)
+ return;
+
+ for (i = 0; i < N_COMPLETERS; ++i)
+ {
+ if (PyModule_AddIntConstant (gdb_module, completers[i].name, i) < 0)
+ return;
+ }
+
+ Py_INCREF (&cmdpy_object_type);
+ PyModule_AddObject (gdb_module, "Command",
+ (PyObject *) &cmdpy_object_type);
+
+ invoke_cst = PyString_FromString ("invoke");
+ complete_cst = PyString_FromString ("complete");
+}
+
+
+
+static PyMethodDef cmdpy_object_methods[] =
+{
+ { "dont_repeat", cmdpy_dont_repeat, METH_NOARGS,
+ "Prevent command repetition when user enters empty line." },
+
+ { 0 }
+};
+
+static PyTypeObject cmdpy_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Command", /*tp_name*/
+ sizeof (cmdpy_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "GDB command object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ cmdpy_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 */
+ cmdpy_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew /* tp_new */
+};
py-cmd.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-lazy-string.c
===================================================================
--- py-lazy-string.c (nonexistent)
+++ py-lazy-string.c (revision 842)
@@ -0,0 +1,291 @@
+/* Python interface to lazy strings.
+
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "value.h"
+#include "exceptions.h"
+#include "valprint.h"
+#include "language.h"
+
+typedef struct {
+ PyObject_HEAD
+ /* Holds the address of the lazy string. */
+ CORE_ADDR address;
+
+ /* Holds the encoding that will be applied to the string
+ when the string is printed by GDB. If the encoding is set
+ to None then GDB will select the most appropriate
+ encoding when the sting is printed. */
+ char *encoding;
+
+ /* Holds the length of the string in characters. If the
+ length is -1, then the string will be fetched and encoded up to
+ the first null of appropriate width. */
+ long length;
+
+ /* This attribute holds the type that is represented by the lazy
+ string's type. */
+ struct type *type;
+} lazy_string_object;
+
+static PyTypeObject lazy_string_object_type;
+
+static PyObject *
+stpy_get_address (PyObject *self, void *closure)
+{
+ lazy_string_object *self_string = (lazy_string_object *) self;
+ return PyLong_FromUnsignedLongLong (self_string->address);
+}
+
+static PyObject *
+stpy_get_encoding (PyObject *self, void *closure)
+{
+ lazy_string_object *self_string = (lazy_string_object *) self;
+ PyObject *result;
+
+ /* An encoding can be set to NULL by the user, so check before
+ attempting a Python FromString call. If NULL return Py_None. */
+ if (self_string->encoding)
+ result = PyString_FromString (self_string->encoding);
+ else
+ {
+ result = Py_None;
+ Py_INCREF (result);
+ }
+
+ return result;
+}
+
+static PyObject *
+stpy_get_length (PyObject *self, void *closure)
+{
+ lazy_string_object *self_string = (lazy_string_object *) self;
+ return PyLong_FromLong (self_string->length);
+}
+
+PyObject *
+stpy_get_type (PyObject *self, void *closure)
+{
+ lazy_string_object *str_obj = (lazy_string_object *) self;
+ return type_to_type_object (str_obj->type);
+}
+
+static PyObject *
+stpy_convert_to_value (PyObject *self, PyObject *args)
+{
+ lazy_string_object *self_string = (lazy_string_object *) self;
+ struct value *val;
+
+ val = value_at_lazy (self_string->type, self_string->address);
+ return value_to_value_object (val);
+}
+
+static void
+stpy_dealloc (PyObject *self)
+{
+ lazy_string_object *self_string = (lazy_string_object *) self;
+ xfree (self_string->encoding);
+}
+
+PyObject *
+gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
+ const char *encoding, struct type *type)
+{
+ lazy_string_object *str_obj = NULL;
+
+ if (address == 0)
+ {
+ PyErr_SetString (PyExc_MemoryError,
+ "Cannot create a lazy string from a GDB-side string.");
+ return NULL;
+ }
+
+ if (!type)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ "A lazy string's type cannot be NULL.");
+ return NULL;
+ }
+
+ str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
+ if (!str_obj)
+ return NULL;
+
+ str_obj->address = address;
+ str_obj->length = length;
+ if (encoding == NULL || !strcmp (encoding, ""))
+ str_obj->encoding = NULL;
+ else
+ str_obj->encoding = xstrdup (encoding);
+ str_obj->type = type;
+
+ return (PyObject *) str_obj;
+}
+
+void
+gdbpy_initialize_lazy_string (void)
+{
+ if (PyType_Ready (&lazy_string_object_type) < 0)
+ return;
+
+ Py_INCREF (&lazy_string_object_type);
+}
+
+/* Determine whether the printer object pointed to by OBJ is a
+ Python lazy string. */
+int
+gdbpy_is_lazy_string (PyObject *result)
+{
+ return PyObject_TypeCheck (result, &lazy_string_object_type);
+}
+
+/* Extract and return the actual string from the lazy string object
+ STRING. Addtionally, the string type is written to *STR_TYPE, the
+ string length is written to *LENGTH, and the string encoding is
+ written to *ENCODING. On error, NULL is returned. The caller is
+ responsible for freeing the returned buffer. */
+gdb_byte *
+gdbpy_extract_lazy_string (PyObject *string, struct type **str_type,
+ long *length, char **encoding)
+{
+ int width;
+ int bytes_read;
+ gdb_byte *buffer = NULL;
+ int errcode = 0;
+ CORE_ADDR addr;
+ struct gdbarch *gdbarch;
+ enum bfd_endian byte_order;
+ PyObject *py_len = NULL, *py_encoding = NULL;
+ PyObject *py_addr = NULL, *py_type = NULL;
+ volatile struct gdb_exception except;
+
+ py_len = PyObject_GetAttrString (string, "length");
+ py_encoding = PyObject_GetAttrString (string, "encoding");
+ py_addr = PyObject_GetAttrString (string, "address");
+ py_type = PyObject_GetAttrString (string, "type");
+
+ /* A NULL encoding, length, address or type is not ok. */
+ if (!py_len || !py_encoding || !py_addr || !py_type)
+ goto error;
+
+ *length = PyLong_AsLong (py_len);
+ addr = PyLong_AsUnsignedLongLong (py_addr);
+
+ /* If the user supplies Py_None an encoding, set encoding to NULL.
+ This will trigger the resulting LA_PRINT_CALL to automatically
+ select an encoding. */
+ if (py_encoding == Py_None)
+ *encoding = NULL;
+ else
+ *encoding = xstrdup (PyString_AsString (py_encoding));
+
+ *str_type = type_object_to_type (py_type);
+ gdbarch = get_type_arch (*str_type);
+ byte_order = gdbarch_byte_order (gdbarch);
+ width = TYPE_LENGTH (*str_type);
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ errcode = read_string (addr, *length, width,
+ *length, byte_order, &buffer,
+ &bytes_read);
+ }
+ if (except.reason < 0)
+ {
+ PyErr_Format (except.reason == RETURN_QUIT \
+ ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
+ "%s", except.message); \
+ goto error;
+
+ }
+
+ if (errcode)
+ goto error;
+
+ *length = bytes_read / width;
+
+ Py_DECREF (py_encoding);
+ Py_DECREF (py_len);
+ Py_DECREF (py_addr);
+ Py_DECREF (py_type);
+ return buffer;
+
+ error:
+ Py_XDECREF (py_encoding);
+ Py_XDECREF (py_len);
+ Py_XDECREF (py_addr);
+ Py_XDECREF (py_type);
+ xfree (buffer);
+ *length = 0;
+ *str_type = NULL;
+ return NULL;
+}
+
+
+
+static PyMethodDef lazy_string_object_methods[] = {
+ { "value", stpy_convert_to_value, METH_NOARGS,
+ "Create a (lazy) value that contains a pointer to the string." },
+ {NULL} /* Sentinel */
+};
+
+
+static PyGetSetDef lazy_string_object_getset[] = {
+ { "address", stpy_get_address, NULL, "Address of the string.", NULL },
+ { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
+ { "length", stpy_get_length, NULL, "Length of the string.", NULL },
+ { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
+ { NULL } /* Sentinel */
+};
+
+static PyTypeObject lazy_string_object_type = {
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.LazyString", /*tp_name*/
+ sizeof (lazy_string_object), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ stpy_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ "GDB lazy string object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ lazy_string_object_methods, /* tp_methods */
+ 0, /* tp_members */
+ lazy_string_object_getset /* tp_getset */
+};
py-lazy-string.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-prettyprint.c
===================================================================
--- py-prettyprint.c (nonexistent)
+++ py-prettyprint.c (revision 842)
@@ -0,0 +1,661 @@
+/* Python pretty-printing
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include "defs.h"
+#include "exceptions.h"
+#include "objfiles.h"
+#include "symtab.h"
+#include "language.h"
+#include "valprint.h"
+
+#include "python.h"
+
+#ifdef HAVE_PYTHON
+#include "python-internal.h"
+
+
+/* Helper function for find_pretty_printer which iterates over a list,
+ calls each function and inspects output. This will return a
+ printer object if one recognizes VALUE. If no printer is found, it
+ will return None. On error, it will set the Python error and
+ return NULL. */
+static PyObject *
+search_pp_list (PyObject *list, PyObject *value)
+{
+ Py_ssize_t pp_list_size, list_index;
+ PyObject *function, *printer = NULL;
+
+ pp_list_size = PyList_Size (list);
+ for (list_index = 0; list_index < pp_list_size; list_index++)
+ {
+ function = PyList_GetItem (list, list_index);
+ if (! function)
+ return NULL;
+
+ printer = PyObject_CallFunctionObjArgs (function, value, NULL);
+ if (! printer)
+ return NULL;
+ else if (printer != Py_None)
+ return printer;
+
+ Py_DECREF (printer);
+ }
+
+ Py_RETURN_NONE;
+}
+
+/* Find the pretty-printing constructor function for VALUE. If no
+ pretty-printer exists, return None. If one exists, return a new
+ reference. On error, set the Python error and return NULL. */
+static PyObject *
+find_pretty_printer (PyObject *value)
+{
+ PyObject *pp_list = NULL;
+ PyObject *function = NULL;
+ struct objfile *obj;
+ volatile struct gdb_exception except;
+
+ /* Look at the pretty-printer dictionary for each objfile. */
+ ALL_OBJFILES (obj)
+ {
+ PyObject *objf = objfile_to_objfile_object (obj);
+ if (!objf)
+ {
+ /* Ignore the error and continue. */
+ PyErr_Clear ();
+ continue;
+ }
+
+ pp_list = objfpy_get_printers (objf, NULL);
+ function = search_pp_list (pp_list, value);
+
+ /* If there is an error in any objfile list, abort the search and
+ exit. */
+ if (! function)
+ {
+ Py_XDECREF (pp_list);
+ return NULL;
+ }
+
+ if (function != Py_None)
+ goto done;
+
+ Py_DECREF (function);
+ Py_XDECREF (pp_list);
+ }
+
+ pp_list = NULL;
+ /* Fetch the global pretty printer dictionary. */
+ if (! PyObject_HasAttrString (gdb_module, "pretty_printers"))
+ {
+ function = Py_None;
+ Py_INCREF (function);
+ goto done;
+ }
+ pp_list = PyObject_GetAttrString (gdb_module, "pretty_printers");
+ if (! pp_list)
+ goto done;
+ if (! PyList_Check (pp_list))
+ goto done;
+
+ function = search_pp_list (pp_list, value);
+
+ done:
+ Py_XDECREF (pp_list);
+
+ return function;
+}
+
+
+/* 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)
+{
+ volatile struct gdb_exception except;
+ PyObject *result = NULL;
+
+ *out_value = NULL;
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ result = PyObject_CallMethodObjArgs (printer, gdbpy_to_string_cst, NULL);
+ if (result)
+ {
+ if (! gdbpy_is_string (result) && ! gdbpy_is_lazy_string (result))
+ {
+ *out_value = convert_value_from_python (result);
+ if (PyErr_Occurred ())
+ *out_value = NULL;
+ Py_DECREF (result);
+ result = NULL;
+ }
+ }
+ }
+
+ return result;
+}
+
+/* Return the display hint for the object printer, PRINTER. Return
+ NULL if there is no display_hint method, or if the method did not
+ return a string. On error, print stack trace and return NULL. On
+ success, return an xmalloc()d string. */
+char *
+gdbpy_get_display_hint (PyObject *printer)
+{
+ PyObject *hint;
+ char *result = NULL;
+
+ if (! PyObject_HasAttr (printer, gdbpy_display_hint_cst))
+ return NULL;
+
+ hint = PyObject_CallMethodObjArgs (printer, gdbpy_display_hint_cst, NULL);
+ if (gdbpy_is_string (hint))
+ result = python_string_to_host_string (hint);
+ if (hint)
+ Py_DECREF (hint);
+ else
+ gdbpy_print_stack ();
+
+ return result;
+}
+
+/* Helper for apply_val_pretty_printer which calls to_string and
+ formats the result. */
+static void
+print_string_repr (PyObject *printer, const char *hint,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ const struct language_defn *language,
+ struct gdbarch *gdbarch)
+{
+ struct value *replacement = NULL;
+ PyObject *py_str = NULL;
+
+ py_str = pretty_print_one_value (printer, &replacement);
+ if (py_str)
+ {
+ gdb_byte *output = NULL;
+ long length;
+ struct type *type;
+ char *encoding = NULL;
+ PyObject *string = NULL;
+ int is_lazy;
+
+ is_lazy = gdbpy_is_lazy_string (py_str);
+ if (is_lazy)
+ output = gdbpy_extract_lazy_string (py_str, &type, &length, &encoding);
+ else
+ {
+ string = python_string_to_target_python_string (py_str);
+ if (string)
+ {
+ output = PyString_AsString (string);
+ length = PyString_Size (string);
+ type = builtin_type (gdbarch)->builtin_char;
+ }
+ else
+ gdbpy_print_stack ();
+
+ }
+
+ if (output)
+ {
+ if (is_lazy || (hint && !strcmp (hint, "string")))
+ LA_PRINT_STRING (stream, type, output, length, encoding,
+ 0, options);
+ else
+ fputs_filtered (output, stream);
+ }
+ else
+ gdbpy_print_stack ();
+
+ if (string)
+ Py_DECREF (string);
+ else
+ xfree (output);
+
+ xfree (encoding);
+ Py_DECREF (py_str);
+ }
+ else if (replacement)
+ {
+ struct value_print_options opts = *options;
+
+ opts.addressprint = 0;
+ common_val_print (replacement, stream, recurse, &opts, language);
+ }
+ else
+ gdbpy_print_stack ();
+}
+
+static void
+py_restore_tstate (void *p)
+{
+ PyFrameObject *frame = p;
+ PyThreadState *tstate = PyThreadState_GET ();
+ tstate->frame = frame;
+}
+
+/* Create a dummy PyFrameObject, needed to work around
+ a Python-2.4 bug with generators. */
+static PyObject *
+push_dummy_python_frame ()
+{
+ PyObject *empty_string, *null_tuple, *globals;
+ PyCodeObject *code;
+ PyFrameObject *frame;
+ PyThreadState *tstate;
+
+ empty_string = PyString_FromString ("");
+ if (!empty_string)
+ return NULL;
+
+ null_tuple = PyTuple_New (0);
+ if (!null_tuple)
+ {
+ Py_DECREF (empty_string);
+ return NULL;
+ }
+
+ code = PyCode_New (0, /* argcount */
+ 0, /* nlocals */
+ 0, /* stacksize */
+ 0, /* flags */
+ empty_string, /* code */
+ null_tuple, /* consts */
+ null_tuple, /* names */
+ null_tuple, /* varnames */
+#if PYTHON_API_VERSION >= 1010
+ null_tuple, /* freevars */
+ null_tuple, /* cellvars */
+#endif
+ empty_string, /* filename */
+ empty_string, /* name */
+ 1, /* firstlineno */
+ empty_string /* lnotab */
+ );
+
+ Py_DECREF (empty_string);
+ Py_DECREF (null_tuple);
+
+ if (!code)
+ return NULL;
+
+ globals = PyDict_New ();
+ if (!globals)
+ {
+ Py_DECREF (code);
+ return NULL;
+ }
+
+ tstate = PyThreadState_GET ();
+
+ frame = PyFrame_New (tstate, code, globals, NULL);
+
+ Py_DECREF (globals);
+ Py_DECREF (code);
+
+ if (!frame)
+ return NULL;
+
+ tstate->frame = frame;
+ make_cleanup (py_restore_tstate, frame->f_back);
+ return (PyObject *) frame;
+}
+
+/* Helper for apply_val_pretty_printer that formats children of the
+ printer, if any exist. */
+static void
+print_children (PyObject *printer, const char *hint,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ const struct language_defn *language)
+{
+ int is_map, is_array, done_flag, pretty;
+ unsigned int i;
+ PyObject *children, *iter, *frame;
+ struct cleanup *cleanups;
+
+ if (! PyObject_HasAttr (printer, gdbpy_children_cst))
+ return;
+
+ /* If we are printing a map or an array, we want some special
+ formatting. */
+ is_map = hint && ! strcmp (hint, "map");
+ is_array = hint && ! strcmp (hint, "array");
+
+ children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+ NULL);
+ if (! children)
+ {
+ gdbpy_print_stack ();
+ return;
+ }
+
+ cleanups = make_cleanup_py_decref (children);
+
+ iter = PyObject_GetIter (children);
+ if (!iter)
+ {
+ gdbpy_print_stack ();
+ goto done;
+ }
+ make_cleanup_py_decref (iter);
+
+ /* Use the prettyprint_arrays option if we are printing an array,
+ and the pretty option otherwise. */
+ pretty = is_array ? options->prettyprint_arrays : options->pretty;
+
+ /* Manufacture a dummy Python frame to work around Python 2.4 bug,
+ where it insists on having a non-NULL tstate->frame when
+ a generator is called. */
+ frame = push_dummy_python_frame ();
+ if (!frame)
+ {
+ gdbpy_print_stack ();
+ goto done;
+ }
+ make_cleanup_py_decref (frame);
+
+ done_flag = 0;
+ for (i = 0; i < options->print_max; ++i)
+ {
+ PyObject *py_v, *item = PyIter_Next (iter);
+ char *name;
+ struct cleanup *inner_cleanup;
+
+ if (! item)
+ {
+ if (PyErr_Occurred ())
+ gdbpy_print_stack ();
+ /* Set a flag so we can know whether we printed all the
+ available elements. */
+ else
+ done_flag = 1;
+ break;
+ }
+
+ if (! PyArg_ParseTuple (item, "sO", &name, &py_v))
+ {
+ gdbpy_print_stack ();
+ Py_DECREF (item);
+ continue;
+ }
+ inner_cleanup = make_cleanup_py_decref (item);
+
+ /* Print initial "{". For other elements, there are three
+ cases:
+ 1. Maps. Print a "," after each value element.
+ 2. Arrays. Always print a ",".
+ 3. Other. Always print a ",". */
+ if (i == 0)
+ fputs_filtered (" = {", stream);
+ else if (! is_map || i % 2 == 0)
+ fputs_filtered (pretty ? "," : ", ", stream);
+
+ /* In summary mode, we just want to print "= {...}" if there is
+ a value. */
+ if (options->summary)
+ {
+ /* This increment tricks the post-loop logic to print what
+ we want. */
+ ++i;
+ /* Likewise. */
+ pretty = 0;
+ break;
+ }
+
+ if (! is_map || i % 2 == 0)
+ {
+ if (pretty)
+ {
+ fputs_filtered ("\n", stream);
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ else
+ wrap_here (n_spaces (2 + 2 *recurse));
+ }
+
+ if (is_map && i % 2 == 0)
+ fputs_filtered ("[", stream);
+ else if (is_array)
+ {
+ /* We print the index, not whatever the child method
+ returned as the name. */
+ if (options->print_array_indexes)
+ fprintf_filtered (stream, "[%d] = ", i);
+ }
+ else if (! is_map)
+ {
+ fputs_filtered (name, stream);
+ fputs_filtered (" = ", stream);
+ }
+
+ if (gdbpy_is_lazy_string (py_v) || gdbpy_is_string (py_v))
+ {
+ gdb_byte *output = NULL;
+
+ if (gdbpy_is_lazy_string (py_v))
+ {
+ struct type *type;
+ long length;
+ char *encoding = NULL;
+
+ output = gdbpy_extract_lazy_string (py_v, &type,
+ &length, &encoding);
+ if (!output)
+ gdbpy_print_stack ();
+ LA_PRINT_STRING (stream, type, output, length, encoding,
+ 0, options);
+ xfree (encoding);
+ xfree (output);
+ }
+ else
+ {
+ output = python_string_to_host_string (py_v);
+ fputs_filtered (output, stream);
+ xfree (output);
+ }
+ }
+ else
+ {
+ struct value *value = convert_value_from_python (py_v);
+
+ if (value == NULL)
+ {
+ gdbpy_print_stack ();
+ error (_("Error while executing Python code."));
+ }
+ else
+ common_val_print (value, stream, recurse + 1, options, language);
+ }
+
+ if (is_map && i % 2 == 0)
+ fputs_filtered ("] = ", stream);
+
+ do_cleanups (inner_cleanup);
+ }
+
+ if (i)
+ {
+ if (!done_flag)
+ {
+ if (pretty)
+ {
+ fputs_filtered ("\n", stream);
+ print_spaces_filtered (2 + 2 * recurse, stream);
+ }
+ fputs_filtered ("...", stream);
+ }
+ if (pretty)
+ {
+ fputs_filtered ("\n", stream);
+ print_spaces_filtered (2 * recurse, stream);
+ }
+ fputs_filtered ("}", stream);
+ }
+
+ done:
+ do_cleanups (cleanups);
+}
+
+int
+apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ const struct language_defn *language)
+{
+ struct gdbarch *gdbarch = get_type_arch (type);
+ PyObject *printer = NULL;
+ PyObject *val_obj = NULL;
+ struct value *value;
+ char *hint = NULL;
+ struct cleanup *cleanups;
+ int result = 0;
+
+ cleanups = ensure_python_env (gdbarch, language);
+
+ /* Instantiate the printer. */
+ if (valaddr)
+ valaddr += embedded_offset;
+ value = value_from_contents_and_address (type, valaddr,
+ address + embedded_offset);
+
+ val_obj = value_to_value_object (value);
+ if (! val_obj)
+ goto done;
+
+ /* Find the constructor. */
+ printer = find_pretty_printer (val_obj);
+ Py_DECREF (val_obj);
+ make_cleanup_py_decref (printer);
+ if (! printer || printer == Py_None)
+ goto done;
+
+ /* If we are printing a map, we want some special formatting. */
+ hint = gdbpy_get_display_hint (printer);
+ make_cleanup (free_current_contents, &hint);
+
+ /* Print the section */
+ print_string_repr (printer, hint, stream, recurse, options, language,
+ gdbarch);
+ print_children (printer, hint, stream, recurse, options, language);
+ result = 1;
+
+
+ done:
+ if (PyErr_Occurred ())
+ gdbpy_print_stack ();
+ do_cleanups (cleanups);
+ 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. 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)
+{
+ int size = 0;
+ PyObject *py_str = NULL;
+
+ *replacement = NULL;
+ py_str = pretty_print_one_value (printer_obj, replacement);
+
+ if (*replacement == NULL && py_str == NULL)
+ gdbpy_print_stack ();
+
+ return py_str;
+}
+
+/* Find a pretty-printer object for the varobj module. Returns a new
+ reference to the object if successful; returns NULL if not. VALUE
+ is the value for which a printer tests to determine if it
+ can pretty-print the value. */
+PyObject *
+gdbpy_get_varobj_pretty_printer (struct value *value)
+{
+ PyObject *val_obj;
+ PyObject *pretty_printer = NULL;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ value = value_copy (value);
+ }
+ GDB_PY_HANDLE_EXCEPTION (except);
+
+ val_obj = value_to_value_object (value);
+ if (! val_obj)
+ return NULL;
+
+ pretty_printer = find_pretty_printer (val_obj);
+ Py_DECREF (val_obj);
+ return pretty_printer;
+}
+
+/* A Python function which wraps find_pretty_printer and instantiates
+ the resulting class. This accepts a Value argument and returns a
+ pretty printer instance, or None. This function is useful as an
+ argument to the MI command -var-set-visualizer. */
+PyObject *
+gdbpy_default_visualizer (PyObject *self, PyObject *args)
+{
+ PyObject *val_obj;
+ PyObject *cons, *printer = NULL;
+ struct value *value;
+
+ if (! PyArg_ParseTuple (args, "O", &val_obj))
+ return NULL;
+ value = value_object_to_value (val_obj);
+ if (! value)
+ {
+ PyErr_SetString (PyExc_TypeError, "argument must be a gdb.Value");
+ return NULL;
+ }
+
+ cons = find_pretty_printer (val_obj);
+ return cons;
+}
+
+#else /* HAVE_PYTHON */
+
+int
+apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
+ int embedded_offset, CORE_ADDR address,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ const struct language_defn *language)
+{
+ return 0;
+}
+
+#endif /* HAVE_PYTHON */
py-prettyprint.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: py-function.c
===================================================================
--- py-function.c (nonexistent)
+++ py-function.c (revision 842)
@@ -0,0 +1,179 @@
+/* Convenience functions implemented in Python.
+
+ Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+
+#include "defs.h"
+#include "value.h"
+#include "exceptions.h"
+#include "python-internal.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "cli/cli-decode.h"
+#include "completer.h"
+#include "expression.h"
+#include "language.h"
+
+static PyTypeObject fnpy_object_type;
+
+
+
+static PyObject *
+convert_values_to_python (int argc, struct value **argv)
+{
+ int i;
+ PyObject *result = PyTuple_New (argc);
+ for (i = 0; i < argc; ++i)
+ {
+ PyObject *elt = value_to_value_object (argv[i]);
+ if (! elt)
+ {
+ Py_DECREF (result);
+ error (_("Could not convert value to Python object."));
+ }
+ PyTuple_SetItem (result, i, elt);
+ }
+ return result;
+}
+
+/* Call a Python function object's invoke method. */
+
+static struct value *
+fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
+ void *cookie, int argc, struct value **argv)
+{
+ int i;
+ struct value *value = NULL;
+ PyObject *result, *callable, *args;
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (gdbarch, language);
+
+ args = convert_values_to_python (argc, argv);
+
+ callable = PyObject_GetAttrString ((PyObject *) cookie, "invoke");
+ if (! callable)
+ {
+ Py_DECREF (args);
+ error (_("No method named 'invoke' in object."));
+ }
+
+ result = PyObject_Call (callable, args, NULL);
+ Py_DECREF (callable);
+ Py_DECREF (args);
+
+ if (!result)
+ {
+ gdbpy_print_stack ();
+ error (_("Error while executing Python code."));
+ }
+
+ value = convert_value_from_python (result);
+ if (value == NULL)
+ {
+ Py_DECREF (result);
+ gdbpy_print_stack ();
+ error (_("Error while executing Python code."));
+ }
+
+ Py_DECREF (result);
+ do_cleanups (cleanup);
+
+ return value;
+}
+
+/* Initializer for a Function object. It takes one argument, the name
+ of the function. */
+
+static int
+fnpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+{
+ char *name, *docstring = NULL;
+ if (! PyArg_ParseTuple (args, "s", &name))
+ return -1;
+ Py_INCREF (self);
+
+ if (PyObject_HasAttrString (self, "__doc__"))
+ {
+ PyObject *ds_obj = PyObject_GetAttrString (self, "__doc__");
+ if (ds_obj && gdbpy_is_string (ds_obj))
+ docstring = python_string_to_host_string (ds_obj);
+ }
+ if (! docstring)
+ docstring = xstrdup (_("This function is not documented."));
+
+ add_internal_function (name, docstring, fnpy_call, self);
+ return 0;
+}
+
+/* Initialize internal function support. */
+
+void
+gdbpy_initialize_functions (void)
+{
+ if (PyType_Ready (&fnpy_object_type) < 0)
+ return;
+
+ Py_INCREF (&fnpy_object_type);
+ PyModule_AddObject (gdb_module, "Function", (PyObject *) &fnpy_object_type);
+}
+
+
+
+static PyTypeObject fnpy_object_type =
+{
+ PyObject_HEAD_INIT (NULL)
+ 0, /*ob_size*/
+ "gdb.Function", /*tp_name*/
+ sizeof (PyObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "GDB function object", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* 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 */
+ fnpy_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew /* tp_new */
+};
py-function.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property