/* Readline support for Python. Copyright (C) 2012-2019 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 "defs.h" #include "python-internal.h" #include "top.h" #include "cli/cli-utils.h" /* Readline function suitable for PyOS_ReadlineFunctionPointer, which is used for Python's interactive parser and raw_input. In both cases, sys_stdin and sys_stdout are always stdin and stdout respectively, as far as I can tell; they are ignored and command_line_input is used instead. */ static char * gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout, #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4 const char *prompt) #else char *prompt) #endif { int n; char *p = NULL, *q; TRY { p = command_line_input (prompt, "python"); } /* Handle errors by raising Python exceptions. */ CATCH (except, RETURN_MASK_ALL) { /* Detect user interrupt (Ctrl-C). */ if (except.reason == RETURN_QUIT) return NULL; /* The thread state is nulled during gdbpy_readline_wrapper, with the original value saved in the following undocumented variable (see Python's Parser/myreadline.c and Modules/readline.c). */ PyEval_RestoreThread (_PyOS_ReadlineTState); gdbpy_convert_exception (except); PyEval_SaveThread (); return NULL; } END_CATCH /* Detect EOF (Ctrl-D). */ if (p == NULL) { q = (char *) PyMem_RawMalloc (1); if (q != NULL) q[0] = '\0'; return q; } n = strlen (p); /* Copy the line to Python and return. */ q = (char *) PyMem_RawMalloc (n + 2); if (q != NULL) { strcpy (q, p); q[n] = '\n'; q[n + 1] = '\0'; } return q; } /* Initialize Python readline support. */ void gdbpy_initialize_gdb_readline (void) { /* Python's readline module conflicts with GDB's use of readline since readline is not reentrant. Ideally, a reentrant wrapper to GDB's readline should be implemented to replace Python's readline and prevent conflicts. For now, this file implements a sys.meta_path finder that simply fails to import the readline module. */ if (PyRun_SimpleString ("\ import sys\n\ \n\ class GdbRemoveReadlineFinder:\n\ def find_module(self, fullname, path=None):\n\ if fullname == 'readline' and path is None:\n\ return self\n\ return None\n\ \n\ def load_module(self, fullname):\n\ raise ImportError('readline module disabled under GDB')\n\ \n\ sys.meta_path.append(GdbRemoveReadlineFinder())\n\ ") == 0) PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper; }