xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1061da546Spatrick #include "PythonReadline.h"
2061da546Spatrick 
3061da546Spatrick #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
4061da546Spatrick 
5*be691f3bSpatrick #include <cstdio>
6061da546Spatrick 
7061da546Spatrick #include <editline/readline.h>
8061da546Spatrick 
9061da546Spatrick // Simple implementation of the Python readline module using libedit.
10061da546Spatrick // In the event that libedit is excluded from the build, this turns
11061da546Spatrick // back into a null implementation that blocks the module from pulling
12061da546Spatrick // in the GNU readline shared lib, which causes linkage confusion when
13061da546Spatrick // both readline and libedit's readline compatibility symbols collide.
14061da546Spatrick //
15061da546Spatrick // Currently it only installs a PyOS_ReadlineFunctionPointer, without
16061da546Spatrick // implementing any of the readline module methods. This is meant to
17061da546Spatrick // work around LLVM pr18841 to avoid seg faults in the stock Python
18061da546Spatrick // readline.so linked against GNU readline.
19061da546Spatrick //
20061da546Spatrick // Bug on the cpython side: https://bugs.python.org/issue38634
21061da546Spatrick 
22061da546Spatrick PyDoc_STRVAR(moduleDocumentation,
23061da546Spatrick              "Simple readline module implementation based on libedit.");
24061da546Spatrick 
25061da546Spatrick #if PY_MAJOR_VERSION >= 3
26061da546Spatrick static struct PyModuleDef readline_module = {
27061da546Spatrick     PyModuleDef_HEAD_INIT, // m_base
28061da546Spatrick     "lldb_editline",       // m_name
29061da546Spatrick     moduleDocumentation,   // m_doc
30061da546Spatrick     -1,                    // m_size
31061da546Spatrick     nullptr,               // m_methods
32061da546Spatrick     nullptr,               // m_reload
33061da546Spatrick     nullptr,               // m_traverse
34061da546Spatrick     nullptr,               // m_clear
35061da546Spatrick     nullptr,               // m_free
36061da546Spatrick };
37061da546Spatrick #else
38061da546Spatrick static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}};
39061da546Spatrick #endif
40061da546Spatrick 
41061da546Spatrick static char *
42061da546Spatrick #if PY_MAJOR_VERSION >= 3
43061da546Spatrick simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
44061da546Spatrick #else
45061da546Spatrick simple_readline(FILE *stdin, FILE *stdout, char *prompt)
46061da546Spatrick #endif
47061da546Spatrick {
48061da546Spatrick   rl_instream = stdin;
49061da546Spatrick   rl_outstream = stdout;
50061da546Spatrick   char *line = readline(prompt);
51061da546Spatrick   if (!line) {
52061da546Spatrick #if PY_MAJOR_VERSION >= 3
53061da546Spatrick     char *ret = (char *)PyMem_RawMalloc(1);
54061da546Spatrick #else
55061da546Spatrick     char *ret = (char *)PyMem_Malloc(1);
56061da546Spatrick #endif
57061da546Spatrick     if (ret != NULL)
58061da546Spatrick       *ret = '\0';
59061da546Spatrick     return ret;
60061da546Spatrick   }
61061da546Spatrick   if (*line)
62061da546Spatrick     add_history(line);
63061da546Spatrick   int n = strlen(line);
64061da546Spatrick #if PY_MAJOR_VERSION >= 3
65061da546Spatrick   char *ret = (char *)PyMem_RawMalloc(n + 2);
66061da546Spatrick #else
67061da546Spatrick   char *ret = (char *)PyMem_Malloc(n + 2);
68061da546Spatrick #endif
69061da546Spatrick   if (ret) {
70061da546Spatrick     memcpy(ret, line, n);
71061da546Spatrick     free(line);
72061da546Spatrick     ret[n] = '\n';
73061da546Spatrick     ret[n + 1] = '\0';
74061da546Spatrick   }
75061da546Spatrick   return ret;
76061da546Spatrick }
77061da546Spatrick 
78061da546Spatrick PyMODINIT_FUNC initlldb_readline(void) {
79061da546Spatrick   PyOS_ReadlineFunctionPointer = simple_readline;
80061da546Spatrick 
81061da546Spatrick #if PY_MAJOR_VERSION >= 3
82061da546Spatrick   return PyModule_Create(&readline_module);
83061da546Spatrick #else
84061da546Spatrick   Py_InitModule4("readline", moduleMethods, moduleDocumentation,
85061da546Spatrick                  static_cast<PyObject *>(NULL), PYTHON_API_VERSION);
86061da546Spatrick #endif
87061da546Spatrick }
88061da546Spatrick #endif
89