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