167754Smsmith/* MI Command Set for GDB, the GNU debugger. 267754Smsmith 377424Smsmith Copyright (C) 2019-2023 Free Software Foundation, Inc. 467754Smsmith 567754Smsmith This file is part of GDB. 667754Smsmith 767754Smsmith This program is free software; you can redistribute it and/or modify 867754Smsmith it under the terms of the GNU General Public License as published by 967754Smsmith the Free Software Foundation; either version 3 of the License, or 1067754Smsmith (at your option) any later version. 11202771Sjkim 1270243Smsmith This program is distributed in the hope that it will be useful, 1367754Smsmith but WITHOUT ANY WARRANTY; without even the implied warranty of 1467754Smsmith MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1567754Smsmith GNU General Public License for more details. 1667754Smsmith 1767754Smsmith You should have received a copy of the GNU General Public License 1867754Smsmith along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1967754Smsmith 2067754Smsmith/* GDB/MI commands implemented in Python. */ 2167754Smsmith 2267754Smsmith#include "defs.h" 2367754Smsmith#include "python-internal.h" 2467754Smsmith#include "arch-utils.h" 2567754Smsmith#include "charset.h" 2667754Smsmith#include "language.h" 2767754Smsmith#include "mi/mi-cmds.h" 2867754Smsmith#include "mi/mi-parse.h" 2967754Smsmith#include "cli/cli-cmds.h" 3067754Smsmith#include <string> 3167754Smsmith 3267754Smsmith/* Debugging of Python MI commands. */ 3367754Smsmith 3467754Smsmithstatic bool pymicmd_debug; 3567754Smsmith 3667754Smsmith/* Implementation of "show debug py-micmd". */ 3767754Smsmith 3867754Smsmithstatic void 3967754Smsmithshow_pymicmd_debug (struct ui_file *file, int from_tty, 4067754Smsmith struct cmd_list_element *c, const char *value) 4167754Smsmith{ 4267754Smsmith gdb_printf (file, _("Python MI command debugging is %s.\n"), value); 4367754Smsmith} 4467754Smsmith 4567754Smsmith/* Print a "py-micmd" debug statement. */ 4667754Smsmith 4767754Smsmith#define pymicmd_debug_printf(fmt, ...) \ 4867754Smsmith debug_prefixed_printf_cond (pymicmd_debug, "py-micmd", fmt, ##__VA_ARGS__) 4967754Smsmith 5067754Smsmith/* Print a "py-micmd" enter/exit debug statements. */ 5167754Smsmith 5267754Smsmith#define PYMICMD_SCOPED_DEBUG_ENTER_EXIT \ 5367754Smsmith scoped_debug_enter_exit (pymicmd_debug, "py-micmd") 5467754Smsmith 5567754Smsmithstruct mi_command_py; 5667754Smsmith 5767754Smsmith/* Representation of a Python gdb.MICommand object. */ 5867754Smsmith 5967754Smsmithstruct micmdpy_object 6067754Smsmith{ 6167754Smsmith PyObject_HEAD 6267754Smsmith 6367754Smsmith /* The object representing this command in the MI command table. This 6467754Smsmith pointer can be nullptr if the command is not currently installed into 6567754Smsmith the MI command table (see gdb.MICommand.installed property). */ 6667754Smsmith struct mi_command_py *mi_command; 6767754Smsmith 6867754Smsmith /* The string representing the name of this command, without the leading 6967754Smsmith dash. This string is never nullptr once the Python object has been 7067754Smsmith initialised. 7167754Smsmith 7267754Smsmith The memory for this string was allocated with malloc, and needs to be 7367754Smsmith deallocated with free when the Python object is deallocated. 7467754Smsmith 7567754Smsmith When the MI_COMMAND field is not nullptr, then the mi_command_py 7667754Smsmith object's name will point back to this string. */ 7767754Smsmith char *mi_command_name; 7867754Smsmith}; 7967754Smsmith 8067754Smsmith/* The MI command implemented in Python. */ 8167754Smsmith 8267754Smsmithstruct mi_command_py : public mi_command 8367754Smsmith{ 8467754Smsmith /* Constructs a new mi_command_py object. NAME is command name without 8567754Smsmith leading dash. OBJECT is a reference to a Python object implementing 8667754Smsmith the command. This object must inherit from gdb.MICommand and must 8767754Smsmith implement the invoke method. */ 8867754Smsmith 8967754Smsmith mi_command_py (const char *name, micmdpy_object *object) 9067754Smsmith : mi_command (name, nullptr), 9167754Smsmith m_pyobj (gdbpy_ref<micmdpy_object>::new_reference (object)) 9267754Smsmith { 9367754Smsmith pymicmd_debug_printf ("this = %p", this); 9467754Smsmith m_pyobj->mi_command = this; 9567754Smsmith } 9667754Smsmith 9767754Smsmith ~mi_command_py () 9867754Smsmith { 9967754Smsmith /* The Python object representing a MI command contains a pointer back 10067754Smsmith to this c++ object. We can safely set this pointer back to nullptr 10167754Smsmith now, to indicate the Python object no longer references a valid c++ 10267754Smsmith object. 10367754Smsmith 10467754Smsmith However, the Python object also holds the storage for our name 10567754Smsmith string. We can't clear that here as our parent's destructor might 10667754Smsmith still want to reference that string. Instead we rely on the Python 10767754Smsmith object deallocator to free that memory, and reset the pointer. */ 10867754Smsmith m_pyobj->mi_command = nullptr; 10967754Smsmith 11067754Smsmith pymicmd_debug_printf ("this = %p", this); 11167754Smsmith }; 11267754Smsmith 11367754Smsmith /* Validate that CMD_OBJ, a non-nullptr pointer, is installed into the MI 11467754Smsmith command table correctly. This function looks up the command in the MI 11567754Smsmith command table and checks that the object we get back references 11677424Smsmith CMD_OBJ. This function is only intended for calling within a 11767754Smsmith gdb_assert. This function performs many assertions internally, and 11867754Smsmith then always returns true. */ 119193341Sjkim static void validate_installation (micmdpy_object *cmd_obj); 120193341Sjkim 121193341Sjkim /* Update M_PYOBJ to NEW_PYOBJ. The pointer from M_PYOBJ that points 12267754Smsmith back to this object is swapped with the pointer in NEW_PYOBJ, which 12377424Smsmith must be nullptr, so that NEW_PYOBJ now points back to this object. 12491116Smsmith Additionally our parent's name string is stored in M_PYOBJ, so we 12567754Smsmith swap the name string with NEW_PYOBJ. 12667754Smsmith 127151937Sjkim Before this call M_PYOBJ is the Python object representing this MI 12867754Smsmith command object. After this call has completed, NEW_PYOBJ now 12967754Smsmith represents this MI command object. */ 13067754Smsmith void swap_python_object (micmdpy_object *new_pyobj) 13167754Smsmith { 13267754Smsmith /* Current object has a backlink, new object doesn't have a backlink. */ 13367754Smsmith gdb_assert (m_pyobj->mi_command != nullptr); 13467754Smsmith gdb_assert (new_pyobj->mi_command == nullptr); 13567754Smsmith 13667754Smsmith /* Clear the current M_PYOBJ's backlink, set NEW_PYOBJ's backlink. */ 13767754Smsmith std::swap (new_pyobj->mi_command, m_pyobj->mi_command); 13867754Smsmith 13967754Smsmith /* Both object have names. */ 140102550Siwasaki gdb_assert (m_pyobj->mi_command_name != nullptr); 141114237Snjl gdb_assert (new_pyobj->mi_command_name != nullptr); 14267754Smsmith 143114237Snjl /* mi_command::m_name is the string owned by the current object. */ 14467754Smsmith gdb_assert (m_pyobj->mi_command_name == this->name ()); 14567754Smsmith 14667754Smsmith /* The name in mi_command::m_name is owned by the current object. Rather 14767754Smsmith than changing the value of mi_command::m_name (which is not accessible 14877424Smsmith from here) to point to the name owned by the new object, swap the names 14967754Smsmith of the two objects, since we know they are identical strings. */ 15067754Smsmith gdb_assert (strcmp (new_pyobj->mi_command_name, 15167754Smsmith m_pyobj->mi_command_name) == 0); 15267754Smsmith std::swap (new_pyobj->mi_command_name, m_pyobj->mi_command_name); 15367754Smsmith 154114237Snjl /* Take a reference to the new object, drop the reference to the current 15567754Smsmith object. */ 15667754Smsmith m_pyobj = gdbpy_ref<micmdpy_object>::new_reference (new_pyobj); 15767754Smsmith } 15867754Smsmith 15967754Smsmith /* Called when the MI command is invoked. */ 16067754Smsmith virtual void invoke(struct mi_parse *parse) const override; 16187031Smsmith 16283174Smsmithprivate: 16367754Smsmith /* The Python object representing this MI command. */ 16467754Smsmith gdbpy_ref<micmdpy_object> m_pyobj; 165129684Snjl}; 166129684Snjl 167129684Snjlusing mi_command_py_up = std::unique_ptr<mi_command_py>; 168129684Snjl 169129684Snjlextern PyTypeObject micmdpy_object_type 170129684Snjl CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("micmdpy_object"); 171129684Snjl 172129684Snjl/* Holds a Python object containing the string 'invoke'. */ 173129684Snjl 17469450Smsmithstatic PyObject *invoke_cst; 175197104Sjkim 176129684Snjl/* Convert KEY_OBJ into a string that can be used as a field name in MI 177197104Sjkim output. KEY_OBJ must be a Python string object, and must only contain 178197104Sjkim characters suitable for use as an MI field name. 179197104Sjkim 180197104Sjkim If KEY_OBJ is not a string, or if KEY_OBJ contains invalid characters, 181197104Sjkim then an error is thrown. Otherwise, KEY_OBJ is converted to a string 182197104Sjkim and returned. */ 183197104Sjkim 184197104Sjkimstatic gdb::unique_xmalloc_ptr<char> 185197104Sjkimpy_object_to_mi_key (PyObject *key_obj) 186129684Snjl{ 187129684Snjl /* The key must be a string. */ 188129684Snjl if (!PyUnicode_Check (key_obj)) 189129684Snjl { 190129684Snjl gdbpy_ref<> key_repr (PyObject_Repr (key_obj)); 19169450Smsmith gdb::unique_xmalloc_ptr<char> key_repr_string; 192167802Sjkim if (key_repr != nullptr) 193167802Sjkim key_repr_string = python_string_to_target_string (key_repr.get ()); 194167802Sjkim if (key_repr_string == nullptr) 195167802Sjkim gdbpy_handle_exception (); 196167802Sjkim 197167802Sjkim gdbpy_error (_("non-string object used as key: %s"), 198167802Sjkim key_repr_string.get ()); 199167802Sjkim } 200167802Sjkim 201167802Sjkim gdb::unique_xmalloc_ptr<char> key_string 202167802Sjkim = python_string_to_target_string (key_obj); 203167802Sjkim if (key_string == nullptr) 204167802Sjkim gdbpy_handle_exception (); 205167802Sjkim 206167802Sjkim /* Predicate function, returns true if NAME is a valid field name for use 207167802Sjkim in MI result output, otherwise, returns false. */ 208167802Sjkim auto is_valid_key_name = [] (const char *name) -> bool 209167802Sjkim { 210129684Snjl gdb_assert (name != nullptr); 211167802Sjkim 212151937Sjkim if (*name == '\0' || !isalpha (*name)) 213151937Sjkim return false; 214167802Sjkim 215151937Sjkim for (; *name != '\0'; ++name) 216127175Snjl if (!isalnum (*name) && *name != '_' && *name != '-') 217167802Sjkim return false; 218167802Sjkim 219167802Sjkim return true; 220167802Sjkim }; 221127175Snjl 222167802Sjkim if (!is_valid_key_name (key_string.get ())) 223167802Sjkim { 224167802Sjkim if (*key_string.get () == '\0') 225167802Sjkim gdbpy_error (_("Invalid empty key in MI result")); 226167802Sjkim else 227167802Sjkim gdbpy_error (_("Invalid key in MI result: %s"), key_string.get ()); 228167802Sjkim } 229167802Sjkim 230167802Sjkim return key_string; 231167802Sjkim} 232167802Sjkim 233167802Sjkim/* Serialize RESULT and print it in MI format to the current_uiout. 234151937Sjkim FIELD_NAME is used as the name of this result field. 23567754Smsmith 23667754Smsmith RESULT can be a dictionary, a sequence, an iterator, or an object that 23767754Smsmith can be converted to a string, these are converted to the matching MI 23867754Smsmith output format (dictionaries as tuples, sequences and iterators as lists, 23967754Smsmith and strings as named fields). 24067754Smsmith 241104470Siwasaki If anything goes wrong while formatting the output then an error is 24267754Smsmith thrown. 24377424Smsmith 244127175Snjl This function is the recursive inner core of serialize_mi_result, and 24577424Smsmith should only be called from that function. */ 246151937Sjkim 247151937Sjkimstatic void 24867754Smsmithserialize_mi_result_1 (PyObject *result, const char *field_name) 24991116Smsmith{ 25067754Smsmith struct ui_out *uiout = current_uiout; 251107325Siwasaki 252107325Siwasaki if (PyDict_Check (result)) 25399679Siwasaki { 254107325Siwasaki PyObject *key, *value; 255129684Snjl Py_ssize_t pos = 0; 256151937Sjkim ui_out_emit_tuple tuple_emitter (uiout, field_name); 25799146Siwasaki while (PyDict_Next (result, &pos, &key, &value)) 258151937Sjkim { 259102550Siwasaki gdb::unique_xmalloc_ptr<char> key_string 260127175Snjl (py_object_to_mi_key (key)); 261151937Sjkim serialize_mi_result_1 (value, key_string.get ()); 262102550Siwasaki } 263151937Sjkim } 264151937Sjkim else if (PySequence_Check (result) && !PyUnicode_Check (result)) 265151937Sjkim { 266151937Sjkim ui_out_emit_list list_emitter (uiout, field_name); 26767754Smsmith Py_ssize_t len = PySequence_Size (result); 26867754Smsmith if (len == -1) 26967754Smsmith gdbpy_handle_exception (); 27067754Smsmith for (Py_ssize_t i = 0; i < len; ++i) 271104470Siwasaki { 27267754Smsmith gdbpy_ref<> item (PySequence_ITEM (result, i)); 273193267Sjkim if (item == nullptr) 27467754Smsmith gdbpy_handle_exception (); 27591116Smsmith serialize_mi_result_1 (item.get (), nullptr); 27691116Smsmith } 27791116Smsmith } 27891116Smsmith else if (PyIter_Check (result)) 27999146Siwasaki { 28091116Smsmith gdbpy_ref<> item; 28199146Siwasaki ui_out_emit_list list_emitter (uiout, field_name); 28299146Siwasaki while (true) 28399146Siwasaki { 28499146Siwasaki item.reset (PyIter_Next (result)); 28599146Siwasaki if (item == nullptr) 28699146Siwasaki { 28799146Siwasaki if (PyErr_Occurred () != nullptr) 28899146Siwasaki gdbpy_handle_exception (); 28991116Smsmith break; 29091116Smsmith } 29191116Smsmith serialize_mi_result_1 (item.get (), nullptr); 29291116Smsmith } 29391116Smsmith } 29491116Smsmith else 29591116Smsmith { 29691116Smsmith gdb::unique_xmalloc_ptr<char> string (gdbpy_obj_to_string (result)); 297128212Snjl if (string == nullptr) 298128212Snjl gdbpy_handle_exception (); 299128212Snjl uiout->field_string (field_name, string.get ()); 300128212Snjl } 301128212Snjl} 302128212Snjl 303128212Snjl/* Serialize RESULT and print it in MI format to the current_uiout. 304128212Snjl 305128212Snjl This function handles the top-level result initially returned from the 30667754Smsmith invoke method of the Python command implementation. At the top-level 30767754Smsmith the result must be a dictionary. The values within this dictionary can 30867754Smsmith be a wider range of types. Handling the values of the top-level 30971867Smsmith dictionary is done by serialize_mi_result_1, see that function for more 31071867Smsmith details. 311114237Snjl 312151937Sjkim If anything goes wrong while parsing and printing the MI output then an 313151937Sjkim error is thrown. */ 314151937Sjkim 315151937Sjkimstatic void 31671867Smsmithserialize_mi_result (PyObject *result) 317151937Sjkim{ 318151937Sjkim /* At the top-level, the result must be a dictionary. */ 31983174Smsmith 32083174Smsmith if (!PyDict_Check (result)) 32183174Smsmith gdbpy_error (_("Result from invoke must be a dictionary")); 32283174Smsmith 32383174Smsmith PyObject *key, *value; 324151937Sjkim Py_ssize_t pos = 0; 32583174Smsmith while (PyDict_Next (result, &pos, &key, &value)) 326151937Sjkim { 32783174Smsmith gdb::unique_xmalloc_ptr<char> key_string 328151937Sjkim (py_object_to_mi_key (key)); 32983174Smsmith serialize_mi_result_1 (value, key_string.get ()); 330151937Sjkim } 33183174Smsmith} 33299679Siwasaki 33382367Smsmith/* Called when the MI command is invoked. PARSE contains the parsed 334202771Sjkim command line arguments from the user. */ 33582367Smsmith 33682367Smsmithvoid 33771867Smsmithmi_command_py::invoke (struct mi_parse *parse) const 33882367Smsmith{ 33982367Smsmith PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 34082367Smsmith 34183174Smsmith pymicmd_debug_printf ("this = %p, name = %s", this, name ()); 34291116Smsmith 34391116Smsmith mi_parse_argv (parse->args, parse); 34491116Smsmith 34591116Smsmith if (parse->argv == nullptr) 34691116Smsmith error (_("Problem parsing arguments: %s %s"), parse->command, parse->args); 34791116Smsmith 34891116Smsmith 34991116Smsmith gdbpy_enter enter_py; 35091116Smsmith 35191116Smsmith /* Place all the arguments into a list which we pass as a single argument 35291116Smsmith to the MI command's invoke method. */ 35391116Smsmith gdbpy_ref<> argobj (PyList_New (parse->argc)); 35491116Smsmith if (argobj == nullptr) 35591116Smsmith gdbpy_handle_exception (); 35691116Smsmith 35791116Smsmith for (int i = 0; i < parse->argc; ++i) 35891116Smsmith { 359151937Sjkim gdbpy_ref<> str (PyUnicode_Decode (parse->argv[i], 36091116Smsmith strlen (parse->argv[i]), 36191116Smsmith host_charset (), nullptr)); 36291116Smsmith if (PyList_SetItem (argobj.get (), i, str.release ()) < 0) 36391116Smsmith gdbpy_handle_exception (); 36491116Smsmith } 36591116Smsmith 366151937Sjkim gdb_assert (this->m_pyobj != nullptr); 36791116Smsmith gdb_assert (PyErr_Occurred () == nullptr); 36891116Smsmith gdbpy_ref<> result 36991116Smsmith (PyObject_CallMethodObjArgs ((PyObject *) this->m_pyobj.get (), invoke_cst, 37091116Smsmith argobj.get (), nullptr)); 371193267Sjkim if (result == nullptr) 37291116Smsmith gdbpy_handle_exception (); 37391116Smsmith 37491116Smsmith if (result != Py_None) 37591116Smsmith serialize_mi_result (result.get ()); 37691116Smsmith} 37791116Smsmith 37891116Smsmith/* See declaration above. */ 37991116Smsmith 38091116Smsmithvoid 38191116Smsmithmi_command_py::validate_installation (micmdpy_object *cmd_obj) 38291116Smsmith{ 38391116Smsmith gdb_assert (cmd_obj != nullptr); 384123315Snjl mi_command_py *cmd = cmd_obj->mi_command; 38591116Smsmith gdb_assert (cmd != nullptr); 38691116Smsmith const char *name = cmd_obj->mi_command_name; 387151937Sjkim gdb_assert (name != nullptr); 38891116Smsmith gdb_assert (name == cmd->name ()); 38991116Smsmith mi_command *mi_cmd = mi_cmd_lookup (name); 39091116Smsmith gdb_assert (mi_cmd == cmd); 39191116Smsmith gdb_assert (cmd->m_pyobj == cmd_obj); 39291116Smsmith} 39391116Smsmith 39491116Smsmith/* Return CMD as an mi_command_py if it is a Python MI command, else 39591116Smsmith nullptr. */ 39691116Smsmith 397151937Sjkimstatic mi_command_py * 39891116Smsmithas_mi_command_py (mi_command *cmd) 39991116Smsmith{ 40091116Smsmith return dynamic_cast<mi_command_py *> (cmd); 401114237Snjl} 40291116Smsmith 40391116Smsmith/* Uninstall OBJ, making the MI command represented by OBJ unavailable for 40491116Smsmith use by the user. On success 0 is returned, otherwise -1 is returned 405100966Siwasaki and a Python exception will be set. */ 40691116Smsmith 40791116Smsmithstatic int 408193267Sjkimmicmdpy_uninstall_command (micmdpy_object *obj) 409100966Siwasaki{ 410197104Sjkim PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 411114237Snjl 41291116Smsmith gdb_assert (obj->mi_command != nullptr); 41391116Smsmith gdb_assert (obj->mi_command_name != nullptr); 41491116Smsmith 415114237Snjl pymicmd_debug_printf ("name = %s", obj->mi_command_name); 41691116Smsmith 41791116Smsmith /* Remove the command from the internal MI table of commands. This will 41891116Smsmith cause the mi_command_py object to be deleted, which will clear the 41991116Smsmith backlink in OBJ. */ 42091116Smsmith bool removed = remove_mi_cmd_entry (obj->mi_command->name ()); 42191116Smsmith gdb_assert (removed); 42291116Smsmith gdb_assert (obj->mi_command == nullptr); 42391116Smsmith 42491116Smsmith return 0; 42591116Smsmith} 426114237Snjl 42791116Smsmith/* Install OBJ as a usable MI command. Return 0 on success, and -1 on 42891116Smsmith error, in which case, a Python error will have been set. 429167802Sjkim 43091116Smsmith After successful completion the command name associated with OBJ will 43191116Smsmith be installed in the MI command table (so it can be found if the user 43291116Smsmith enters that command name), additionally, OBJ will have been added to 433151937Sjkim the gdb._mi_commands dictionary (using the command name as its key), 43491116Smsmith this will ensure that OBJ remains live even if the user gives up all 43591116Smsmith references. */ 43691116Smsmith 43791116Smsmithstatic int 43891116Smsmithmicmdpy_install_command (micmdpy_object *obj) 43991116Smsmith{ 44091116Smsmith PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 44191116Smsmith 44291116Smsmith gdb_assert (obj->mi_command == nullptr); 443151937Sjkim gdb_assert (obj->mi_command_name != nullptr); 44491116Smsmith 44591116Smsmith pymicmd_debug_printf ("name = %s", obj->mi_command_name); 44691116Smsmith 447114237Snjl /* Look up this command name in MI_COMMANDS, a command with this name may 44891116Smsmith already exist. */ 44991116Smsmith mi_command *cmd = mi_cmd_lookup (obj->mi_command_name); 45091116Smsmith mi_command_py *cmd_py = as_mi_command_py (cmd); 45191116Smsmith 45291116Smsmith if (cmd != nullptr && cmd_py == nullptr) 45391116Smsmith { 45491116Smsmith /* There is already an MI command registered with that name, and it's not 45591116Smsmith a Python one. Forbid replacing a non-Python MI command. */ 45691116Smsmith PyErr_SetString (PyExc_RuntimeError, 457114237Snjl _("unable to add command, name is already in use")); 45891116Smsmith return -1; 45991116Smsmith } 46091116Smsmith 46191116Smsmith if (cmd_py != nullptr) 46291116Smsmith { 46391116Smsmith /* There is already a Python MI command registered with that name, swap 46491116Smsmith in the new gdb.MICommand implementation. */ 46591116Smsmith cmd_py->swap_python_object (obj); 46691116Smsmith } 467167802Sjkim else 46891116Smsmith { 46991116Smsmith /* There's no MI command registered with that name at all, create one. */ 47091116Smsmith mi_command_py_up mi_cmd (new mi_command_py (obj->mi_command_name, obj)); 471151937Sjkim 47267754Smsmith /* Add the command to the gdb internal MI command table. */ 47391116Smsmith bool result = insert_mi_cmd_entry (std::move (mi_cmd)); 47491116Smsmith gdb_assert (result); 47591116Smsmith } 47691116Smsmith 47791116Smsmith return 0; 47891116Smsmith} 47991116Smsmith 48091116Smsmith/* Implement gdb.MICommand.__init__. The init method takes the name of 481151937Sjkim the MI command as the first argument, which must be a string, starting 48291116Smsmith with a single dash. */ 48367754Smsmith 48467754Smsmithstatic int 48567754Smsmithmicmdpy_init (PyObject *self, PyObject *args, PyObject *kwargs) 48667754Smsmith{ 487151937Sjkim PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 488151937Sjkim 489151937Sjkim micmdpy_object *cmd = (micmdpy_object *) self; 49067754Smsmith 491114237Snjl static const char *keywords[] = { "name", nullptr }; 49267754Smsmith const char *name; 493151937Sjkim 494151937Sjkim if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s", keywords, 495151937Sjkim &name)) 49667754Smsmith return -1; 49767754Smsmith 49871867Smsmith /* Validate command name */ 49967754Smsmith const int name_len = strlen (name); 50067754Smsmith if (name_len == 0) 50167754Smsmith { 50267754Smsmith PyErr_SetString (PyExc_ValueError, _("MI command name is empty.")); 50367754Smsmith return -1; 50467754Smsmith } 50567754Smsmith else if ((name_len < 2) || (name[0] != '-') || !isalnum (name[1])) 50667754Smsmith { 50767754Smsmith PyErr_SetString (PyExc_ValueError, 50867754Smsmith _("MI command name does not start with '-'" 50967754Smsmith " followed by at least one letter or digit.")); 51067754Smsmith return -1; 51185756Smsmith } 51267754Smsmith else 51385756Smsmith { 51485756Smsmith for (int i = 2; i < name_len; i++) 51577424Smsmith { 51685756Smsmith if (!isalnum (name[i]) && name[i] != '-') 51767754Smsmith { 51867754Smsmith PyErr_Format 519128212Snjl (PyExc_ValueError, 520128212Snjl _("MI command name contains invalid character: %c."), 521128212Snjl name[i]); 522128212Snjl return -1; 523128212Snjl } 524128212Snjl } 525128212Snjl 526128212Snjl /* Skip over the leading dash. For the rest of this function the 527128212Snjl dash is not important. */ 52867754Smsmith ++name; 52967754Smsmith } 53067754Smsmith 531114237Snjl /* If this object already has a name set, then this object has been 53277424Smsmith initialized before. We handle this case a little differently. */ 53391116Smsmith if (cmd->mi_command_name != nullptr) 53467754Smsmith { 53567754Smsmith /* First, we don't allow the user to change the MI command name. 536107325Siwasaki Supporting this would be tricky as we would need to delete the 53767754Smsmith mi_command_py from the MI command table, however, the user might 538167802Sjkim be trying to perform this reinitialization from within the very 53967754Smsmith command we're about to delete... it all gets very messy. 54067754Smsmith 541167802Sjkim So, for now at least, we don't allow this. This doesn't seem like 54267754Smsmith an excessive restriction. */ 54367754Smsmith if (strcmp (cmd->mi_command_name, name) != 0) 54469746Smsmith { 545114237Snjl PyErr_SetString 54699679Siwasaki (PyExc_ValueError, 54799679Siwasaki _("can't reinitialize object with a different command name")); 54899679Siwasaki return -1; 54999679Siwasaki } 55099679Siwasaki 55199679Siwasaki /* If there's already an object registered with the MI command table, 55299679Siwasaki then we're done. That object must be a mi_command_py, which 55399679Siwasaki should reference back to this micmdpy_object. */ 55499679Siwasaki if (cmd->mi_command != nullptr) 555193267Sjkim { 55699679Siwasaki mi_command_py::validate_installation (cmd); 55799679Siwasaki return 0; 55899679Siwasaki } 559151937Sjkim } 560123315Snjl else 561123315Snjl cmd->mi_command_name = xstrdup (name); 562123315Snjl 563123315Snjl /* Now we can install this mi_command_py in the MI command table. */ 564123315Snjl return micmdpy_install_command (cmd); 565123315Snjl} 566123315Snjl 567123315Snjl/* Called when a gdb.MICommand object is deallocated. */ 568123315Snjl 569151937Sjkimstatic void 570123315Snjlmicmdpy_dealloc (PyObject *obj) 571123315Snjl{ 572123315Snjl PYMICMD_SCOPED_DEBUG_ENTER_EXIT; 573123315Snjl 574123315Snjl micmdpy_object *cmd = (micmdpy_object *) obj; 575128212Snjl 576123315Snjl /* If the Python object failed to initialize, then the name field might 577123315Snjl be nullptr. */ 578128212Snjl pymicmd_debug_printf ("obj = %p, name = %s", cmd, 579128212Snjl (cmd->mi_command_name == nullptr 580123315Snjl ? "(null)" : cmd->mi_command_name)); 581123315Snjl 582128212Snjl /* As the mi_command_py object holds a reference to the micmdpy_object, 583123315Snjl the only way the dealloc function can be called is if the mi_command_py 584123315Snjl object has been deleted, in which case the following assert will 585128212Snjl hold. */ 586123315Snjl gdb_assert (cmd->mi_command == nullptr); 587128212Snjl 588128212Snjl /* Free the memory that holds the command name. */ 589128212Snjl xfree (cmd->mi_command_name); 590128212Snjl cmd->mi_command_name = nullptr; 591128212Snjl 592128212Snjl /* Finally, free the memory for this Python object. */ 593128212Snjl Py_TYPE (obj)->tp_free (obj); 594128212Snjl} 595167802Sjkim 596123315Snjl/* Python initialization for the MI commands components. */ 597128212Snjl 598123315Snjlint 599123315Snjlgdbpy_initialize_micommands () 600193267Sjkim{ 601193267Sjkim micmdpy_object_type.tp_new = PyType_GenericNew; 602193267Sjkim if (PyType_Ready (&micmdpy_object_type) < 0) 603193267Sjkim return -1; 604193267Sjkim 605128212Snjl if (gdb_pymodule_addobject (gdb_module, "MICommand", 606128212Snjl (PyObject *) &micmdpy_object_type) 607128212Snjl < 0) 608123315Snjl return -1; 609123315Snjl 610123315Snjl invoke_cst = PyUnicode_FromString ("invoke"); 611123315Snjl if (invoke_cst == nullptr) 612151937Sjkim return -1; 613123315Snjl 614123315Snjl return 0; 615123315Snjl} 616123315Snjl 617123315Snjlvoid 618123315Snjlgdbpy_finalize_micommands () 619123315Snjl{ 620123315Snjl /* mi_command_py objects hold references to micmdpy_object objects. They must 621123315Snjl be dropped before the Python interpreter is finalized. Do so by removing 622151937Sjkim those MI command entries, thus deleting the mi_command_py objects. */ 623123315Snjl remove_mi_cmd_entries ([] (mi_command *cmd) 624151937Sjkim { 625151937Sjkim return as_mi_command_py (cmd) != nullptr; 626151937Sjkim }); 627123315Snjl} 628207344Sjkim 629123315Snjl/* Get the gdb.MICommand.name attribute, returns a string, the name of this 630123315Snjl MI command. */ 631123315Snjl 632123315Snjlstatic PyObject * 633123315Snjlmicmdpy_get_name (PyObject *self, void *closure) 634123315Snjl{ 635123315Snjl struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 636123315Snjl 637123315Snjl gdb_assert (micmd_obj->mi_command_name != nullptr); 638123315Snjl std::string name_str = string_printf ("-%s", micmd_obj->mi_command_name); 639123315Snjl return PyUnicode_FromString (name_str.c_str ()); 640123315Snjl} 641123315Snjl 642123315Snjl/* Get the gdb.MICommand.installed property. Returns true if this MI 643123315Snjl command is installed into the MI command table, otherwise returns 644123315Snjl false. */ 645123315Snjl 646123315Snjlstatic PyObject * 647123315Snjlmicmdpy_get_installed (PyObject *self, void *closure) 648123315Snjl{ 649123315Snjl struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 650123315Snjl 651123315Snjl if (micmd_obj->mi_command == nullptr) 652123315Snjl Py_RETURN_FALSE; 653123315Snjl Py_RETURN_TRUE; 654123315Snjl} 655123315Snjl 656123315Snjl/* Set the gdb.MICommand.installed property. The property can be set to 657123315Snjl either true or false. Setting the property to true will cause the 658123315Snjl command to be installed into the MI command table (if it isn't 659207344Sjkim already), while setting this property to false will cause the command 660123315Snjl to be removed from the MI command table (if it is present). */ 661123315Snjl 662167802Sjkimstatic int 663167802Sjkimmicmdpy_set_installed (PyObject *self, PyObject *newvalue, void *closure) 664123315Snjl{ 665123315Snjl struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self; 666123315Snjl 667123315Snjl bool installed_p = PyObject_IsTrue (newvalue); 668193267Sjkim if (installed_p == (micmd_obj->mi_command != nullptr)) 669193267Sjkim return 0; 670193267Sjkim 671193267Sjkim if (installed_p) 672193267Sjkim return micmdpy_install_command (micmd_obj); 673193267Sjkim else 674193267Sjkim return micmdpy_uninstall_command (micmd_obj); 675193267Sjkim} 676193267Sjkim 677193267Sjkim/* The gdb.MICommand properties. */ 678193267Sjkim 679193267Sjkimstatic gdb_PyGetSetDef micmdpy_object_getset[] = { 680193267Sjkim { "name", micmdpy_get_name, nullptr, "The command's name.", nullptr }, 681193267Sjkim { "installed", micmdpy_get_installed, micmdpy_set_installed, 682193267Sjkim "Is this command installed for use.", nullptr }, 683193267Sjkim { nullptr } /* Sentinel. */ 684193267Sjkim}; 685193267Sjkim 686193267Sjkim/* The gdb.MICommand descriptor. */ 687193267Sjkim 688193267SjkimPyTypeObject micmdpy_object_type = { 689193267Sjkim PyVarObject_HEAD_INIT (nullptr, 0) "gdb.MICommand", /*tp_name */ 690193267Sjkim sizeof (micmdpy_object), /*tp_basicsize */ 691193267Sjkim 0, /*tp_itemsize */ 692193267Sjkim micmdpy_dealloc, /*tp_dealloc */ 693193267Sjkim 0, /*tp_print */ 694193267Sjkim 0, /*tp_getattr */ 695193267Sjkim 0, /*tp_setattr */ 696193267Sjkim 0, /*tp_compare */ 697193267Sjkim 0, /*tp_repr */ 698193267Sjkim 0, /*tp_as_number */ 699193267Sjkim 0, /*tp_as_sequence */ 700193267Sjkim 0, /*tp_as_mapping */ 701193267Sjkim 0, /*tp_hash */ 702193267Sjkim 0, /*tp_call */ 703193267Sjkim 0, /*tp_str */ 704193267Sjkim 0, /*tp_getattro */ 705193267Sjkim 0, /*tp_setattro */ 706193267Sjkim 0, /*tp_as_buffer */ 707193267Sjkim Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags */ 708193267Sjkim "GDB mi-command object", /* tp_doc */ 709193267Sjkim 0, /* tp_traverse */ 710193267Sjkim 0, /* tp_clear */ 711193267Sjkim 0, /* tp_richcompare */ 712193267Sjkim 0, /* tp_weaklistoffset */ 713193267Sjkim 0, /* tp_iter */ 714193267Sjkim 0, /* tp_iternext */ 715193267Sjkim 0, /* tp_methods */ 716193267Sjkim 0, /* tp_members */ 717193267Sjkim micmdpy_object_getset, /* tp_getset */ 718193267Sjkim 0, /* tp_base */ 719193267Sjkim 0, /* tp_dict */ 720193267Sjkim 0, /* tp_descr_get */ 721193267Sjkim 0, /* tp_descr_set */ 722102550Siwasaki 0, /* tp_dictoffset */ 723100966Siwasaki micmdpy_init, /* tp_init */ 724100966Siwasaki 0, /* tp_alloc */ 725100966Siwasaki}; 72699679Siwasaki 727151937Sjkimvoid _initialize_py_micmd (); 728100966Siwasakivoid 729100966Siwasaki_initialize_py_micmd () 730100966Siwasaki{ 731151937Sjkim add_setshow_boolean_cmd 732100966Siwasaki ("py-micmd", class_maintenance, &pymicmd_debug, 733151937Sjkim _("Set Python micmd debugging."), 734151937Sjkim _("Show Python micmd debugging."), 735100966Siwasaki _("When on, Python micmd debugging is enabled."), 736100966Siwasaki nullptr, 737100966Siwasaki show_pymicmd_debug, 738151937Sjkim &setdebuglist, &showdebuglist); 73969746Smsmith} 740114237Snjl