1 /* Readline support for Python. 2 3 Copyright (C) 2012-2019 Free Software Foundation, Inc. 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 #include "defs.h" 21 #include "python-internal.h" 22 #include "top.h" 23 #include "cli/cli-utils.h" 24 25 /* Readline function suitable for PyOS_ReadlineFunctionPointer, which 26 is used for Python's interactive parser and raw_input. In both 27 cases, sys_stdin and sys_stdout are always stdin and stdout 28 respectively, as far as I can tell; they are ignored and 29 command_line_input is used instead. */ 30 31 static char * 32 gdbpy_readline_wrapper (FILE *sys_stdin, FILE *sys_stdout, 33 #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 4 34 const char *prompt) 35 #else 36 char *prompt) 37 #endif 38 { 39 int n; 40 char *p = NULL, *q; 41 42 TRY 43 { 44 p = command_line_input (prompt, "python"); 45 } 46 /* Handle errors by raising Python exceptions. */ 47 CATCH (except, RETURN_MASK_ALL) 48 { 49 /* Detect user interrupt (Ctrl-C). */ 50 if (except.reason == RETURN_QUIT) 51 return NULL; 52 53 /* The thread state is nulled during gdbpy_readline_wrapper, 54 with the original value saved in the following undocumented 55 variable (see Python's Parser/myreadline.c and 56 Modules/readline.c). */ 57 PyEval_RestoreThread (_PyOS_ReadlineTState); 58 gdbpy_convert_exception (except); 59 PyEval_SaveThread (); 60 return NULL; 61 } 62 END_CATCH 63 64 /* Detect EOF (Ctrl-D). */ 65 if (p == NULL) 66 { 67 q = (char *) PyMem_RawMalloc (1); 68 if (q != NULL) 69 q[0] = '\0'; 70 return q; 71 } 72 73 n = strlen (p); 74 75 /* Copy the line to Python and return. */ 76 q = (char *) PyMem_RawMalloc (n + 2); 77 if (q != NULL) 78 { 79 strcpy (q, p); 80 q[n] = '\n'; 81 q[n + 1] = '\0'; 82 } 83 return q; 84 } 85 86 /* Initialize Python readline support. */ 87 88 void 89 gdbpy_initialize_gdb_readline (void) 90 { 91 /* Python's readline module conflicts with GDB's use of readline 92 since readline is not reentrant. Ideally, a reentrant wrapper to 93 GDB's readline should be implemented to replace Python's readline 94 and prevent conflicts. For now, this file implements a 95 sys.meta_path finder that simply fails to import the readline 96 module. */ 97 if (PyRun_SimpleString ("\ 98 import sys\n\ 99 \n\ 100 class GdbRemoveReadlineFinder:\n\ 101 def find_module(self, fullname, path=None):\n\ 102 if fullname == 'readline' and path is None:\n\ 103 return self\n\ 104 return None\n\ 105 \n\ 106 def load_module(self, fullname):\n\ 107 raise ImportError('readline module disabled under GDB')\n\ 108 \n\ 109 sys.meta_path.append(GdbRemoveReadlineFinder())\n\ 110 ") == 0) 111 PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper; 112 } 113 114