1 /* GDB parameters implemented in Python
2 
3    Copyright (C) 2008-2024 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 
21 #include "value.h"
22 #include "python-internal.h"
23 #include "charset.h"
24 #include "cli/cli-cmds.h"
25 #include "cli/cli-decode.h"
26 #include "completer.h"
27 #include "language.h"
28 #include "arch-utils.h"
29 
30 /* Python parameter types as in PARM_CONSTANTS below.  */
31 
32 enum py_param_types
33 {
34   param_boolean,
35   param_auto_boolean,
36   param_uinteger,
37   param_integer,
38   param_string,
39   param_string_noescape,
40   param_optional_filename,
41   param_filename,
42   param_zinteger,
43   param_zuinteger,
44   param_zuinteger_unlimited,
45   param_enum,
46 };
47 
48 /* Translation from Python parameters to GDB variable types.  Keep in the
49    same order as PARAM_TYPES due to C++'s lack of designated initializers.  */
50 
51 static const struct
52 {
53   /* The type of the parameter.  */
54   enum var_types type;
55 
56   /* Extra literals, such as `unlimited', accepted in lieu of a number.  */
57   const literal_def *extra_literals;
58 }
59 param_to_var[] =
60 {
61   { var_boolean },
62   { var_auto_boolean },
63   { var_uinteger, uinteger_unlimited_literals },
64   { var_integer, integer_unlimited_literals },
65   { var_string },
66   { var_string_noescape },
67   { var_optional_filename },
68   { var_filename },
69   { var_integer },
70   { var_uinteger },
71   { var_pinteger, pinteger_unlimited_literals },
72   { var_enum }
73 };
74 
75 /* Parameter constants and their values.  */
76 static struct {
77   const char *name;
78   int value;
79 } parm_constants[] =
80 {
81   { "PARAM_BOOLEAN", param_boolean }, /* ARI: param_boolean */
82   { "PARAM_AUTO_BOOLEAN", param_auto_boolean },
83   { "PARAM_UINTEGER", param_uinteger },
84   { "PARAM_INTEGER", param_integer },
85   { "PARAM_STRING", param_string },
86   { "PARAM_STRING_NOESCAPE", param_string_noescape },
87   { "PARAM_OPTIONAL_FILENAME", param_optional_filename },
88   { "PARAM_FILENAME", param_filename },
89   { "PARAM_ZINTEGER", param_zinteger },
90   { "PARAM_ZUINTEGER", param_zuinteger },
91   { "PARAM_ZUINTEGER_UNLIMITED", param_zuinteger_unlimited },
92   { "PARAM_ENUM", param_enum },
93   { NULL, 0 }
94 };
95 
96 /* A union that can hold anything described by enum var_types.  */
97 union parmpy_variable
98 {
99   /* Hold a boolean value.  */
100   bool boolval;
101 
102   /* Hold an integer value.  */
103   int intval;
104 
105   /* Hold an auto_boolean.  */
106   enum auto_boolean autoboolval;
107 
108   /* Hold an unsigned integer value, for uinteger.  */
109   unsigned int uintval;
110 
111   /* Hold a string, for the various string types.  The std::string is
112      new-ed.  */
113   std::string *stringval;
114 
115   /* Hold a string, for enums.  */
116   const char *cstringval;
117 };
118 
119 /* A GDB parameter.  */
120 struct parmpy_object
121 {
122   PyObject_HEAD
123 
124   /* The type of the parameter.  */
125   enum var_types type;
126 
127   /* Extra literals, such as `unlimited', accepted in lieu of a number.  */
128   const literal_def *extra_literals;
129 
130   /* The value of the parameter.  */
131   union parmpy_variable value;
132 
133   /* For an enum command, the possible values.  The vector is
134      allocated with xmalloc, as is each element.  It is
135      NULL-terminated.  */
136   const char **enumeration;
137 };
138 
139 /* Wraps a setting around an existing parmpy_object.  This abstraction
140    is used to manipulate the value in S->VALUE in a type safe manner using
141    the setting interface.  */
142 
143 static setting
make_setting(parmpy_object * s)144 make_setting (parmpy_object *s)
145 {
146   enum var_types type = s->type;
147 
148   if (var_type_uses<bool> (type))
149     return setting (type, &s->value.boolval);
150   else if (var_type_uses<int> (type))
151     return setting (type, &s->value.intval, s->extra_literals);
152   else if (var_type_uses<auto_boolean> (type))
153     return setting (type, &s->value.autoboolval);
154   else if (var_type_uses<unsigned int> (type))
155     return setting (type, &s->value.uintval, s->extra_literals);
156   else if (var_type_uses<std::string> (type))
157     return setting (type, s->value.stringval);
158   else if (var_type_uses<const char *> (type))
159     return setting (type, &s->value.cstringval);
160   else
161     gdb_assert_not_reached ("unhandled var type");
162 }
163 
164 extern PyTypeObject parmpy_object_type
165     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object");
166 
167 /* Some handy string constants.  */
168 static PyObject *set_doc_cst;
169 static PyObject *show_doc_cst;
170 
171 
172 
173 /* Get an attribute.  */
174 static PyObject *
get_attr(PyObject * obj,PyObject * attr_name)175 get_attr (PyObject *obj, PyObject *attr_name)
176 {
177   if (PyUnicode_Check (attr_name)
178       && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
179     {
180       parmpy_object *self = (parmpy_object *) obj;
181 
182       return gdbpy_parameter_value (make_setting (self));
183     }
184 
185   return PyObject_GenericGetAttr (obj, attr_name);
186 }
187 
188 /* Set a parameter value from a Python value.  Return 0 on success.  Returns
189    -1 on error, with a python exception set.  */
190 static int
set_parameter_value(parmpy_object * self,PyObject * value)191 set_parameter_value (parmpy_object *self, PyObject *value)
192 {
193   int cmp;
194 
195   switch (self->type)
196     {
197     case var_string:
198     case var_string_noescape:
199     case var_optional_filename:
200     case var_filename:
201       if (! gdbpy_is_string (value)
202             && (self->type == var_filename
203                 || value != Py_None))
204           {
205             PyErr_SetString (PyExc_RuntimeError,
206                                  _("String required for filename."));
207 
208             return -1;
209           }
210       if (value == Py_None)
211           self->value.stringval->clear ();
212       else
213           {
214             gdb::unique_xmalloc_ptr<char>
215               string (python_string_to_host_string (value));
216             if (string == NULL)
217               return -1;
218 
219             *self->value.stringval = string.get ();
220           }
221       break;
222 
223     case var_enum:
224       {
225           int i;
226 
227           if (! gdbpy_is_string (value))
228             {
229               PyErr_SetString (PyExc_RuntimeError,
230                                    _("ENUM arguments must be a string."));
231               return -1;
232             }
233 
234           gdb::unique_xmalloc_ptr<char>
235             str (python_string_to_host_string (value));
236           if (str == NULL)
237             return -1;
238           for (i = 0; self->enumeration[i]; ++i)
239             if (! strcmp (self->enumeration[i], str.get ()))
240               break;
241           if (! self->enumeration[i])
242             {
243               PyErr_SetString (PyExc_RuntimeError,
244                                    _("The value must be member of an enumeration."));
245               return -1;
246             }
247           self->value.cstringval = self->enumeration[i];
248           break;
249       }
250 
251     case var_boolean:
252       if (! PyBool_Check (value))
253           {
254             PyErr_SetString (PyExc_RuntimeError,
255                                  _("A boolean argument is required."));
256             return -1;
257           }
258       cmp = PyObject_IsTrue (value);
259       if (cmp < 0)
260             return -1;
261       self->value.boolval = cmp;
262       break;
263 
264     case var_auto_boolean:
265       if (! PyBool_Check (value) && value != Py_None)
266           {
267             PyErr_SetString (PyExc_RuntimeError,
268                                  _("A boolean or None is required"));
269             return -1;
270           }
271 
272       if (value == Py_None)
273           self->value.autoboolval = AUTO_BOOLEAN_AUTO;
274       else
275           {
276             cmp = PyObject_IsTrue (value);
277             if (cmp < 0 )
278               return -1;
279             if (cmp == 1)
280               self->value.autoboolval = AUTO_BOOLEAN_TRUE;
281             else
282               self->value.autoboolval = AUTO_BOOLEAN_FALSE;
283           }
284       break;
285 
286     case var_uinteger:
287     case var_integer:
288     case var_pinteger:
289       {
290           const literal_def *extra_literals = self->extra_literals;
291           enum tribool allowed = TRIBOOL_UNKNOWN;
292           enum var_types var_type = self->type;
293           std::string buffer = "";
294           size_t count = 0;
295           LONGEST val;
296 
297           if (extra_literals != nullptr)
298             {
299               gdb::unique_xmalloc_ptr<char>
300                 str (python_string_to_host_string (value));
301               const char *s = str != nullptr ? str.get () : nullptr;
302               PyErr_Clear ();
303 
304               for (const literal_def *l = extra_literals;
305                      l->literal != nullptr;
306                      l++, count++)
307                 {
308                     if (count != 0)
309                       buffer += ", ";
310                     buffer = buffer + "'" + l->literal + "'";
311                     if (allowed == TRIBOOL_UNKNOWN
312                         && ((value == Py_None && !strcmp ("unlimited", l->literal))
313                               || (s != nullptr && !strcmp (s, l->literal))))
314                       {
315                         val = l->use;
316                         allowed = TRIBOOL_TRUE;
317                       }
318                 }
319             }
320 
321           if (allowed == TRIBOOL_UNKNOWN)
322             {
323               val = PyLong_AsLongLong (value);
324 
325               if (PyErr_Occurred ())
326                 {
327                     if (extra_literals == nullptr)
328                       PyErr_SetString (PyExc_RuntimeError,
329                                            _("The value must be integer."));
330                     else if (count > 1)
331                       PyErr_SetString (PyExc_RuntimeError,
332                                            string_printf (_("integer or one of: %s"),
333                                                               buffer.c_str ()).c_str ());
334                     else
335                       PyErr_SetString (PyExc_RuntimeError,
336                                            string_printf (_("integer or %s"),
337                                                               buffer.c_str ()).c_str ());
338                     return -1;
339                 }
340 
341 
342               if (extra_literals != nullptr)
343                 for (const literal_def *l = extra_literals;
344                        l->literal != nullptr;
345                        l++)
346                     {
347                       if (l->val.has_value () && val == *l->val)
348                         {
349                           allowed = TRIBOOL_TRUE;
350                           val = l->use;
351                           break;
352                         }
353                       else if (val == l->use)
354                         allowed = TRIBOOL_FALSE;
355                     }
356               }
357 
358           if (allowed == TRIBOOL_UNKNOWN)
359             {
360               if (val > UINT_MAX || val < INT_MIN
361                     || (var_type == var_uinteger && val < 0)
362                     || (var_type == var_integer && val > INT_MAX)
363                     || (var_type == var_pinteger && val < 0)
364                     || (var_type == var_pinteger && val > INT_MAX))
365                 allowed = TRIBOOL_FALSE;
366             }
367           if (allowed == TRIBOOL_FALSE)
368             {
369               PyErr_SetString (PyExc_RuntimeError,
370                                    _("Range exceeded."));
371               return -1;
372             }
373 
374           if (self->type == var_uinteger)
375             self->value.uintval = (unsigned) val;
376           else
377             self->value.intval = (int) val;
378           break;
379       }
380 
381     default:
382       PyErr_SetString (PyExc_RuntimeError,
383                            _("Unhandled type in parameter value."));
384       return -1;
385     }
386 
387   return 0;
388 }
389 
390 /* Set an attribute.  Returns -1 on error, with a python exception set.  */
391 static int
set_attr(PyObject * obj,PyObject * attr_name,PyObject * val)392 set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
393 {
394   if (PyUnicode_Check (attr_name)
395       && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
396     {
397       if (!val)
398           {
399             PyErr_SetString (PyExc_RuntimeError,
400                                  _("Cannot delete a parameter's value."));
401             return -1;
402           }
403       return set_parameter_value ((parmpy_object *) obj, val);
404     }
405 
406   return PyObject_GenericSetAttr (obj, attr_name, val);
407 }
408 
409 /* Build up the path to command C, but drop the first component of the
410    command prefix.  This is only intended for use with the set/show
411    parameters this file deals with, the first prefix should always be
412    either 'set' or 'show'.
413 
414    As an example, if this full command is 'set prefix_a prefix_b command'
415    this function will return the string 'prefix_a prefix_b command'.  */
416 
417 static std::string
full_cmd_name_without_first_prefix(struct cmd_list_element * c)418 full_cmd_name_without_first_prefix (struct cmd_list_element *c)
419 {
420   std::vector<std::string> components
421     = c->command_components ();
422   gdb_assert (components.size () > 1);
423   std::string result = components[1];
424   for (int i = 2; i < components.size (); ++i)
425     result += " " + components[i];
426   return result;
427 }
428 
429 /* The different types of documentation string.  */
430 
431 enum doc_string_type
432 {
433   doc_string_set,
434   doc_string_show,
435   doc_string_description
436 };
437 
438 /* A helper function which returns a documentation string for an
439    object. */
440 
441 static gdb::unique_xmalloc_ptr<char>
get_doc_string(PyObject * object,enum doc_string_type doc_type,const char * cmd_name)442 get_doc_string (PyObject *object, enum doc_string_type doc_type,
443                     const char *cmd_name)
444 {
445   gdb::unique_xmalloc_ptr<char> result;
446 
447   PyObject *attr = nullptr;
448   switch (doc_type)
449     {
450     case doc_string_set:
451       attr = set_doc_cst;
452       break;
453     case doc_string_show:
454       attr = show_doc_cst;
455       break;
456     case doc_string_description:
457       attr = gdbpy_doc_cst;
458       break;
459     }
460   gdb_assert (attr != nullptr);
461 
462   if (PyObject_HasAttr (object, attr))
463     {
464       gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr));
465 
466       if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
467           {
468             result = python_string_to_host_string (ds_obj.get ());
469             if (result == NULL)
470               gdbpy_print_stack ();
471             else if (doc_type == doc_string_description)
472               result = gdbpy_fix_doc_string_indentation (std::move (result));
473           }
474     }
475 
476   if (result == nullptr)
477     {
478       if (doc_type == doc_string_description)
479           result.reset (xstrdup (_("This command is not documented.")));
480       else
481           {
482             if (doc_type == doc_string_show)
483               result = xstrprintf (_("Show the current value of '%s'."),
484                                          cmd_name);
485             else
486               result = xstrprintf (_("Set the current value of '%s'."),
487                                          cmd_name);
488           }
489     }
490   return result;
491 }
492 
493 /* Helper function which will execute a METHOD in OBJ passing the
494    argument ARG.  ARG can be NULL.  METHOD should return a Python
495    string.  If this function returns NULL, there has been an error and
496    the appropriate exception set.  */
497 static gdb::unique_xmalloc_ptr<char>
call_doc_function(PyObject * obj,PyObject * method,PyObject * arg)498 call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
499 {
500   gdb::unique_xmalloc_ptr<char> data;
501   gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL));
502 
503   if (result == NULL)
504     return NULL;
505 
506   if (gdbpy_is_string (result.get ()))
507     {
508       data = python_string_to_host_string (result.get ());
509       if (! data)
510           return NULL;
511     }
512   else
513     {
514       PyErr_SetString (PyExc_RuntimeError,
515                            _("Parameter must return a string value."));
516       return NULL;
517     }
518 
519   return data;
520 }
521 
522 /* A callback function that is registered against the respective
523    add_setshow_* set_doc prototype.  This function calls the Python function
524    "get_set_string" if it exists, which will return a string.  That string
525    is then printed.  If "get_set_string" does not exist, or returns an
526    empty string, then nothing is printed.  */
527 static void
get_set_value(const char * args,int from_tty,struct cmd_list_element * c)528 get_set_value (const char *args, int from_tty,
529                  struct cmd_list_element *c)
530 {
531   PyObject *obj = (PyObject *) c->context ();
532   gdb::unique_xmalloc_ptr<char> set_doc_string;
533 
534   gdbpy_enter enter_py;
535   gdbpy_ref<> set_doc_func (PyUnicode_FromString ("get_set_string"));
536 
537   if (set_doc_func == NULL)
538     {
539       gdbpy_print_stack ();
540       return;
541     }
542 
543   if (PyObject_HasAttr (obj, set_doc_func.get ()))
544     {
545       set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL);
546       if (! set_doc_string)
547           gdbpy_handle_exception ();
548     }
549 
550   const char *str = set_doc_string.get ();
551   if (str != nullptr && str[0] != '\0')
552     gdb_printf ("%s\n", str);
553 }
554 
555 /* A callback function that is registered against the respective
556    add_setshow_* show_doc prototype.  This function will either call
557    the Python function "get_show_string" or extract the Python
558    attribute "show_doc" and return the contents as a string.  If
559    neither exist, insert a string indicating the Parameter is not
560    documented.  */
561 static void
get_show_value(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)562 get_show_value (struct ui_file *file, int from_tty,
563                     struct cmd_list_element *c,
564                     const char *value)
565 {
566   PyObject *obj = (PyObject *) c->context ();
567   gdb::unique_xmalloc_ptr<char> show_doc_string;
568 
569   gdbpy_enter enter_py;
570   gdbpy_ref<> show_doc_func (PyUnicode_FromString ("get_show_string"));
571 
572   if (show_doc_func == NULL)
573     {
574       gdbpy_print_stack ();
575       return;
576     }
577 
578   if (PyObject_HasAttr (obj, show_doc_func.get ()))
579     {
580       gdbpy_ref<> val_obj (PyUnicode_FromString (value));
581 
582       if (val_obj == NULL)
583           {
584             gdbpy_print_stack ();
585             return;
586           }
587 
588       show_doc_string = call_doc_function (obj, show_doc_func.get (),
589                                                      val_obj.get ());
590       if (! show_doc_string)
591           {
592             gdbpy_print_stack ();
593             return;
594           }
595 
596       gdb_printf (file, "%s\n", show_doc_string.get ());
597     }
598   else
599     {
600       /* If there is no 'get_show_string' callback then we want to show
601            something sensible here.  In older versions of GDB (< 7.3) we
602            didn't support 'get_show_string', and instead we just made use of
603            GDB's builtin use of the show_doc.  However, GDB's builtin
604            show_doc adjustment is not i18n friendly, so, instead, we just
605            print this generic string.  */
606       std::string cmd_path = full_cmd_name_without_first_prefix (c);
607       gdb_printf (file, _("The current value of '%s' is \"%s\".\n"),
608                       cmd_path.c_str (), value);
609     }
610 }
611 
612 
613 /* A helper function that dispatches to the appropriate add_setshow
614    function.  */
615 static void
add_setshow_generic(enum var_types type,const literal_def * extra_literals,enum command_class cmdclass,gdb::unique_xmalloc_ptr<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)616 add_setshow_generic (enum var_types type, const literal_def *extra_literals,
617                          enum command_class cmdclass,
618                          gdb::unique_xmalloc_ptr<char> cmd_name,
619                          parmpy_object *self,
620                          const char *set_doc, const char *show_doc,
621                          const char *help_doc,
622                          struct cmd_list_element **set_list,
623                          struct cmd_list_element **show_list)
624 {
625   set_show_commands commands;
626 
627   switch (type)
628     {
629     case var_boolean:
630       commands = add_setshow_boolean_cmd (cmd_name.get (), cmdclass,
631                                                     &self->value.boolval, set_doc,
632                                                     show_doc, help_doc, get_set_value,
633                                                     get_show_value, set_list, show_list);
634 
635       break;
636 
637     case var_auto_boolean:
638       commands = add_setshow_auto_boolean_cmd (cmd_name.get (), cmdclass,
639                                                          &self->value.autoboolval,
640                                                          set_doc, show_doc, help_doc,
641                                                          get_set_value, get_show_value,
642                                                          set_list, show_list);
643       break;
644 
645     case var_uinteger:
646       commands = add_setshow_uinteger_cmd (cmd_name.get (), cmdclass,
647                                                      &self->value.uintval,
648                                                      extra_literals, set_doc,
649                                                      show_doc, help_doc, get_set_value,
650                                                      get_show_value, set_list, show_list);
651       break;
652 
653     case var_integer:
654       commands = add_setshow_integer_cmd (cmd_name.get (), cmdclass,
655                                                     &self->value.intval,
656                                                     extra_literals, set_doc,
657                                                     show_doc, help_doc, get_set_value,
658                                                     get_show_value, set_list, show_list);
659       break;
660 
661     case var_pinteger:
662       commands = add_setshow_pinteger_cmd (cmd_name.get (), cmdclass,
663                                                      &self->value.intval,
664                                                      extra_literals, set_doc,
665                                                      show_doc, help_doc, get_set_value,
666                                                      get_show_value, set_list, show_list);
667       break;
668 
669     case var_string:
670       commands = add_setshow_string_cmd (cmd_name.get (), cmdclass,
671                                                    self->value.stringval, set_doc,
672                                                    show_doc, help_doc, get_set_value,
673                                                    get_show_value, set_list, show_list);
674       break;
675 
676     case var_string_noescape:
677       commands = add_setshow_string_noescape_cmd (cmd_name.get (), cmdclass,
678                                                               self->value.stringval,
679                                                               set_doc, show_doc, help_doc,
680                                                               get_set_value, get_show_value,
681                                                               set_list, show_list);
682       break;
683 
684     case var_optional_filename:
685       commands = add_setshow_optional_filename_cmd (cmd_name.get (), cmdclass,
686                                                                 self->value.stringval,
687                                                                 set_doc, show_doc, help_doc,
688                                                                 get_set_value,
689                                                                 get_show_value, set_list,
690                                                                 show_list);
691       break;
692 
693     case var_filename:
694       commands = add_setshow_filename_cmd (cmd_name.get (), cmdclass,
695                                                      self->value.stringval, set_doc,
696                                                      show_doc, help_doc, get_set_value,
697                                                      get_show_value, set_list, show_list);
698       break;
699 
700     case var_enum:
701       /* Initialize the value, just in case.  */
702       self->value.cstringval = self->enumeration[0];
703       commands = add_setshow_enum_cmd (cmd_name.get (), cmdclass,
704                                                self->enumeration,
705                                                &self->value.cstringval, set_doc,
706                                                show_doc, help_doc, get_set_value,
707                                                get_show_value, set_list, show_list);
708       break;
709 
710     default:
711       gdb_assert_not_reached ("Unhandled parameter class.");
712     }
713 
714   /* Register Python objects in both commands' context.  */
715   commands.set->set_context (self);
716   commands.show->set_context (self);
717 
718   /* We (unfortunately) currently leak the command name.  */
719   cmd_name.release ();
720 }
721 
722 /* A helper which computes enum values.  Returns 1 on success.  Returns 0 on
723    error, with a python exception set.  */
724 static int
compute_enum_values(parmpy_object * self,PyObject * enum_values)725 compute_enum_values (parmpy_object *self, PyObject *enum_values)
726 {
727   Py_ssize_t size, i;
728 
729   if (! enum_values)
730     {
731       PyErr_SetString (PyExc_RuntimeError,
732                            _("An enumeration is required for PARAM_ENUM."));
733       return 0;
734     }
735 
736   if (! PySequence_Check (enum_values))
737     {
738       PyErr_SetString (PyExc_RuntimeError,
739                            _("The enumeration is not a sequence."));
740       return 0;
741     }
742 
743   size = PySequence_Size (enum_values);
744   if (size < 0)
745     return 0;
746   if (size == 0)
747     {
748       PyErr_SetString (PyExc_RuntimeError,
749                            _("The enumeration is empty."));
750       return 0;
751     }
752 
753   gdb_argv holder (XCNEWVEC (char *, size + 1));
754   char **enumeration = holder.get ();
755 
756   for (i = 0; i < size; ++i)
757     {
758       gdbpy_ref<> item (PySequence_GetItem (enum_values, i));
759 
760       if (item == NULL)
761           return 0;
762       if (! gdbpy_is_string (item.get ()))
763           {
764             PyErr_SetString (PyExc_RuntimeError,
765                                  _("The enumeration item not a string."));
766             return 0;
767           }
768       enumeration[i] = python_string_to_host_string (item.get ()).release ();
769       if (enumeration[i] == NULL)
770           return 0;
771     }
772 
773   self->enumeration = const_cast<const char**> (holder.release ());
774   return 1;
775 }
776 
777 /* Object initializer; sets up gdb-side structures for command.
778 
779    Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])
780 
781    NAME is the name of the parameter.  It may consist of multiple
782    words, in which case the final word is the name of the new command,
783    and earlier words must be prefix commands.
784 
785    CMDCLASS is the kind of command.  It should be one of the COMMAND_*
786    constants defined in the gdb module.
787 
788    PARMCLASS is the type of the parameter.  It should be one of the
789    PARAM_* constants defined in the gdb module.
790 
791    If PARMCLASS is PARAM_ENUM, then the final argument should be a
792    collection of strings.  These strings are the valid values for this
793    parameter.
794 
795    The documentation for the parameter is taken from the doc string
796    for the python class.
797 
798    Returns -1 on error, with a python exception set.  */
799 
800 static int
parmpy_init(PyObject * self,PyObject * args,PyObject * kwds)801 parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
802 {
803   parmpy_object *obj = (parmpy_object *) self;
804   const char *name;
805   gdb::unique_xmalloc_ptr<char> set_doc, show_doc, doc;
806   int parmclass, cmdtype;
807   PyObject *enum_values = NULL;
808   struct cmd_list_element **set_list, **show_list;
809   const literal_def *extra_literals;
810   enum var_types type;
811 
812   if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
813                                 &enum_values))
814     return -1;
815 
816   if (cmdtype != no_class && cmdtype != class_run
817       && cmdtype != class_vars && cmdtype != class_stack
818       && cmdtype != class_files && cmdtype != class_support
819       && cmdtype != class_info && cmdtype != class_breakpoint
820       && cmdtype != class_trace && cmdtype != class_obscure
821       && cmdtype != class_maintenance)
822     {
823       PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
824       return -1;
825     }
826 
827   if (parmclass != param_boolean /* ARI: param_boolean */
828       && parmclass != param_auto_boolean
829       && parmclass != param_uinteger && parmclass != param_integer
830       && parmclass != param_string && parmclass != param_string_noescape
831       && parmclass != param_optional_filename && parmclass != param_filename
832       && parmclass != param_zinteger && parmclass != param_zuinteger
833       && parmclass != param_zuinteger_unlimited && parmclass != param_enum)
834     {
835       PyErr_SetString (PyExc_RuntimeError,
836                            _("Invalid parameter class argument."));
837       return -1;
838     }
839 
840   if (enum_values && parmclass != param_enum)
841     {
842       PyErr_SetString (PyExc_RuntimeError,
843                            _("Only PARAM_ENUM accepts a fourth argument."));
844       return -1;
845     }
846   if (parmclass == param_enum)
847     {
848       if (! compute_enum_values (obj, enum_values))
849           return -1;
850     }
851   else
852     obj->enumeration = NULL;
853   type = param_to_var[parmclass].type;
854   extra_literals = param_to_var[parmclass].extra_literals;
855   obj->type = type;
856   obj->extra_literals = extra_literals;
857   memset (&obj->value, 0, sizeof (obj->value));
858 
859   if (var_type_uses<std::string> (obj->type))
860     obj->value.stringval = new std::string;
861 
862   gdb::unique_xmalloc_ptr<char> cmd_name
863     = gdbpy_parse_command_name (name, &set_list, &setlist);
864   if (cmd_name == nullptr)
865     return -1;
866 
867   cmd_name = gdbpy_parse_command_name (name, &show_list, &showlist);
868   if (cmd_name == nullptr)
869     return -1;
870 
871   set_doc = get_doc_string (self, doc_string_set, name);
872   show_doc = get_doc_string (self, doc_string_show, name);
873   doc = get_doc_string (self, doc_string_description, cmd_name.get ());
874 
875   Py_INCREF (self);
876 
877   try
878     {
879       add_setshow_generic (type, extra_literals,
880                                  (enum command_class) cmdtype,
881                                  std::move (cmd_name), obj,
882                                  set_doc.get (), show_doc.get (),
883                                  doc.get (), set_list, show_list);
884     }
885   catch (const gdb_exception &except)
886     {
887       Py_DECREF (self);
888       gdbpy_convert_exception (except);
889       return -1;
890     }
891 
892   return 0;
893 }
894 
895 /* Deallocate function for a gdb.Parameter.  */
896 
897 static void
parmpy_dealloc(PyObject * obj)898 parmpy_dealloc (PyObject *obj)
899 {
900   parmpy_object *parm_obj = (parmpy_object *) obj;
901 
902   if (var_type_uses<std::string> (parm_obj->type))
903     delete parm_obj->value.stringval;
904 }
905 
906 /* Initialize the 'parameters' module.  */
907 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_parameters(void)908 gdbpy_initialize_parameters (void)
909 {
910   int i;
911 
912   parmpy_object_type.tp_new = PyType_GenericNew;
913   if (PyType_Ready (&parmpy_object_type) < 0)
914     return -1;
915 
916   set_doc_cst = PyUnicode_FromString ("set_doc");
917   if (! set_doc_cst)
918     return -1;
919   show_doc_cst = PyUnicode_FromString ("show_doc");
920   if (! show_doc_cst)
921     return -1;
922 
923   for (i = 0; parm_constants[i].name; ++i)
924     {
925       if (PyModule_AddIntConstant (gdb_module,
926                                            parm_constants[i].name,
927                                            parm_constants[i].value) < 0)
928           return -1;
929     }
930 
931   return gdb_pymodule_addobject (gdb_module, "Parameter",
932                                          (PyObject *) &parmpy_object_type);
933 }
934 
935 GDBPY_INITIALIZE_FILE (gdbpy_initialize_parameters);
936 
937 
938 
939 PyTypeObject parmpy_object_type =
940 {
941   PyVarObject_HEAD_INIT (NULL, 0)
942   "gdb.Parameter",              /*tp_name*/
943   sizeof (parmpy_object),       /*tp_basicsize*/
944   0,                                      /*tp_itemsize*/
945   parmpy_dealloc,               /*tp_dealloc*/
946   0,                                      /*tp_print*/
947   0,                                      /*tp_getattr*/
948   0,                                      /*tp_setattr*/
949   0,                                      /*tp_compare*/
950   0,                                      /*tp_repr*/
951   0,                                      /*tp_as_number*/
952   0,                                      /*tp_as_sequence*/
953   0,                                      /*tp_as_mapping*/
954   0,                                      /*tp_hash */
955   0,                                      /*tp_call*/
956   0,                                      /*tp_str*/
957   get_attr,                               /*tp_getattro*/
958   set_attr,                               /*tp_setattro*/
959   0,                                      /*tp_as_buffer*/
960   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
961   "GDB parameter object",       /* tp_doc */
962   0,                                      /* tp_traverse */
963   0,                                      /* tp_clear */
964   0,                                      /* tp_richcompare */
965   0,                                      /* tp_weaklistoffset */
966   0,                                      /* tp_iter */
967   0,                                      /* tp_iternext */
968   0,                                      /* tp_methods */
969   0,                                      /* tp_members */
970   0,                                      /* tp_getset */
971   0,                                      /* tp_base */
972   0,                                      /* tp_dict */
973   0,                                      /* tp_descr_get */
974   0,                                      /* tp_descr_set */
975   0,                                      /* tp_dictoffset */
976   parmpy_init,                            /* tp_init */
977   0,                                      /* tp_alloc */
978 };
979