19357b5d0Sserge-sans-paille #include "PythonReadline.h"
29357b5d0Sserge-sans-paille
39357b5d0Sserge-sans-paille #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
49357b5d0Sserge-sans-paille
576e47d48SRaphael Isemann #include <cstdio>
69357b5d0Sserge-sans-paille
79357b5d0Sserge-sans-paille #include <editline/readline.h>
89357b5d0Sserge-sans-paille
99357b5d0Sserge-sans-paille // Simple implementation of the Python readline module using libedit.
109357b5d0Sserge-sans-paille // In the event that libedit is excluded from the build, this turns
119357b5d0Sserge-sans-paille // back into a null implementation that blocks the module from pulling
129357b5d0Sserge-sans-paille // in the GNU readline shared lib, which causes linkage confusion when
139357b5d0Sserge-sans-paille // both readline and libedit's readline compatibility symbols collide.
149357b5d0Sserge-sans-paille //
159357b5d0Sserge-sans-paille // Currently it only installs a PyOS_ReadlineFunctionPointer, without
169357b5d0Sserge-sans-paille // implementing any of the readline module methods. This is meant to
179357b5d0Sserge-sans-paille // work around LLVM pr18841 to avoid seg faults in the stock Python
189357b5d0Sserge-sans-paille // readline.so linked against GNU readline.
199357b5d0Sserge-sans-paille //
209357b5d0Sserge-sans-paille // Bug on the cpython side: https://bugs.python.org/issue38634
219357b5d0Sserge-sans-paille
229357b5d0Sserge-sans-paille PyDoc_STRVAR(moduleDocumentation,
239357b5d0Sserge-sans-paille "Simple readline module implementation based on libedit.");
249357b5d0Sserge-sans-paille
259357b5d0Sserge-sans-paille static struct PyModuleDef readline_module = {
269357b5d0Sserge-sans-paille PyModuleDef_HEAD_INIT, // m_base
279357b5d0Sserge-sans-paille "lldb_editline", // m_name
289357b5d0Sserge-sans-paille moduleDocumentation, // m_doc
299357b5d0Sserge-sans-paille -1, // m_size
309357b5d0Sserge-sans-paille nullptr, // m_methods
319357b5d0Sserge-sans-paille nullptr, // m_reload
329357b5d0Sserge-sans-paille nullptr, // m_traverse
339357b5d0Sserge-sans-paille nullptr, // m_clear
349357b5d0Sserge-sans-paille nullptr, // m_free
359357b5d0Sserge-sans-paille };
369357b5d0Sserge-sans-paille
simple_readline(FILE * stdin,FILE * stdout,const char * prompt)3790537673SJonas Devlieghere static char *simple_readline(FILE *stdin, FILE *stdout, const char *prompt) {
389357b5d0Sserge-sans-paille rl_instream = stdin;
399357b5d0Sserge-sans-paille rl_outstream = stdout;
409357b5d0Sserge-sans-paille char *line = readline(prompt);
419357b5d0Sserge-sans-paille if (!line) {
429357b5d0Sserge-sans-paille char *ret = (char *)PyMem_RawMalloc(1);
43*920ffab9SKazu Hirata if (ret != nullptr)
449357b5d0Sserge-sans-paille *ret = '\0';
459357b5d0Sserge-sans-paille return ret;
469357b5d0Sserge-sans-paille }
479357b5d0Sserge-sans-paille if (*line)
489357b5d0Sserge-sans-paille add_history(line);
499357b5d0Sserge-sans-paille int n = strlen(line);
509357b5d0Sserge-sans-paille char *ret = (char *)PyMem_RawMalloc(n + 2);
519357b5d0Sserge-sans-paille if (ret) {
521805d1f8SPavel Labath memcpy(ret, line, n);
539357b5d0Sserge-sans-paille free(line);
549357b5d0Sserge-sans-paille ret[n] = '\n';
559357b5d0Sserge-sans-paille ret[n + 1] = '\0';
569357b5d0Sserge-sans-paille }
579357b5d0Sserge-sans-paille return ret;
589357b5d0Sserge-sans-paille }
599357b5d0Sserge-sans-paille
initlldb_readline(void)609357b5d0Sserge-sans-paille PyMODINIT_FUNC initlldb_readline(void) {
619357b5d0Sserge-sans-paille PyOS_ReadlineFunctionPointer = simple_readline;
629357b5d0Sserge-sans-paille
639357b5d0Sserge-sans-paille return PyModule_Create(&readline_module);
649357b5d0Sserge-sans-paille }
659357b5d0Sserge-sans-paille #endif
66