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