1061da546Spatrick #include "PythonReadline.h"
2061da546Spatrick
3061da546Spatrick #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
4061da546Spatrick
5be691f3bSpatrick #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 static struct PyModuleDef readline_module = {
26061da546Spatrick PyModuleDef_HEAD_INIT, // m_base
27061da546Spatrick "lldb_editline", // m_name
28061da546Spatrick moduleDocumentation, // m_doc
29061da546Spatrick -1, // m_size
30061da546Spatrick nullptr, // m_methods
31061da546Spatrick nullptr, // m_reload
32061da546Spatrick nullptr, // m_traverse
33061da546Spatrick nullptr, // m_clear
34061da546Spatrick nullptr, // m_free
35061da546Spatrick };
36061da546Spatrick
simple_readline(FILE * stdin,FILE * stdout,const char * prompt)37*f6aab3d8Srobert static char *simple_readline(FILE *stdin, FILE *stdout, const char *prompt) {
38061da546Spatrick rl_instream = stdin;
39061da546Spatrick rl_outstream = stdout;
40061da546Spatrick char *line = readline(prompt);
41061da546Spatrick if (!line) {
42061da546Spatrick char *ret = (char *)PyMem_RawMalloc(1);
43*f6aab3d8Srobert if (ret != nullptr)
44061da546Spatrick *ret = '\0';
45061da546Spatrick return ret;
46061da546Spatrick }
47061da546Spatrick if (*line)
48061da546Spatrick add_history(line);
49061da546Spatrick int n = strlen(line);
50061da546Spatrick char *ret = (char *)PyMem_RawMalloc(n + 2);
51061da546Spatrick if (ret) {
52061da546Spatrick memcpy(ret, line, n);
53061da546Spatrick free(line);
54061da546Spatrick ret[n] = '\n';
55061da546Spatrick ret[n + 1] = '\0';
56061da546Spatrick }
57061da546Spatrick return ret;
58061da546Spatrick }
59061da546Spatrick
initlldb_readline(void)60061da546Spatrick PyMODINIT_FUNC initlldb_readline(void) {
61061da546Spatrick PyOS_ReadlineFunctionPointer = simple_readline;
62061da546Spatrick
63061da546Spatrick return PyModule_Create(&readline_module);
64061da546Spatrick }
65061da546Spatrick #endif
66