1 1.1 christos /* MI Command Set for GDB, the GNU debugger. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2019-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos /* GDB/MI commands implemented in Python. */ 21 1.1 christos 22 1.1 christos #include "python-internal.h" 23 1.1 christos #include "arch-utils.h" 24 1.1 christos #include "charset.h" 25 1.1 christos #include "language.h" 26 1.1 christos #include "mi/mi-cmds.h" 27 1.1 christos #include "mi/mi-parse.h" 28 1.1 christos #include "cli/cli-cmds.h" 29 1.1 christos #include <string> 30 1.1 christos 31 1.1 christos /* Debugging of Python MI commands. */ 32 1.1 christos 33 1.1 christos static bool pymicmd_debug; 34 1.1 christos 35 1.1 christos /* Implementation of "show debug py-micmd". */ 36 1.1 christos 37 1.1 christos static void 38 1.1 christos show_pymicmd_debug (struct ui_file *file, int from_tty, 39 1.1 christos struct cmd_list_element *c, const char *value) 40 1.1 christos { 41 1.1 christos gdb_printf (file, _("Python MI command debugging is %s.\n"), value); 42 1.1 christos } 43 1.1 christos 44 1.1 christos /* Print a "py-micmd" debug statement. */ 45 1.1 christos 46 1.1 christos #define pymicmd_debug_printf(fmt, ...) \ 47 1.1 christos debug_prefixed_printf_cond (pymicmd_debug, "py-micmd", fmt, ##__VA_ARGS__) 48 1.1 christos 49 1.1 christos /* Print a "py-micmd" enter/exit debug statements. */ 50 1.1 christos 51 1.1 christos #define PYMICMD_SCOPED_DEBUG_ENTER_EXIT \ 52 1.1 christos scoped_debug_enter_exit (pymicmd_debug, "py-micmd") 53 1.1 christos 54 1.1 christos struct mi_command_py; 55 1.1 christos 56 1.1 christos /* Representation of a Python gdb.MICommand object. */ 57 1.1 christos 58 1.1 christos struct micmdpy_object 59 1.1 christos { 60 1.1 christos PyObject_HEAD 61 1.1 christos 62 1.1 christos /* The object representing this command in the MI command table. This 63 1.1 christos pointer can be nullptr if the command is not currently installed into 64 1.1 christos the MI command table (see gdb.MICommand.installed property). */ 65 1.1 christos struct mi_command_py *mi_command; 66 1.1 christos 67 1.1 christos /* The string representing the name of this command, without the leading 68 1.1 christos dash. This string is never nullptr once the Python object has been 69 1.1 christos initialised. 70 1.1 christos 71 1.1 christos The memory for this string was allocated with malloc, and needs to be 72 1.1 christos deallocated with free when the Python object is deallocated. 73 1.1 christos 74 1.1 christos When the MI_COMMAND field is not nullptr, then the mi_command_py 75 1.1 christos object's name will point back to this string. */ 76 1.1 christos char *mi_command_name; 77 1.1 christos }; 78 1.1 christos 79 1.1 christos /* The MI command implemented in Python. */ 80 1.1 christos 81 1.1 christos struct mi_command_py : public mi_command 82 1.1 christos { 83 1.1 christos /* Constructs a new mi_command_py object. NAME is command name without 84 1.1 christos leading dash. OBJECT is a reference to a Python object implementing 85 1.1 christos the command. This object must inherit from gdb.MICommand and must 86 1.1 christos implement the invoke method. */ 87 1.1 christos 88 1.1 christos mi_command_py (const char *name, micmdpy_object *object) 89 1.1 christos : mi_command (name, nullptr), 90 1.1 christos m_pyobj (gdbpy_ref<micmdpy_object>::new_reference (object)) 91 1.1 christos { 92 1.1 christos pymicmd_debug_printf ("this = %p", this); 93 1.1 christos m_pyobj->mi_command = this; 94 1.1 christos } 95 1.1 christos 96 1.1 christos ~mi_command_py () 97 1.1 christos { 98 1.1 christos /* The Python object representing a MI command contains a pointer back 99 1.1 christos to this c++ object. We can safely set this pointer back to nullptr 100 1.1 christos now, to indicate the Python object no longer references a valid c++ 101 1.1 christos object. 102 1.1 christos 103 1.1 christos However, the Python object also holds the storage for our name 104 1.1 christos string. We can't clear that here as our parent's destructor might 105 1.1 christos still want to reference that string. Instead we rely on the Python 106 1.1 christos object deallocator to free that memory, and reset the pointer. */ 107 1.1 christos m_pyobj->mi_command = nullptr; 108 1.1 christos 109 1.1 christos pymicmd_debug_printf ("this = %p", this); 110 1.1 christos }; 111 1.1 christos 112 1.1 christos /* Validate that CMD_OBJ, a non-nullptr pointer, is installed into the MI 113 1.1 christos command table correctly. This function looks up the command in the MI 114 1.1 christos command table and checks that the object we get back references 115 1.1 christos CMD_OBJ. This function is only intended for calling within a 116 1.1 christos gdb_assert. This function performs many assertions internally, and 117 1.1 christos then always returns true. */ 118 1.1 christos static void validate_installation (micmdpy_object *cmd_obj); 119 1.1 christos 120 1.1 christos /* Update M_PYOBJ to NEW_PYOBJ. The pointer from M_PYOBJ that points 121 1.1 christos back to this object is swapped with the pointer in NEW_PYOBJ, which 122 1.1 christos must be nullptr, so that NEW_PYOBJ now points back to this object. 123 1.1 christos Additionally our parent's name string is stored in M_PYOBJ, so we 124 1.1 christos swap the name string with NEW_PYOBJ. 125 1.1 christos 126 1.1 christos Before this call M_PYOBJ is the Python object representing this MI 127 1.1 christos command object. After this call has completed, NEW_PYOBJ now 128 1.1 christos represents this MI command object. */ 129 1.1 christos void swap_python_object (micmdpy_object *new_pyobj) 130 1.1 christos { 131 1.1 christos /* Current object has a backlink, new object doesn't have a backlink. */ 132 1.1 christos gdb_assert (m_pyobj->mi_command != nullptr); 133 1.1 christos gdb_assert (new_pyobj->mi_command == nullptr); 134 1.1 christos 135 1.1 christos /* Clear the current M_PYOBJ's backlink, set NEW_PYOBJ's backlink. */ 136 1.1 christos std::swap (new_pyobj->mi_command, m_pyobj->mi_command); 137 1.1 christos 138 1.1 christos /* Both object have names. */ 139 1.1 christos gdb_assert (m_pyobj->mi_command_name != nullptr); 140 1.1 christos gdb_assert (new_pyobj->mi_command_name != nullptr); 141 1.1 christos 142 1.1 christos /* mi_command::m_name is the string owned by the current object. */ 143 1.1 christos gdb_assert (m_pyobj->mi_command_name == this->name ()); 144 1.1 christos 145 1.1 christos /* The name in mi_command::m_name is owned by the current object. Rather 146 1.1 christos than changing the value of mi_command::m_name (which is not accessible 147 1.1 christos from here) to point to the name owned by the new object, swap the names 148 1.1 christos of the two objects, since we know they are identical strings. */ 149 1.1 christos gdb_assert (strcmp (new_pyobj->mi_command_name, 150 1.1 christos m_pyobj->mi_command_name) == 0); 151 1.1 christos std::swap (new_pyobj->mi_command_name, m_pyobj->mi_command_name); 152 1.1 christos 153 1.1 christos /* Take a reference to the new object, drop the reference to the current 154 1.1 christos object. */ 155 1.1 christos m_pyobj = gdbpy_ref<micmdpy_object>::new_reference (new_pyobj); 156 1.1 christos } 157 1.1 christos 158 1.1 christos /* Called when the MI command is invoked. */ 159 1.1 christos virtual void invoke(struct mi_parse *parse) const override; 160 1.1 christos 161 1.1 christos private: 162 1.1 christos /* The Python object representing this MI command. */ 163 1.1 christos gdbpy_ref<micmdpy_object> m_pyobj; 164 1.1 christos }; 165 1.1 christos 166 1.1 christos using mi_command_py_up = std::unique_ptr<mi_command_py>; 167 1.1 christos 168 1.1 christos extern PyTypeObject micmdpy_object_type 169 1.1 christos CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("micmdpy_object"); 170 1.1 christos 171 1.1 christos /* Holds a Python object containing the string 'invoke'. */ 172 1.1 christos 173 1.1 christos static PyObject *invoke_cst; 174 1.1 christos 175 1.1 christos /* Called when the MI command is invoked. PARSE contains the parsed 176 1.1 christos command line arguments from the user. */ 177 1.1 christos 178 1.1 christos void 179 1.1 christos mi_command_py::invoke (struct mi_parse *parse) const 180 1.1 christos { 181 1.1 christos PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 182 1.1 christos 183 1.1 christos pymicmd_debug_printf ("this = %p, name = %s", this, name ()); 184 1.1 christos 185 1.1.1.2 christos parse->parse_argv (); 186 1.1 christos 187 1.1 christos if (parse->argv == nullptr) 188 1.1.1.2 christos error (_("Problem parsing arguments: %s %s"), parse->command.get (), 189 1.1.1.2 christos parse->args ()); 190 1.1 christos 191 1.1 christos 192 1.1 christos gdbpy_enter enter_py; 193 1.1 christos 194 1.1 christos /* Place all the arguments into a list which we pass as a single argument 195 1.1 christos to the MI command's invoke method. */ 196 1.1 christos gdbpy_ref<> argobj (PyList_New (parse->argc)); 197 1.1 christos if (argobj == nullptr) 198 1.1 christos gdbpy_handle_exception (); 199 1.1 christos 200 1.1 christos for (int i = 0; i < parse->argc; ++i) 201 1.1 christos { 202 1.1 christos gdbpy_ref<> str (PyUnicode_Decode (parse->argv[i], 203 1.1 christos strlen (parse->argv[i]), 204 1.1 christos host_charset (), nullptr)); 205 1.1 christos if (PyList_SetItem (argobj.get (), i, str.release ()) < 0) 206 1.1 christos gdbpy_handle_exception (); 207 1.1 christos } 208 1.1 christos 209 1.1 christos gdb_assert (this->m_pyobj != nullptr); 210 1.1 christos gdb_assert (PyErr_Occurred () == nullptr); 211 1.1.1.2 christos gdbpy_ref<> results 212 1.1 christos (PyObject_CallMethodObjArgs ((PyObject *) this->m_pyobj.get (), invoke_cst, 213 1.1 christos argobj.get (), nullptr)); 214 1.1.1.2 christos if (results == nullptr) 215 1.1 christos gdbpy_handle_exception (); 216 1.1 christos 217 1.1.1.2 christos if (results != Py_None) 218 1.1.1.2 christos { 219 1.1.1.2 christos /* At the top-level, the results must be a dictionary. */ 220 1.1.1.2 christos if (!PyDict_Check (results.get ())) 221 1.1.1.2 christos gdbpy_error (_("Result from invoke must be a dictionary")); 222 1.1.1.2 christos serialize_mi_results (results.get ()); 223 1.1.1.2 christos } 224 1.1 christos } 225 1.1 christos 226 1.1 christos /* See declaration above. */ 227 1.1 christos 228 1.1 christos void 229 1.1 christos mi_command_py::validate_installation (micmdpy_object *cmd_obj) 230 1.1 christos { 231 1.1 christos gdb_assert (cmd_obj != nullptr); 232 1.1 christos mi_command_py *cmd = cmd_obj->mi_command; 233 1.1 christos gdb_assert (cmd != nullptr); 234 1.1 christos const char *name = cmd_obj->mi_command_name; 235 1.1 christos gdb_assert (name != nullptr); 236 1.1 christos gdb_assert (name == cmd->name ()); 237 1.1 christos mi_command *mi_cmd = mi_cmd_lookup (name); 238 1.1 christos gdb_assert (mi_cmd == cmd); 239 1.1 christos gdb_assert (cmd->m_pyobj == cmd_obj); 240 1.1 christos } 241 1.1 christos 242 1.1 christos /* Return CMD as an mi_command_py if it is a Python MI command, else 243 1.1 christos nullptr. */ 244 1.1 christos 245 1.1 christos static mi_command_py * 246 1.1 christos as_mi_command_py (mi_command *cmd) 247 1.1 christos { 248 1.1 christos return dynamic_cast<mi_command_py *> (cmd); 249 1.1 christos } 250 1.1 christos 251 1.1 christos /* Uninstall OBJ, making the MI command represented by OBJ unavailable for 252 1.1 christos use by the user. On success 0 is returned, otherwise -1 is returned 253 1.1 christos and a Python exception will be set. */ 254 1.1 christos 255 1.1 christos static int 256 1.1 christos micmdpy_uninstall_command (micmdpy_object *obj) 257 1.1 christos { 258 1.1 christos PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 259 1.1 christos 260 1.1 christos gdb_assert (obj->mi_command != nullptr); 261 1.1 christos gdb_assert (obj->mi_command_name != nullptr); 262 1.1 christos 263 1.1 christos pymicmd_debug_printf ("name = %s", obj->mi_command_name); 264 1.1 christos 265 1.1 christos /* Remove the command from the internal MI table of commands. This will 266 1.1 christos cause the mi_command_py object to be deleted, which will clear the 267 1.1 christos backlink in OBJ. */ 268 1.1 christos bool removed = remove_mi_cmd_entry (obj->mi_command->name ()); 269 1.1 christos gdb_assert (removed); 270 1.1 christos gdb_assert (obj->mi_command == nullptr); 271 1.1 christos 272 1.1 christos return 0; 273 1.1 christos } 274 1.1 christos 275 1.1 christos /* Install OBJ as a usable MI command. Return 0 on success, and -1 on 276 1.1 christos error, in which case, a Python error will have been set. 277 1.1 christos 278 1.1 christos After successful completion the command name associated with OBJ will 279 1.1 christos be installed in the MI command table (so it can be found if the user 280 1.1 christos enters that command name), additionally, OBJ will have been added to 281 1.1 christos the gdb._mi_commands dictionary (using the command name as its key), 282 1.1 christos this will ensure that OBJ remains live even if the user gives up all 283 1.1 christos references. */ 284 1.1 christos 285 1.1 christos static int 286 1.1 christos micmdpy_install_command (micmdpy_object *obj) 287 1.1 christos { 288 1.1 christos PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 289 1.1 christos 290 1.1 christos gdb_assert (obj->mi_command == nullptr); 291 1.1 christos gdb_assert (obj->mi_command_name != nullptr); 292 1.1 christos 293 1.1 christos pymicmd_debug_printf ("name = %s", obj->mi_command_name); 294 1.1 christos 295 1.1 christos /* Look up this command name in MI_COMMANDS, a command with this name may 296 1.1 christos already exist. */ 297 1.1 christos mi_command *cmd = mi_cmd_lookup (obj->mi_command_name); 298 1.1 christos mi_command_py *cmd_py = as_mi_command_py (cmd); 299 1.1 christos 300 1.1 christos if (cmd != nullptr && cmd_py == nullptr) 301 1.1 christos { 302 1.1 christos /* There is already an MI command registered with that name, and it's not 303 1.1.1.2 christos a Python one. Forbid replacing a non-Python MI command. */ 304 1.1 christos PyErr_SetString (PyExc_RuntimeError, 305 1.1 christos _("unable to add command, name is already in use")); 306 1.1 christos return -1; 307 1.1 christos } 308 1.1 christos 309 1.1 christos if (cmd_py != nullptr) 310 1.1 christos { 311 1.1 christos /* There is already a Python MI command registered with that name, swap 312 1.1.1.2 christos in the new gdb.MICommand implementation. */ 313 1.1 christos cmd_py->swap_python_object (obj); 314 1.1 christos } 315 1.1 christos else 316 1.1 christos { 317 1.1 christos /* There's no MI command registered with that name at all, create one. */ 318 1.1 christos mi_command_py_up mi_cmd (new mi_command_py (obj->mi_command_name, obj)); 319 1.1 christos 320 1.1 christos /* Add the command to the gdb internal MI command table. */ 321 1.1 christos bool result = insert_mi_cmd_entry (std::move (mi_cmd)); 322 1.1 christos gdb_assert (result); 323 1.1 christos } 324 1.1 christos 325 1.1 christos return 0; 326 1.1 christos } 327 1.1 christos 328 1.1 christos /* Implement gdb.MICommand.__init__. The init method takes the name of 329 1.1 christos the MI command as the first argument, which must be a string, starting 330 1.1 christos with a single dash. */ 331 1.1 christos 332 1.1 christos static int 333 1.1 christos micmdpy_init (PyObject *self, PyObject *args, PyObject *kwargs) 334 1.1 christos { 335 1.1 christos PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 336 1.1 christos 337 1.1 christos micmdpy_object *cmd = (micmdpy_object *) self; 338 1.1 christos 339 1.1 christos static const char *keywords[] = { "name", nullptr }; 340 1.1 christos const char *name; 341 1.1 christos 342 1.1 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s", keywords, 343 1.1 christos &name)) 344 1.1 christos return -1; 345 1.1 christos 346 1.1 christos /* Validate command name */ 347 1.1 christos const int name_len = strlen (name); 348 1.1 christos if (name_len == 0) 349 1.1 christos { 350 1.1 christos PyErr_SetString (PyExc_ValueError, _("MI command name is empty.")); 351 1.1 christos return -1; 352 1.1 christos } 353 1.1 christos else if ((name_len < 2) || (name[0] != '-') || !isalnum (name[1])) 354 1.1 christos { 355 1.1 christos PyErr_SetString (PyExc_ValueError, 356 1.1 christos _("MI command name does not start with '-'" 357 1.1 christos " followed by at least one letter or digit.")); 358 1.1 christos return -1; 359 1.1 christos } 360 1.1 christos else 361 1.1 christos { 362 1.1 christos for (int i = 2; i < name_len; i++) 363 1.1 christos { 364 1.1 christos if (!isalnum (name[i]) && name[i] != '-') 365 1.1 christos { 366 1.1 christos PyErr_Format 367 1.1 christos (PyExc_ValueError, 368 1.1 christos _("MI command name contains invalid character: %c."), 369 1.1 christos name[i]); 370 1.1 christos return -1; 371 1.1 christos } 372 1.1 christos } 373 1.1 christos 374 1.1 christos /* Skip over the leading dash. For the rest of this function the 375 1.1 christos dash is not important. */ 376 1.1 christos ++name; 377 1.1 christos } 378 1.1 christos 379 1.1 christos /* If this object already has a name set, then this object has been 380 1.1 christos initialized before. We handle this case a little differently. */ 381 1.1 christos if (cmd->mi_command_name != nullptr) 382 1.1 christos { 383 1.1 christos /* First, we don't allow the user to change the MI command name. 384 1.1 christos Supporting this would be tricky as we would need to delete the 385 1.1 christos mi_command_py from the MI command table, however, the user might 386 1.1 christos be trying to perform this reinitialization from within the very 387 1.1 christos command we're about to delete... it all gets very messy. 388 1.1 christos 389 1.1 christos So, for now at least, we don't allow this. This doesn't seem like 390 1.1 christos an excessive restriction. */ 391 1.1 christos if (strcmp (cmd->mi_command_name, name) != 0) 392 1.1 christos { 393 1.1 christos PyErr_SetString 394 1.1 christos (PyExc_ValueError, 395 1.1 christos _("can't reinitialize object with a different command name")); 396 1.1 christos return -1; 397 1.1 christos } 398 1.1 christos 399 1.1 christos /* If there's already an object registered with the MI command table, 400 1.1 christos then we're done. That object must be a mi_command_py, which 401 1.1 christos should reference back to this micmdpy_object. */ 402 1.1 christos if (cmd->mi_command != nullptr) 403 1.1 christos { 404 1.1 christos mi_command_py::validate_installation (cmd); 405 1.1 christos return 0; 406 1.1 christos } 407 1.1 christos } 408 1.1 christos else 409 1.1 christos cmd->mi_command_name = xstrdup (name); 410 1.1 christos 411 1.1 christos /* Now we can install this mi_command_py in the MI command table. */ 412 1.1 christos return micmdpy_install_command (cmd); 413 1.1 christos } 414 1.1 christos 415 1.1 christos /* Called when a gdb.MICommand object is deallocated. */ 416 1.1 christos 417 1.1 christos static void 418 1.1 christos micmdpy_dealloc (PyObject *obj) 419 1.1 christos { 420 1.1 christos PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 421 1.1 christos 422 1.1 christos micmdpy_object *cmd = (micmdpy_object *) obj; 423 1.1 christos 424 1.1 christos /* If the Python object failed to initialize, then the name field might 425 1.1 christos be nullptr. */ 426 1.1 christos pymicmd_debug_printf ("obj = %p, name = %s", cmd, 427 1.1 christos (cmd->mi_command_name == nullptr 428 1.1 christos ? "(null)" : cmd->mi_command_name)); 429 1.1 christos 430 1.1 christos /* As the mi_command_py object holds a reference to the micmdpy_object, 431 1.1 christos the only way the dealloc function can be called is if the mi_command_py 432 1.1 christos object has been deleted, in which case the following assert will 433 1.1 christos hold. */ 434 1.1 christos gdb_assert (cmd->mi_command == nullptr); 435 1.1 christos 436 1.1 christos /* Free the memory that holds the command name. */ 437 1.1 christos xfree (cmd->mi_command_name); 438 1.1 christos cmd->mi_command_name = nullptr; 439 1.1 christos 440 1.1 christos /* Finally, free the memory for this Python object. */ 441 1.1 christos Py_TYPE (obj)->tp_free (obj); 442 1.1 christos } 443 1.1 christos 444 1.1 christos /* Python initialization for the MI commands components. */ 445 1.1 christos 446 1.1.1.2 christos static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION 447 1.1 christos gdbpy_initialize_micommands () 448 1.1 christos { 449 1.1 christos micmdpy_object_type.tp_new = PyType_GenericNew; 450 1.1 christos if (PyType_Ready (&micmdpy_object_type) < 0) 451 1.1 christos return -1; 452 1.1 christos 453 1.1 christos if (gdb_pymodule_addobject (gdb_module, "MICommand", 454 1.1 christos (PyObject *) &micmdpy_object_type) 455 1.1 christos < 0) 456 1.1 christos return -1; 457 1.1 christos 458 1.1 christos invoke_cst = PyUnicode_FromString ("invoke"); 459 1.1 christos if (invoke_cst == nullptr) 460 1.1 christos return -1; 461 1.1 christos 462 1.1 christos return 0; 463 1.1 christos } 464 1.1 christos 465 1.1.1.2 christos /* Cleanup just before GDB shuts down the Python interpreter. */ 466 1.1.1.2 christos 467 1.1.1.2 christos static void 468 1.1 christos gdbpy_finalize_micommands () 469 1.1 christos { 470 1.1 christos /* mi_command_py objects hold references to micmdpy_object objects. They must 471 1.1 christos be dropped before the Python interpreter is finalized. Do so by removing 472 1.1 christos those MI command entries, thus deleting the mi_command_py objects. */ 473 1.1 christos remove_mi_cmd_entries ([] (mi_command *cmd) 474 1.1 christos { 475 1.1 christos return as_mi_command_py (cmd) != nullptr; 476 1.1 christos }); 477 1.1 christos } 478 1.1 christos 479 1.1 christos /* Get the gdb.MICommand.name attribute, returns a string, the name of this 480 1.1 christos MI command. */ 481 1.1 christos 482 1.1 christos static PyObject * 483 1.1 christos micmdpy_get_name (PyObject *self, void *closure) 484 1.1 christos { 485 1.1 christos struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 486 1.1 christos 487 1.1 christos gdb_assert (micmd_obj->mi_command_name != nullptr); 488 1.1 christos std::string name_str = string_printf ("-%s", micmd_obj->mi_command_name); 489 1.1 christos return PyUnicode_FromString (name_str.c_str ()); 490 1.1 christos } 491 1.1 christos 492 1.1 christos /* Get the gdb.MICommand.installed property. Returns true if this MI 493 1.1 christos command is installed into the MI command table, otherwise returns 494 1.1 christos false. */ 495 1.1 christos 496 1.1 christos static PyObject * 497 1.1 christos micmdpy_get_installed (PyObject *self, void *closure) 498 1.1 christos { 499 1.1 christos struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 500 1.1 christos 501 1.1 christos if (micmd_obj->mi_command == nullptr) 502 1.1 christos Py_RETURN_FALSE; 503 1.1 christos Py_RETURN_TRUE; 504 1.1 christos } 505 1.1 christos 506 1.1 christos /* Set the gdb.MICommand.installed property. The property can be set to 507 1.1 christos either true or false. Setting the property to true will cause the 508 1.1 christos command to be installed into the MI command table (if it isn't 509 1.1 christos already), while setting this property to false will cause the command 510 1.1 christos to be removed from the MI command table (if it is present). */ 511 1.1 christos 512 1.1 christos static int 513 1.1 christos micmdpy_set_installed (PyObject *self, PyObject *newvalue, void *closure) 514 1.1 christos { 515 1.1 christos struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 516 1.1 christos 517 1.1 christos bool installed_p = PyObject_IsTrue (newvalue); 518 1.1 christos if (installed_p == (micmd_obj->mi_command != nullptr)) 519 1.1 christos return 0; 520 1.1 christos 521 1.1 christos if (installed_p) 522 1.1 christos return micmdpy_install_command (micmd_obj); 523 1.1 christos else 524 1.1 christos return micmdpy_uninstall_command (micmd_obj); 525 1.1 christos } 526 1.1 christos 527 1.1 christos /* The gdb.MICommand properties. */ 528 1.1 christos 529 1.1 christos static gdb_PyGetSetDef micmdpy_object_getset[] = { 530 1.1 christos { "name", micmdpy_get_name, nullptr, "The command's name.", nullptr }, 531 1.1 christos { "installed", micmdpy_get_installed, micmdpy_set_installed, 532 1.1 christos "Is this command installed for use.", nullptr }, 533 1.1 christos { nullptr } /* Sentinel. */ 534 1.1 christos }; 535 1.1 christos 536 1.1 christos /* The gdb.MICommand descriptor. */ 537 1.1 christos 538 1.1 christos PyTypeObject micmdpy_object_type = { 539 1.1 christos PyVarObject_HEAD_INIT (nullptr, 0) "gdb.MICommand", /*tp_name */ 540 1.1 christos sizeof (micmdpy_object), /*tp_basicsize */ 541 1.1 christos 0, /*tp_itemsize */ 542 1.1 christos micmdpy_dealloc, /*tp_dealloc */ 543 1.1 christos 0, /*tp_print */ 544 1.1 christos 0, /*tp_getattr */ 545 1.1 christos 0, /*tp_setattr */ 546 1.1 christos 0, /*tp_compare */ 547 1.1 christos 0, /*tp_repr */ 548 1.1 christos 0, /*tp_as_number */ 549 1.1 christos 0, /*tp_as_sequence */ 550 1.1 christos 0, /*tp_as_mapping */ 551 1.1 christos 0, /*tp_hash */ 552 1.1 christos 0, /*tp_call */ 553 1.1 christos 0, /*tp_str */ 554 1.1 christos 0, /*tp_getattro */ 555 1.1 christos 0, /*tp_setattro */ 556 1.1 christos 0, /*tp_as_buffer */ 557 1.1 christos Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags */ 558 1.1 christos "GDB mi-command object", /* tp_doc */ 559 1.1 christos 0, /* tp_traverse */ 560 1.1 christos 0, /* tp_clear */ 561 1.1 christos 0, /* tp_richcompare */ 562 1.1 christos 0, /* tp_weaklistoffset */ 563 1.1 christos 0, /* tp_iter */ 564 1.1 christos 0, /* tp_iternext */ 565 1.1 christos 0, /* tp_methods */ 566 1.1 christos 0, /* tp_members */ 567 1.1 christos micmdpy_object_getset, /* tp_getset */ 568 1.1 christos 0, /* tp_base */ 569 1.1 christos 0, /* tp_dict */ 570 1.1 christos 0, /* tp_descr_get */ 571 1.1 christos 0, /* tp_descr_set */ 572 1.1 christos 0, /* tp_dictoffset */ 573 1.1 christos micmdpy_init, /* tp_init */ 574 1.1 christos 0, /* tp_alloc */ 575 1.1 christos }; 576 1.1 christos 577 1.1 christos void _initialize_py_micmd (); 578 1.1 christos void 579 1.1 christos _initialize_py_micmd () 580 1.1 christos { 581 1.1 christos add_setshow_boolean_cmd 582 1.1 christos ("py-micmd", class_maintenance, &pymicmd_debug, 583 1.1 christos _("Set Python micmd debugging."), 584 1.1 christos _("Show Python micmd debugging."), 585 1.1 christos _("When on, Python micmd debugging is enabled."), 586 1.1 christos nullptr, 587 1.1 christos show_pymicmd_debug, 588 1.1 christos &setdebuglist, &showdebuglist); 589 1.1 christos } 590 1.1.1.2 christos 591 1.1.1.2 christos GDBPY_INITIALIZE_FILE (gdbpy_initialize_micommands, gdbpy_finalize_micommands); 592