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