You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.4 KiB
89 lines
2.4 KiB
4 months ago
|
#include "PythonReadline.h"
|
||
|
|
||
|
#ifdef LLDB_USE_LIBEDIT_READLINE_COMPAT_MODULE
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#include <editline/readline.h>
|
||
|
|
||
|
// Simple implementation of the Python readline module using libedit.
|
||
|
// In the event that libedit is excluded from the build, this turns
|
||
|
// back into a null implementation that blocks the module from pulling
|
||
|
// in the GNU readline shared lib, which causes linkage confusion when
|
||
|
// both readline and libedit's readline compatibility symbols collide.
|
||
|
//
|
||
|
// Currently it only installs a PyOS_ReadlineFunctionPointer, without
|
||
|
// implementing any of the readline module methods. This is meant to
|
||
|
// work around LLVM pr18841 to avoid seg faults in the stock Python
|
||
|
// readline.so linked against GNU readline.
|
||
|
//
|
||
|
// Bug on the cpython side: https://bugs.python.org/issue38634
|
||
|
|
||
|
PyDoc_STRVAR(moduleDocumentation,
|
||
|
"Simple readline module implementation based on libedit.");
|
||
|
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
static struct PyModuleDef readline_module = {
|
||
|
PyModuleDef_HEAD_INIT, // m_base
|
||
|
"lldb_editline", // m_name
|
||
|
moduleDocumentation, // m_doc
|
||
|
-1, // m_size
|
||
|
nullptr, // m_methods
|
||
|
nullptr, // m_reload
|
||
|
nullptr, // m_traverse
|
||
|
nullptr, // m_clear
|
||
|
nullptr, // m_free
|
||
|
};
|
||
|
#else
|
||
|
static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}};
|
||
|
#endif
|
||
|
|
||
|
static char *
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
|
||
|
#else
|
||
|
simple_readline(FILE *stdin, FILE *stdout, char *prompt)
|
||
|
#endif
|
||
|
{
|
||
|
rl_instream = stdin;
|
||
|
rl_outstream = stdout;
|
||
|
char *line = readline(prompt);
|
||
|
if (!line) {
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
char *ret = (char *)PyMem_RawMalloc(1);
|
||
|
#else
|
||
|
char *ret = (char *)PyMem_Malloc(1);
|
||
|
#endif
|
||
|
if (ret != NULL)
|
||
|
*ret = '\0';
|
||
|
return ret;
|
||
|
}
|
||
|
if (*line)
|
||
|
add_history(line);
|
||
|
int n = strlen(line);
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
char *ret = (char *)PyMem_RawMalloc(n + 2);
|
||
|
#else
|
||
|
char *ret = (char *)PyMem_Malloc(n + 2);
|
||
|
#endif
|
||
|
if (ret) {
|
||
|
memcpy(ret, line, n);
|
||
|
free(line);
|
||
|
ret[n] = '\n';
|
||
|
ret[n + 1] = '\0';
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
PyMODINIT_FUNC initlldb_readline(void) {
|
||
|
PyOS_ReadlineFunctionPointer = simple_readline;
|
||
|
|
||
|
#if PY_MAJOR_VERSION >= 3
|
||
|
return PyModule_Create(&readline_module);
|
||
|
#else
|
||
|
Py_InitModule4("readline", moduleMethods, moduleDocumentation,
|
||
|
static_cast<PyObject *>(NULL), PYTHON_API_VERSION);
|
||
|
#endif
|
||
|
}
|
||
|
#endif
|