Simplify gdbpy_stop_recording
[external/binutils.git] / gdb / python / py-gdb-readline.c
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