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