19357b5d0Sserge-sans-paille #include "PythonReadline.h" 29357b5d0Sserge-sans-paille 39357b5d0Sserge-sans-paille #ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE 49357b5d0Sserge-sans-paille 5*76e47d48SRaphael 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 #if PY_MAJOR_VERSION >= 3 269357b5d0Sserge-sans-paille static struct PyModuleDef readline_module = { 279357b5d0Sserge-sans-paille PyModuleDef_HEAD_INIT, // m_base 289357b5d0Sserge-sans-paille "lldb_editline", // m_name 299357b5d0Sserge-sans-paille moduleDocumentation, // m_doc 309357b5d0Sserge-sans-paille -1, // m_size 319357b5d0Sserge-sans-paille nullptr, // m_methods 329357b5d0Sserge-sans-paille nullptr, // m_reload 339357b5d0Sserge-sans-paille nullptr, // m_traverse 349357b5d0Sserge-sans-paille nullptr, // m_clear 359357b5d0Sserge-sans-paille nullptr, // m_free 369357b5d0Sserge-sans-paille }; 379357b5d0Sserge-sans-paille #else 389357b5d0Sserge-sans-paille static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}}; 399357b5d0Sserge-sans-paille #endif 409357b5d0Sserge-sans-paille 419357b5d0Sserge-sans-paille static char * 429357b5d0Sserge-sans-paille #if PY_MAJOR_VERSION >= 3 439357b5d0Sserge-sans-paille simple_readline(FILE *stdin, FILE *stdout, const char *prompt) 449357b5d0Sserge-sans-paille #else 459357b5d0Sserge-sans-paille simple_readline(FILE *stdin, FILE *stdout, char *prompt) 469357b5d0Sserge-sans-paille #endif 479357b5d0Sserge-sans-paille { 489357b5d0Sserge-sans-paille rl_instream = stdin; 499357b5d0Sserge-sans-paille rl_outstream = stdout; 509357b5d0Sserge-sans-paille char *line = readline(prompt); 519357b5d0Sserge-sans-paille if (!line) { 52d5904988Sserge-sans-paille #if PY_MAJOR_VERSION >= 3 539357b5d0Sserge-sans-paille char *ret = (char *)PyMem_RawMalloc(1); 54d5904988Sserge-sans-paille #else 55d5904988Sserge-sans-paille char *ret = (char *)PyMem_Malloc(1); 56d5904988Sserge-sans-paille #endif 579357b5d0Sserge-sans-paille if (ret != NULL) 589357b5d0Sserge-sans-paille *ret = '\0'; 599357b5d0Sserge-sans-paille return ret; 609357b5d0Sserge-sans-paille } 619357b5d0Sserge-sans-paille if (*line) 629357b5d0Sserge-sans-paille add_history(line); 639357b5d0Sserge-sans-paille int n = strlen(line); 64d5904988Sserge-sans-paille #if PY_MAJOR_VERSION >= 3 659357b5d0Sserge-sans-paille char *ret = (char *)PyMem_RawMalloc(n + 2); 66d5904988Sserge-sans-paille #else 67d5904988Sserge-sans-paille char *ret = (char *)PyMem_Malloc(n + 2); 68d5904988Sserge-sans-paille #endif 699357b5d0Sserge-sans-paille if (ret) { 701805d1f8SPavel Labath memcpy(ret, line, n); 719357b5d0Sserge-sans-paille free(line); 729357b5d0Sserge-sans-paille ret[n] = '\n'; 739357b5d0Sserge-sans-paille ret[n + 1] = '\0'; 749357b5d0Sserge-sans-paille } 759357b5d0Sserge-sans-paille return ret; 769357b5d0Sserge-sans-paille } 779357b5d0Sserge-sans-paille 789357b5d0Sserge-sans-paille PyMODINIT_FUNC initlldb_readline(void) { 799357b5d0Sserge-sans-paille PyOS_ReadlineFunctionPointer = simple_readline; 809357b5d0Sserge-sans-paille 819357b5d0Sserge-sans-paille #if PY_MAJOR_VERSION >= 3 829357b5d0Sserge-sans-paille return PyModule_Create(&readline_module); 839357b5d0Sserge-sans-paille #else 84d5904988Sserge-sans-paille Py_InitModule4("readline", moduleMethods, moduleDocumentation, 859357b5d0Sserge-sans-paille static_cast<PyObject *>(NULL), PYTHON_API_VERSION); 869357b5d0Sserge-sans-paille #endif 879357b5d0Sserge-sans-paille } 889357b5d0Sserge-sans-paille #endif 89