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