xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick #include "PythonReadline.h"
2*061da546Spatrick 
3*061da546Spatrick #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
4*061da546Spatrick 
5*061da546Spatrick #include <stdio.h>
6*061da546Spatrick 
7*061da546Spatrick #include <editline/readline.h>
8*061da546Spatrick 
9*061da546Spatrick // Simple implementation of the Python readline module using libedit.
10*061da546Spatrick // In the event that libedit is excluded from the build, this turns
11*061da546Spatrick // back into a null implementation that blocks the module from pulling
12*061da546Spatrick // in the GNU readline shared lib, which causes linkage confusion when
13*061da546Spatrick // both readline and libedit's readline compatibility symbols collide.
14*061da546Spatrick //
15*061da546Spatrick // Currently it only installs a PyOS_ReadlineFunctionPointer, without
16*061da546Spatrick // implementing any of the readline module methods. This is meant to
17*061da546Spatrick // work around LLVM pr18841 to avoid seg faults in the stock Python
18*061da546Spatrick // readline.so linked against GNU readline.
19*061da546Spatrick //
20*061da546Spatrick // Bug on the cpython side: https://bugs.python.org/issue38634
21*061da546Spatrick 
22*061da546Spatrick PyDoc_STRVAR(moduleDocumentation,
23*061da546Spatrick              "Simple readline module implementation based on libedit.");
24*061da546Spatrick 
25*061da546Spatrick #if PY_MAJOR_VERSION >= 3
26*061da546Spatrick static struct PyModuleDef readline_module = {
27*061da546Spatrick     PyModuleDef_HEAD_INIT, // m_base
28*061da546Spatrick     "lldb_editline",       // m_name
29*061da546Spatrick     moduleDocumentation,   // m_doc
30*061da546Spatrick     -1,                    // m_size
31*061da546Spatrick     nullptr,               // m_methods
32*061da546Spatrick     nullptr,               // m_reload
33*061da546Spatrick     nullptr,               // m_traverse
34*061da546Spatrick     nullptr,               // m_clear
35*061da546Spatrick     nullptr,               // m_free
36*061da546Spatrick };
37*061da546Spatrick #else
38*061da546Spatrick static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}};
39*061da546Spatrick #endif
40*061da546Spatrick 
41*061da546Spatrick static char *
42*061da546Spatrick #if PY_MAJOR_VERSION >= 3
43*061da546Spatrick simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
44*061da546Spatrick #else
45*061da546Spatrick simple_readline(FILE *stdin, FILE *stdout, char *prompt)
46*061da546Spatrick #endif
47*061da546Spatrick {
48*061da546Spatrick   rl_instream = stdin;
49*061da546Spatrick   rl_outstream = stdout;
50*061da546Spatrick   char *line = readline(prompt);
51*061da546Spatrick   if (!line) {
52*061da546Spatrick #if PY_MAJOR_VERSION >= 3
53*061da546Spatrick     char *ret = (char *)PyMem_RawMalloc(1);
54*061da546Spatrick #else
55*061da546Spatrick     char *ret = (char *)PyMem_Malloc(1);
56*061da546Spatrick #endif
57*061da546Spatrick     if (ret != NULL)
58*061da546Spatrick       *ret = '\0';
59*061da546Spatrick     return ret;
60*061da546Spatrick   }
61*061da546Spatrick   if (*line)
62*061da546Spatrick     add_history(line);
63*061da546Spatrick   int n = strlen(line);
64*061da546Spatrick #if PY_MAJOR_VERSION >= 3
65*061da546Spatrick   char *ret = (char *)PyMem_RawMalloc(n + 2);
66*061da546Spatrick #else
67*061da546Spatrick   char *ret = (char *)PyMem_Malloc(n + 2);
68*061da546Spatrick #endif
69*061da546Spatrick   if (ret) {
70*061da546Spatrick     memcpy(ret, line, n);
71*061da546Spatrick     free(line);
72*061da546Spatrick     ret[n] = '\n';
73*061da546Spatrick     ret[n + 1] = '\0';
74*061da546Spatrick   }
75*061da546Spatrick   return ret;
76*061da546Spatrick }
77*061da546Spatrick 
78*061da546Spatrick PyMODINIT_FUNC initlldb_readline(void) {
79*061da546Spatrick   PyOS_ReadlineFunctionPointer = simple_readline;
80*061da546Spatrick 
81*061da546Spatrick #if PY_MAJOR_VERSION >= 3
82*061da546Spatrick   return PyModule_Create(&readline_module);
83*061da546Spatrick #else
84*061da546Spatrick   Py_InitModule4("readline", moduleMethods, moduleDocumentation,
85*061da546Spatrick                  static_cast<PyObject *>(NULL), PYTHON_API_VERSION);
86*061da546Spatrick #endif
87*061da546Spatrick }
88*061da546Spatrick #endif
89