/* Python DAP interpreter Copyright (C) 2022-2024 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "python-internal.h" #include "interps.h" #include "cli-out.h" #include "ui.h" class dap_interp final : public interp { public: explicit dap_interp (const char *name) : interp (name), m_ui_out (new cli_ui_out (gdb_stdout)) { } ~dap_interp () override = default; void init (bool top_level) override; void suspend () override { } void resume () override { } void exec (const char *command) override { /* Just ignore it. */ } void set_logging (ui_file_up logfile, bool logging_redirect, bool debug_redirect) override { /* Just ignore it. */ } ui_out *interp_ui_out () override { return m_ui_out.get (); } void pre_command_loop () override; bool supports_new_ui () const override { return false; } private: std::unique_ptr m_ui_out; }; /* Call function FN_NAME from module gdb.dap. */ static void call_dap_fn (const char *fn_name) { gdbpy_enter enter_py; gdbpy_ref<> dap_module (PyImport_ImportModule ("gdb.dap")); if (dap_module == nullptr) gdbpy_handle_exception (); gdbpy_ref<> func (PyObject_GetAttrString (dap_module.get (), fn_name)); if (func == nullptr) gdbpy_handle_exception (); gdbpy_ref<> result_obj (PyObject_CallObject (func.get (), nullptr)); if (result_obj == nullptr) gdbpy_handle_exception (); } void dap_interp::init (bool top_level) { #if CXX_STD_THREAD call_dap_fn ("run"); current_ui->input_fd = -1; current_ui->m_input_interactive_p = false; #else error (_("GDB was compiled without threading, which DAP requires")); #endif } void dap_interp::pre_command_loop () { call_dap_fn ("pre_command_loop"); } void _initialize_py_interp (); void _initialize_py_interp () { /* The dap code uses module typing, available starting python 3.5. */ #if PY_VERSION_HEX >= 0x03050000 interp_factory_register ("dap", [] (const char *name) -> interp * { return new dap_interp (name); }); #endif }