X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-param.c;h=7b183cfa553c71bbd767937018e722138608f86d;hb=1acda8039ba681e88416a7da6a6e3abdcae6b86b;hp=9f56c3a744d97d8c7ccff64619d8735c19fbf1d7;hpb=aa36459a9256a0e74bba08842e9ff6d10cab543d;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c index 9f56c3a744..7b183cfa55 100644 --- a/gdb/python/py-param.c +++ b/gdb/python/py-param.c @@ -1,6 +1,6 @@ /* GDB parameters implemented in Python - Copyright (C) 2008-2013 Free Software Foundation, Inc. + Copyright (C) 2008-2020 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" @@ -32,7 +31,7 @@ /* Parameter constants and their values. */ struct parm_constant { - char *name; + const char *name; int value; }; @@ -47,6 +46,8 @@ struct parm_constant parm_constants[] = { "PARAM_OPTIONAL_FILENAME", var_optional_filename }, { "PARAM_FILENAME", var_filename }, { "PARAM_ZINTEGER", var_zinteger }, + { "PARAM_ZUINTEGER", var_zuinteger }, + { "PARAM_ZUINTEGER_UNLIMITED", var_zuinteger_unlimited }, { "PARAM_ENUM", var_enum }, { NULL, 0 } }; @@ -54,7 +55,10 @@ struct parm_constant parm_constants[] = /* A union that can hold anything described by enum var_types. */ union parmpy_variable { - /* Hold an integer value, for boolean and integer types. */ + /* Hold a boolean value. */ + bool boolval; + + /* Hold an integer value. */ int intval; /* Hold an auto_boolean. */ @@ -89,7 +93,7 @@ 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. */ @@ -134,7 +138,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; @@ -149,36 +153,34 @@ set_parameter_value (parmpy_object *self, PyObject *value) } else { - char *string; - - string = python_string_to_host_string (value); + gdb::unique_xmalloc_ptr + 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 + 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, @@ -192,14 +194,14 @@ 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; + self->value.boolval = cmp; break; case var_auto_boolean: @@ -216,10 +218,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; @@ -227,13 +229,15 @@ set_parameter_value (parmpy_object *self, PyObject *value) case var_integer: case var_zinteger: case var_uinteger: + case var_zuinteger: + case var_zuinteger_unlimited: { long l; int ok; if (! PyInt_Check (value)) { - PyErr_SetString (PyExc_RuntimeError, + PyErr_SetString (PyExc_RuntimeError, _("The value must be integer.")); return -1; } @@ -241,34 +245,50 @@ set_parameter_value (parmpy_object *self, PyObject *value) if (! gdb_py_int_as_long (value, &l)) return -1; - if (self->type == var_uinteger) + switch (self->type) { - ok = (l >= 0 && l <= UINT_MAX); + case var_uinteger: if (l == 0) l = UINT_MAX; - } - else if (self->type == var_integer) - { + /* Fall through. */ + case var_zuinteger: + ok = (l >= 0 && l <= UINT_MAX); + break; + + case var_zuinteger_unlimited: + ok = (l >= -1 && l <= INT_MAX); + break; + + case var_integer: ok = (l >= INT_MIN && l <= INT_MAX); if (l == 0) l = INT_MAX; + break; + + case var_zinteger: + ok = (l >= INT_MIN && l <= INT_MAX); + break; + + default: + gdb_assert_not_reached ("unknown var_ constant"); } - else - ok = (l >= INT_MIN && l <= INT_MAX); if (! ok) { - PyErr_SetString (PyExc_RuntimeError, + PyErr_SetString (PyExc_RuntimeError, _("Range exceeded.")); return -1; } - self->value.intval = (int) l; + if (self->type == var_uinteger || self->type == var_zuinteger) + self->value.uintval = (unsigned) l; + else + self->value.intval = (int) l; break; } default: - PyErr_SetString (PyExc_RuntimeError, + PyErr_SetString (PyExc_RuntimeError, _("Unhandled type in parameter value.")); return -1; } @@ -302,25 +322,24 @@ 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 get_doc_string (PyObject *object, PyObject *attr) { - char *result = NULL; + gdb::unique_xmalloc_ptr result; if (PyObject_HasAttr (object, attr)) { - PyObject *ds_obj = PyObject_GetAttr (object, attr); + gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr)); - if (ds_obj && gdbpy_is_string (ds_obj)) + if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ())) { - result = python_string_to_host_string (ds_obj); + result = python_string_to_host_string (ds_obj.get ()); if (result == NULL) gdbpy_print_stack (); } - Py_XDECREF (ds_obj); } if (! result) - result = xstrdup (_("This command is not documented.")); + result.reset (xstrdup (_("This command is not documented."))); return result; } @@ -328,19 +347,18 @@ 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 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) { - char *data = NULL; - PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL); + gdb::unique_xmalloc_ptr data; + gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL)); - if (! result) + if (result == NULL) return NULL; - if (gdbpy_is_string (result)) + if (gdbpy_is_string (result.get ())) { - data = python_string_to_host_string (result); - Py_DECREF (result); + data = python_string_to_host_string (result.get ()); if (! data) return NULL; } @@ -348,7 +366,6 @@ call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) { PyErr_SetString (PyExc_RuntimeError, _("Parameter must return a string value.")); - Py_DECREF (result); return NULL; } @@ -362,44 +379,31 @@ call_doc_function (PyObject *obj, PyObject *method, PyObject *arg) neither exist, insert a string indicating the Parameter is not documented. */ static void -get_set_value (char *args, int from_tty, +get_set_value (const char *args, int from_tty, struct cmd_list_element *c) { PyObject *obj = (PyObject *) get_cmd_context (c); - char *set_doc_string; - struct cleanup *cleanup = ensure_python_env (get_current_arch (), - current_language); - PyObject *set_doc_func = PyString_FromString ("get_set_string"); + gdb::unique_xmalloc_ptr set_doc_string; - if (! set_doc_func) - goto error; + gdbpy_enter enter_py (get_current_arch (), current_language); + gdbpy_ref<> set_doc_func (PyString_FromString ("get_set_string")); - if (PyObject_HasAttr (obj, set_doc_func)) + if (set_doc_func == NULL) { - set_doc_string = call_doc_function (obj, set_doc_func, NULL); - if (! set_doc_string) - goto error; + gdbpy_print_stack (); + return; } - else + + if (PyObject_HasAttr (obj, set_doc_func.get ())) { - /* We have to preserve the existing < GDB 7.3 API. If a - callback function does not exist, then attempt to read the - set_doc attribute. */ - set_doc_string = get_doc_string (obj, set_doc_cst); + set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL); + if (! set_doc_string) + gdbpy_handle_exception (); } - make_cleanup (xfree, set_doc_string); - fprintf_filtered (gdb_stdout, "%s\n", set_doc_string); - - Py_XDECREF (set_doc_func); - do_cleanups (cleanup); - return; - - error: - Py_XDECREF (set_doc_func); - gdbpy_print_stack (); - do_cleanups (cleanup); - return; + const char *str = set_doc_string.get (); + if (str != nullptr && str[0] != '\0') + fprintf_filtered (gdb_stdout, "%s\n", str); } /* A callback function that is registered against the respective @@ -414,29 +418,36 @@ 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; - struct cleanup *cleanup = ensure_python_env (get_current_arch (), - current_language); - PyObject *show_doc_func = PyString_FromString ("get_show_string"); + gdb::unique_xmalloc_ptr show_doc_string; - if (! show_doc_func) - goto error; + gdbpy_enter enter_py (get_current_arch (), current_language); + gdbpy_ref<> show_doc_func (PyString_FromString ("get_show_string")); - if (PyObject_HasAttr (obj, show_doc_func)) + if (show_doc_func == NULL) { - PyObject *val_obj = PyString_FromString (value); + gdbpy_print_stack (); + return; + } - if (! val_obj) - goto error; + if (PyObject_HasAttr (obj, show_doc_func.get ())) + { + gdbpy_ref<> val_obj (PyString_FromString (value)); - show_doc_string = call_doc_function (obj, show_doc_func, val_obj); - Py_DECREF (val_obj); - if (! show_doc_string) - goto error; + if (val_obj == NULL) + { + gdbpy_print_stack (); + return; + } - make_cleanup (xfree, show_doc_string); + show_doc_string = call_doc_function (obj, show_doc_func.get (), + val_obj.get ()); + if (! show_doc_string) + { + gdbpy_print_stack (); + return; + } - fprintf_filtered (file, "%s\n", show_doc_string); + fprintf_filtered (file, "%s\n", show_doc_string.get ()); } else { @@ -444,19 +455,8 @@ 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; } @@ -464,8 +464,9 @@ get_show_value (struct ui_file *file, int from_tty, function. */ static void add_setshow_generic (int parmclass, enum command_class cmdclass, - char *cmd_name, parmpy_object *self, - char *set_doc, char *show_doc, char *help_doc, + const char *cmd_name, parmpy_object *self, + const char *set_doc, const char *show_doc, + const char *help_doc, struct cmd_list_element **set_list, struct cmd_list_element **show_list) { @@ -477,7 +478,7 @@ add_setshow_generic (int parmclass, enum command_class cmdclass, case var_boolean: add_setshow_boolean_cmd (cmd_name, cmdclass, - &self->value.intval, set_doc, show_doc, + &self->value.boolval, set_doc, show_doc, help_doc, get_set_value, get_show_value, set_list, show_list); @@ -540,6 +541,21 @@ add_setshow_generic (int parmclass, enum command_class cmdclass, set_list, show_list); break; + case var_zuinteger: + add_setshow_zuinteger_cmd (cmd_name, cmdclass, + &self->value.uintval, set_doc, show_doc, + help_doc, get_set_value, get_show_value, + set_list, show_list); + break; + + case var_zuinteger_unlimited: + add_setshow_zuinteger_unlimited_cmd (cmd_name, cmdclass, + &self->value.intval, set_doc, + show_doc, help_doc, get_set_value, + get_show_value, + set_list, show_list); + break; + case var_enum: add_setshow_enum_cmd (cmd_name, cmdclass, self->enumeration, &self->value.cstringval, set_doc, show_doc, @@ -569,7 +585,6 @@ static int compute_enum_values (parmpy_object *self, PyObject *enum_values) { Py_ssize_t size, i; - struct cleanup *back_to; if (! enum_values) { @@ -580,7 +595,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; } @@ -590,43 +605,32 @@ 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 *)); - back_to = make_cleanup (free_current_contents, &self->enumeration); - memset (self->enumeration, 0, (size + 1) * sizeof (char *)); + gdb_argv holder (XCNEWVEC (char *, size + 1)); + char **enumeration = holder.get (); for (i = 0; i < size; ++i) { - PyObject *item = PySequence_GetItem (enum_values, i); + gdbpy_ref<> item (PySequence_GetItem (enum_values, i)); - if (! item) + if (item == NULL) + return 0; + if (! gdbpy_is_string (item.get ())) { - do_cleanups (back_to); - return 0; - } - 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); - Py_DECREF (item); - if (self->enumeration[i] == NULL) - { - do_cleanups (back_to); - return 0; - } - make_cleanup (xfree, (char *) self->enumeration[i]); + enumeration[i] = python_string_to_host_string (item.get ()).release (); + if (enumeration[i] == NULL) + return 0; } - discard_cleanups (back_to); + self->enumeration = const_cast (holder.release ()); return 1; } @@ -658,12 +662,11 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) { parmpy_object *obj = (parmpy_object *) self; const char *name; - char *set_doc, *show_doc, *doc; + gdb::unique_xmalloc_ptr set_doc, show_doc, doc; char *cmd_name; 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)) @@ -685,7 +688,8 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) && parmclass != var_uinteger && parmclass != var_integer && parmclass != var_string && parmclass != var_string_noescape && parmclass != var_optional_filename && parmclass != var_filename - && parmclass != var_zinteger && parmclass != var_enum) + && parmclass != var_zinteger && parmclass != var_zuinteger + && parmclass != var_zuinteger_unlimited && parmclass != var_enum) { PyErr_SetString (PyExc_RuntimeError, _("Invalid parameter class argument.")); @@ -725,25 +729,21 @@ parmpy_init (PyObject *self, PyObject *args, PyObject *kwds) 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); + set_doc.get (), show_doc.get (), + doc.get (), set_list, show_list); } - if (except.reason < 0) + catch (const gdb_exception &except) { xfree (cmd_name); - xfree (set_doc); - xfree (show_doc); - xfree (doc); Py_DECREF (self); - PyErr_Format (except.reason == RETURN_QUIT - ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, - "%s", except.message); + gdbpy_convert_exception (except); return -1; } + return 0; } @@ -780,7 +780,7 @@ gdbpy_initialize_parameters (void) -static PyTypeObject parmpy_object_type = +PyTypeObject parmpy_object_type = { PyVarObject_HEAD_INIT (NULL, 0) "gdb.Parameter", /*tp_name*/