Use unique_xmalloc_ptr in Python code
[deliverable/binutils-gdb.git] / gdb / python / py-param.c
index d68d8fb9fe8b4a2c3ecc9929570ee9d6f98f41f1..0d19c97efb8858c88d7665ced730ec406b9c84fc 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB parameters implemented in Python
 
-   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2008-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +20,6 @@
 
 #include "defs.h"
 #include "value.h"
-#include "exceptions.h"
 #include "python-internal.h"
 #include "charset.h"
 #include "gdbcmd.h"
@@ -89,7 +88,8 @@ struct parmpy_object
 
 typedef struct parmpy_object parmpy_object;
 
-static PyTypeObject parmpy_object_type;
+extern PyTypeObject parmpy_object_type
+    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object");
 
 /* Some handy string constants.  */
 static PyObject *set_doc_cst;
@@ -102,7 +102,11 @@ static PyObject *
 get_attr (PyObject *obj, PyObject *attr_name)
 {
   if (PyString_Check (attr_name)
+#ifdef IS_PY3K
+      && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
+#else
       && ! strcmp (PyString_AsString (attr_name), "value"))
+#endif
     {
       parmpy_object *self = (parmpy_object *) obj;
 
@@ -129,7 +133,7 @@ set_parameter_value (parmpy_object *self, PyObject *value)
          && (self->type == var_filename
              || value != Py_None))
        {
-         PyErr_SetString (PyExc_RuntimeError, 
+         PyErr_SetString (PyExc_RuntimeError,
                           _("String required for filename."));
 
          return -1;
@@ -144,36 +148,34 @@ set_parameter_value (parmpy_object *self, PyObject *value)
        }
       else
        {
-         char *string;
-
-         string = python_string_to_host_string (value);
+         gdb::unique_xmalloc_ptr<char>
+           string (python_string_to_host_string (value));
          if (string == NULL)
            return -1;
 
          xfree (self->value.stringval);
-         self->value.stringval = string;
+         self->value.stringval = string.release ();
        }
       break;
 
     case var_enum:
       {
        int i;
-       char *str;
 
        if (! gdbpy_is_string (value))
          {
-           PyErr_SetString (PyExc_RuntimeError, 
+           PyErr_SetString (PyExc_RuntimeError,
                             _("ENUM arguments must be a string."));
            return -1;
          }
 
-       str = python_string_to_host_string (value);
+       gdb::unique_xmalloc_ptr<char>
+         str (python_string_to_host_string (value));
        if (str == NULL)
          return -1;
        for (i = 0; self->enumeration[i]; ++i)
-         if (! strcmp (self->enumeration[i], str))
+         if (! strcmp (self->enumeration[i], str.get ()))
            break;
-       xfree (str);
        if (! self->enumeration[i])
          {
            PyErr_SetString (PyExc_RuntimeError,
@@ -187,12 +189,12 @@ set_parameter_value (parmpy_object *self, PyObject *value)
     case var_boolean:
       if (! PyBool_Check (value))
        {
-         PyErr_SetString (PyExc_RuntimeError, 
+         PyErr_SetString (PyExc_RuntimeError,
                           _("A boolean argument is required."));
          return -1;
        }
       cmp = PyObject_IsTrue (value);
-      if (cmp < 0) 
+      if (cmp < 0)
          return -1;
       self->value.intval = cmp;
       break;
@@ -211,10 +213,10 @@ set_parameter_value (parmpy_object *self, PyObject *value)
        {
          cmp = PyObject_IsTrue (value);
          if (cmp < 0 )
-           return -1;    
+           return -1;  
          if (cmp == 1)
            self->value.autoboolval = AUTO_BOOLEAN_TRUE;
-         else 
+         else
            self->value.autoboolval = AUTO_BOOLEAN_FALSE;
        }
       break;
@@ -228,7 +230,7 @@ set_parameter_value (parmpy_object *self, PyObject *value)
 
        if (! PyInt_Check (value))
          {
-           PyErr_SetString (PyExc_RuntimeError, 
+           PyErr_SetString (PyExc_RuntimeError,
                             _("The value must be integer."));
            return -1;
          }
@@ -253,7 +255,7 @@ set_parameter_value (parmpy_object *self, PyObject *value)
 
        if (! ok)
          {
-           PyErr_SetString (PyExc_RuntimeError, 
+           PyErr_SetString (PyExc_RuntimeError,
                             _("Range exceeded."));
            return -1;
          }
@@ -263,7 +265,7 @@ set_parameter_value (parmpy_object *self, PyObject *value)
       }
 
     default:
-      PyErr_SetString (PyExc_RuntimeError, 
+      PyErr_SetString (PyExc_RuntimeError,
                       _("Unhandled type in parameter value."));
       return -1;
     }
@@ -276,7 +278,11 @@ static int
 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
 {
   if (PyString_Check (attr_name)
+#ifdef IS_PY3K
+      && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
+#else
       && ! strcmp (PyString_AsString (attr_name), "value"))
+#endif
     {
       if (!val)
        {
@@ -293,10 +299,10 @@ set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
 /* A helper function which returns a documentation string for an
    object. */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 get_doc_string (PyObject *object, PyObject *attr)
 {
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
   if (PyObject_HasAttr (object, attr))
     {
@@ -311,7 +317,7 @@ get_doc_string (PyObject *object, PyObject *attr)
       Py_XDECREF (ds_obj);
     }
   if (! result)
-    result = xstrdup (_("This command is not documented."));
+    result.reset (xstrdup (_("This command is not documented.")));
   return result;
 }
 
@@ -319,10 +325,10 @@ get_doc_string (PyObject *object, PyObject *attr)
    argument ARG.  ARG can be NULL.  METHOD should return a Python
    string.  If this function returns NULL, there has been an error and
    the appropriate exception set.  */
-static char *
+static gdb::unique_xmalloc_ptr<char>
 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
 {
-  char *data = NULL;
+  gdb::unique_xmalloc_ptr<char> data;
   PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL);
 
   if (! result)
@@ -331,6 +337,7 @@ call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
   if (gdbpy_is_string (result))
     {
       data = python_string_to_host_string (result);
+      Py_DECREF (result);
       if (! data)
        return NULL;
     }
@@ -338,6 +345,7 @@ call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
     {
       PyErr_SetString (PyExc_RuntimeError,
                       _("Parameter must return a string value."));
+      Py_DECREF (result);
       return NULL;
     }
 
@@ -355,7 +363,7 @@ get_set_value (char *args, int from_tty,
               struct cmd_list_element *c)
 {
   PyObject *obj = (PyObject *) get_cmd_context (c);
-  char *set_doc_string;
+  gdb::unique_xmalloc_ptr<char> set_doc_string;
   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
                                               current_language);
   PyObject *set_doc_func = PyString_FromString ("get_set_string");
@@ -363,8 +371,6 @@ get_set_value (char *args, int from_tty,
   if (! set_doc_func)
     goto error;
 
-  make_cleanup_py_decref (set_doc_func);
-
   if (PyObject_HasAttr (obj, set_doc_func))
     {
       set_doc_string = call_doc_function (obj, set_doc_func, NULL);
@@ -379,13 +385,14 @@ get_set_value (char *args, int from_tty,
       set_doc_string  = get_doc_string (obj, set_doc_cst);
     }
 
-  make_cleanup (xfree, set_doc_string);
-  fprintf_filtered (gdb_stdout, "%s\n", set_doc_string);
+  fprintf_filtered (gdb_stdout, "%s\n", set_doc_string.get ());
 
+  Py_XDECREF (set_doc_func);
   do_cleanups (cleanup);
   return;
 
  error:
+  Py_XDECREF (set_doc_func);
   gdbpy_print_stack ();
   do_cleanups (cleanup);
   return;
@@ -403,7 +410,7 @@ get_show_value (struct ui_file *file, int from_tty,
                const char *value)
 {
   PyObject *obj = (PyObject *) get_cmd_context (c);
-  char *show_doc_string = NULL;
+  gdb::unique_xmalloc_ptr<char> show_doc_string;
   struct cleanup *cleanup = ensure_python_env (get_current_arch (),
                                               current_language);
   PyObject *show_doc_func = PyString_FromString ("get_show_string");
@@ -411,8 +418,6 @@ get_show_value (struct ui_file *file, int from_tty,
   if (! show_doc_func)
     goto error;
 
-  make_cleanup_py_decref (show_doc_func);
-
   if (PyObject_HasAttr (obj, show_doc_func))
     {
       PyObject *val_obj = PyString_FromString (value);
@@ -420,15 +425,12 @@ get_show_value (struct ui_file *file, int from_tty,
       if (! val_obj)
        goto error;
 
-      make_cleanup_py_decref (val_obj);
-
       show_doc_string = call_doc_function (obj, show_doc_func, val_obj);
+      Py_DECREF (val_obj);
       if (! show_doc_string)
        goto error;
 
-      make_cleanup (xfree, show_doc_string);
-
-      fprintf_filtered (file, "%s\n", show_doc_string);
+      fprintf_filtered (file, "%s\n", show_doc_string.get ());
     }
   else
     {
@@ -436,14 +438,15 @@ get_show_value (struct ui_file *file, int from_tty,
         callback function does not exist, then attempt to read the
         show_doc attribute.  */
       show_doc_string  = get_doc_string (obj, show_doc_cst);
-      make_cleanup (xfree, show_doc_string);
-      fprintf_filtered (file, "%s %s\n", show_doc_string, value);
+      fprintf_filtered (file, "%s %s\n", show_doc_string.get (), value);
     }
 
+  Py_XDECREF (show_doc_func);
   do_cleanups (cleanup);
   return;
 
  error:
+  Py_XDECREF (show_doc_func);
   gdbpy_print_stack ();
   do_cleanups (cleanup);
   return;
@@ -460,7 +463,7 @@ add_setshow_generic (int parmclass, enum command_class cmdclass,
                     struct cmd_list_element **show_list)
 {
   struct cmd_list_element *param = NULL;
-  char *tmp_name = NULL;
+  const char *tmp_name = NULL;
 
   switch (parmclass)
     {
@@ -570,7 +573,7 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
 
   if (! PySequence_Check (enum_values))
     {
-      PyErr_SetString (PyExc_RuntimeError, 
+      PyErr_SetString (PyExc_RuntimeError,
                       _("The enumeration is not a sequence."));
       return 0;
     }
@@ -580,14 +583,13 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
     return 0;
   if (size == 0)
     {
-      PyErr_SetString (PyExc_RuntimeError, 
+      PyErr_SetString (PyExc_RuntimeError,
                       _("The enumeration is empty."));
       return 0;
     }
 
-  self->enumeration = xmalloc ((size + 1) * sizeof (char *));
+  self->enumeration = XCNEWVEC (const char *, size + 1);
   back_to = make_cleanup (free_current_contents, &self->enumeration);
-  memset (self->enumeration, 0, (size + 1) * sizeof (char *));
 
   for (i = 0; i < size; ++i)
     {
@@ -600,12 +602,14 @@ compute_enum_values (parmpy_object *self, PyObject *enum_values)
        }
       if (! gdbpy_is_string (item))
        {
+         Py_DECREF (item);
          do_cleanups (back_to);
-         PyErr_SetString (PyExc_RuntimeError, 
+         PyErr_SetString (PyExc_RuntimeError,
                           _("The enumeration item not a string."));
          return 0;
        }
-      self->enumeration[i] = python_string_to_host_string (item);
+      self->enumeration[i] = python_string_to_host_string (item).release ();
+      Py_DECREF (item);
       if (self->enumeration[i] == NULL)
        {
          do_cleanups (back_to);
@@ -651,7 +655,6 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   int parmclass, cmdtype;
   PyObject *enum_values = NULL;
   struct cmd_list_element **set_list, **show_list;
-  volatile struct gdb_exception except;
 
   if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
                          &enum_values))
@@ -707,20 +710,20 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   if (! cmd_name)
     return -1;
 
-  set_doc = get_doc_string (self, set_doc_cst);
-  show_doc = get_doc_string (self, show_doc_cst);
-  doc = get_doc_string (self, gdbpy_doc_cst);
+  set_doc = get_doc_string (self, set_doc_cst).release ();
+  show_doc = get_doc_string (self, show_doc_cst).release ();
+  doc = get_doc_string (self, gdbpy_doc_cst).release ();
 
   Py_INCREF (self);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       add_setshow_generic (parmclass, (enum command_class) cmdtype,
                           cmd_name, obj,
                           set_doc, show_doc,
                           doc, set_list, show_list);
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ALL)
     {
       xfree (cmd_name);
       xfree (set_doc);
@@ -732,47 +735,47 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
                    "%s", except.message);
       return -1;
     }
+  END_CATCH
+
   return 0;
 }
 
 \f
 
 /* Initialize the 'parameters' module.  */
-void
+int
 gdbpy_initialize_parameters (void)
 {
   int i;
 
   parmpy_object_type.tp_new = PyType_GenericNew;
   if (PyType_Ready (&parmpy_object_type) < 0)
-    return;
+    return -1;
 
   set_doc_cst = PyString_FromString ("set_doc");
   if (! set_doc_cst)
-    return;
+    return -1;
   show_doc_cst = PyString_FromString ("show_doc");
   if (! show_doc_cst)
-    return;
+    return -1;
 
   for (i = 0; parm_constants[i].name; ++i)
     {
       if (PyModule_AddIntConstant (gdb_module,
                                   parm_constants[i].name,
                                   parm_constants[i].value) < 0)
-       return;
+       return -1;
     }
 
-  Py_INCREF (&parmpy_object_type);
-  PyModule_AddObject (gdb_module, "Parameter",
-                     (PyObject *) &parmpy_object_type);
+  return gdb_pymodule_addobject (gdb_module, "Parameter",
+                                (PyObject *) &parmpy_object_type);
 }
 
 \f
 
-static PyTypeObject parmpy_object_type =
+PyTypeObject parmpy_object_type =
 {
-  PyObject_HEAD_INIT (NULL)
-  0,                             /*ob_size*/
+  PyVarObject_HEAD_INIT (NULL, 0)
   "gdb.Parameter",               /*tp_name*/
   sizeof (parmpy_object),        /*tp_basicsize*/
   0,                             /*tp_itemsize*/
This page took 0.032131 seconds and 4 git commands to generate.