GDB (API)
/home/stan/gdb/src/gdb/python/py-lazy-string.c
Go to the documentation of this file.
00001 /* Python interface to lazy strings.
00002 
00003    Copyright (C) 2010-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "python-internal.h"
00022 #include "charset.h"
00023 #include "value.h"
00024 #include "exceptions.h"
00025 #include "valprint.h"
00026 #include "language.h"
00027 #include "gdb_assert.h"
00028 
00029 typedef struct {
00030   PyObject_HEAD
00031   /*  Holds the address of the lazy string.  */
00032   CORE_ADDR address;
00033 
00034   /*  Holds the encoding that will be applied to the string
00035       when the string is printed by GDB.  If the encoding is set
00036       to None then GDB will select the most appropriate
00037       encoding when the sting is printed.  */
00038   char *encoding;
00039 
00040   /* Holds the length of the string in characters.  If the
00041      length is -1, then the string will be fetched and encoded up to
00042      the first null of appropriate width.  */
00043   long length;
00044 
00045   /*  This attribute holds the type that is represented by the lazy
00046       string's type.  */
00047   struct type *type;
00048 } lazy_string_object;
00049 
00050 static PyTypeObject lazy_string_object_type
00051     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
00052 
00053 static PyObject *
00054 stpy_get_address (PyObject *self, void *closure)
00055 {
00056   lazy_string_object *self_string = (lazy_string_object *) self;
00057 
00058   return gdb_py_long_from_ulongest (self_string->address);
00059 }
00060 
00061 static PyObject *
00062 stpy_get_encoding (PyObject *self, void *closure)
00063 {
00064   lazy_string_object *self_string = (lazy_string_object *) self;
00065   PyObject *result;
00066 
00067   /* An encoding can be set to NULL by the user, so check before
00068      attempting a Python FromString call.  If NULL return Py_None.  */
00069   if (self_string->encoding)
00070     result = PyString_FromString (self_string->encoding);
00071   else
00072     {
00073       result = Py_None;
00074       Py_INCREF (result);
00075     }
00076 
00077   return result;
00078 }
00079 
00080 static PyObject *
00081 stpy_get_length (PyObject *self, void *closure)
00082 {
00083   lazy_string_object *self_string = (lazy_string_object *) self;
00084 
00085   return PyLong_FromLong (self_string->length);
00086 }
00087 
00088 static PyObject *
00089 stpy_get_type (PyObject *self, void *closure)
00090 {
00091   lazy_string_object *str_obj = (lazy_string_object *) self;
00092 
00093   return type_to_type_object (str_obj->type);
00094 }
00095 
00096 static PyObject *
00097 stpy_convert_to_value  (PyObject *self, PyObject *args)
00098 {
00099   lazy_string_object *self_string = (lazy_string_object *) self;
00100   struct value *val = NULL;
00101   volatile struct gdb_exception except;
00102 
00103   if (self_string->address == 0)
00104     {
00105       PyErr_SetString (PyExc_MemoryError,
00106                        _("Cannot create a value from NULL."));
00107       return NULL;
00108     }
00109 
00110   TRY_CATCH (except, RETURN_MASK_ALL)
00111     {
00112       val = value_at_lazy (self_string->type, self_string->address);
00113     }
00114   GDB_PY_HANDLE_EXCEPTION (except);
00115 
00116   return value_to_value_object (val);
00117 }
00118 
00119 static void
00120 stpy_dealloc (PyObject *self)
00121 {
00122   lazy_string_object *self_string = (lazy_string_object *) self;
00123 
00124   xfree (self_string->encoding);
00125 }
00126 
00127 PyObject *
00128 gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
00129                            const char *encoding, struct type *type)
00130 {
00131   lazy_string_object *str_obj = NULL;
00132 
00133   if (address == 0 && length != 0)
00134     {
00135       PyErr_SetString (PyExc_MemoryError,
00136                        _("Cannot create a lazy string with address 0x0, " \
00137                          "and a non-zero length."));
00138       return NULL;
00139     }
00140 
00141   if (!type)
00142     {
00143       PyErr_SetString (PyExc_RuntimeError,
00144                        _("A lazy string's type cannot be NULL."));
00145       return NULL;
00146     }
00147 
00148   str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
00149   if (!str_obj)
00150     return NULL;
00151 
00152   str_obj->address = address;
00153   str_obj->length = length;
00154   if (encoding == NULL || !strcmp (encoding, ""))
00155     str_obj->encoding = NULL;
00156   else
00157     str_obj->encoding = xstrdup (encoding);
00158   str_obj->type = type;
00159 
00160   return (PyObject *) str_obj;
00161 }
00162 
00163 int
00164 gdbpy_initialize_lazy_string (void)
00165 {
00166   if (PyType_Ready (&lazy_string_object_type) < 0)
00167     return -1;
00168 
00169   Py_INCREF (&lazy_string_object_type);
00170   return 0;
00171 }
00172 
00173 /* Determine whether the printer object pointed to by OBJ is a
00174    Python lazy string.  */
00175 int
00176 gdbpy_is_lazy_string (PyObject *result)
00177 {
00178   return PyObject_TypeCheck (result, &lazy_string_object_type);
00179 }
00180 
00181 /* Extract the parameters from the lazy string object STRING.
00182    ENCODING will either be set to NULL, or will be allocated with
00183    xmalloc, in which case the callers is responsible for freeing
00184    it.  */
00185 
00186 void
00187 gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
00188                            struct type **str_type,
00189                            long *length, char **encoding)
00190 {
00191   lazy_string_object *lazy;
00192 
00193   gdb_assert (gdbpy_is_lazy_string (string));
00194 
00195   lazy = (lazy_string_object *) string;
00196 
00197   *addr = lazy->address;
00198   *str_type = lazy->type;
00199   *length = lazy->length;
00200   *encoding = lazy->encoding ? xstrdup (lazy->encoding) : NULL;
00201 }
00202 
00203 
00204 
00205 static PyMethodDef lazy_string_object_methods[] = {
00206   { "value", stpy_convert_to_value, METH_NOARGS,
00207     "Create a (lazy) value that contains a pointer to the string." },
00208   {NULL}  /* Sentinel */
00209 };
00210 
00211 
00212 static PyGetSetDef lazy_string_object_getset[] = {
00213   { "address", stpy_get_address, NULL, "Address of the string.", NULL },
00214   { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
00215   { "length", stpy_get_length, NULL, "Length of the string.", NULL },
00216   { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
00217   { NULL }  /* Sentinel */
00218 };
00219 
00220 static PyTypeObject lazy_string_object_type = {
00221   PyVarObject_HEAD_INIT (NULL, 0)
00222   "gdb.LazyString",               /*tp_name*/
00223   sizeof (lazy_string_object),    /*tp_basicsize*/
00224   0,                              /*tp_itemsize*/
00225   stpy_dealloc,                   /*tp_dealloc*/
00226   0,                              /*tp_print*/
00227   0,                              /*tp_getattr*/
00228   0,                              /*tp_setattr*/
00229   0,                              /*tp_compare*/
00230   0,                              /*tp_repr*/
00231   0,                              /*tp_as_number*/
00232   0,                              /*tp_as_sequence*/
00233   0,                              /*tp_as_mapping*/
00234   0,                              /*tp_hash */
00235   0,                              /*tp_call*/
00236   0,                              /*tp_str*/
00237   0,                              /*tp_getattro*/
00238   0,                              /*tp_setattro*/
00239   0,                              /*tp_as_buffer*/
00240   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
00241   "GDB lazy string object",       /* tp_doc */
00242   0,                              /* tp_traverse */
00243   0,                              /* tp_clear */
00244   0,                              /* tp_richcompare */
00245   0,                              /* tp_weaklistoffset */
00246   0,                              /* tp_iter */
00247   0,                              /* tp_iternext */
00248   lazy_string_object_methods,     /* tp_methods */
00249   0,                              /* tp_members */
00250   lazy_string_object_getset       /* tp_getset */
00251 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines