mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
New mechanism for GNU readline interface, via module
This commit is contained in:
parent
570278be6e
commit
0969d36275
@ -120,6 +120,16 @@ signal signalmodule.c # signal(2)
|
|||||||
|
|
||||||
#*shared*
|
#*shared*
|
||||||
|
|
||||||
|
# GNU readline. Unlike previous Python incarnations, GNU readline is
|
||||||
|
# now incorporated in an optional module, configured in the Setup file
|
||||||
|
# instead of by a configure script switch. You may have to insert a
|
||||||
|
# -L option pointing to the directory where libreadline.* lives,
|
||||||
|
# and you may have to change -ltermcap to -ltermlib or perhaps remove
|
||||||
|
# it, depending on your system -- see the GNU readline instructions.
|
||||||
|
# It's okay for this to be a shared library, too.
|
||||||
|
|
||||||
|
#readline readline.c -lreadline -ltermcap
|
||||||
|
|
||||||
|
|
||||||
# Modules that should always be present (non UNIX dependent):
|
# Modules that should always be present (non UNIX dependent):
|
||||||
|
|
||||||
|
@ -1428,11 +1428,9 @@ static PyMethodDef moduleMethods[] =
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef WITH_READLINE
|
|
||||||
static int
|
static int
|
||||||
EventHook()
|
EventHook()
|
||||||
{
|
{
|
||||||
/* XXX Reset tty */
|
|
||||||
if (errorInCmd) {
|
if (errorInCmd) {
|
||||||
errorInCmd = 0;
|
errorInCmd = 0;
|
||||||
PyErr_Restore(excInCmd, valInCmd, trbInCmd);
|
PyErr_Restore(excInCmd, valInCmd, trbInCmd);
|
||||||
@ -1443,7 +1441,6 @@ EventHook()
|
|||||||
Tcl_DoOneEvent(TCL_DONT_WAIT);
|
Tcl_DoOneEvent(TCL_DONT_WAIT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WITH_READLINE */
|
|
||||||
|
|
||||||
|
|
||||||
/* all errors will be checked in one fell swoop in init_tkinter() */
|
/* all errors will be checked in one fell swoop in init_tkinter() */
|
||||||
@ -1476,9 +1473,7 @@ ins_string(d, name, val)
|
|||||||
void
|
void
|
||||||
init_tkinter()
|
init_tkinter()
|
||||||
{
|
{
|
||||||
#ifdef WITH_READLINE
|
extern int (*Py_input_hook) ();
|
||||||
extern int (*rl_event_hook) ();
|
|
||||||
#endif /* WITH_READLINE */
|
|
||||||
PyObject *m, *d;
|
PyObject *m, *d;
|
||||||
|
|
||||||
Tkapp_Type.ob_type = &PyType_Type;
|
Tkapp_Type.ob_type = &PyType_Type;
|
||||||
@ -1502,9 +1497,8 @@ init_tkinter()
|
|||||||
ins_string(d, "TK_VERSION", TK_VERSION);
|
ins_string(d, "TK_VERSION", TK_VERSION);
|
||||||
ins_string(d, "TCL_VERSION", TCL_VERSION);
|
ins_string(d, "TCL_VERSION", TCL_VERSION);
|
||||||
|
|
||||||
#ifdef WITH_READLINE
|
if (Py_input_hook == NULL)
|
||||||
rl_event_hook = EventHook;
|
Py_input_hook = EventHook;
|
||||||
#endif /* WITH_READLINE */
|
|
||||||
|
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
Py_FatalError("can't initialize module _tkinter");
|
Py_FatalError("can't initialize module _tkinter");
|
||||||
|
122
Modules/readline.c
Normal file
122
Modules/readline.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/* The readline module makes GNU readline available to Python. It
|
||||||
|
* has ideas contributed by Lee Busby, LLNL, and William Magro,
|
||||||
|
* Cornell Theory Center.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Python.h"
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* Routines needed from outside (but not declared in a header file). */
|
||||||
|
extern int (*Py_input_hook)();
|
||||||
|
extern char *readline();
|
||||||
|
extern int rl_initialize();
|
||||||
|
extern int rl_insert();
|
||||||
|
extern int rl_bind_key();
|
||||||
|
extern void add_history();
|
||||||
|
extern char *rl_readline_name;
|
||||||
|
extern int (*rl_event_hook)();
|
||||||
|
extern char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));
|
||||||
|
|
||||||
|
/* This module's initialization routine */
|
||||||
|
void initreadline (void);
|
||||||
|
|
||||||
|
static void PyOS_ReadlineInit();
|
||||||
|
static RETSIGTYPE onintr();
|
||||||
|
static char *PyOS_GnuReadline();
|
||||||
|
static jmp_buf jbuf;
|
||||||
|
static PyObject *ReadlineError;
|
||||||
|
static int already_initialized = 0;
|
||||||
|
static char readline_module_documentation[] =
|
||||||
|
"Readline Module, version0.0"
|
||||||
|
;
|
||||||
|
|
||||||
|
static struct PyMethodDef readline_methods[] =
|
||||||
|
{
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
|
||||||
|
|
||||||
|
/* Initialize the module. Actually, that's all you can or need to do. */
|
||||||
|
void initreadline (void)
|
||||||
|
{
|
||||||
|
PyObject *m, *d;
|
||||||
|
|
||||||
|
if (already_initialized)
|
||||||
|
return;
|
||||||
|
m = Py_InitModule4 ("readline", readline_methods,
|
||||||
|
readline_module_documentation,
|
||||||
|
(PyObject *) 0, PYTHON_API_VERSION);
|
||||||
|
d = PyModule_GetDict (m);
|
||||||
|
ReadlineError = PyString_FromString ("Readline.error");
|
||||||
|
PyDict_SetItemString (d, "error", ReadlineError);
|
||||||
|
if (PyErr_Occurred ()) {
|
||||||
|
Py_FatalError ("Cannot initialize module readline");
|
||||||
|
}
|
||||||
|
if (isatty(fileno(stdin))){
|
||||||
|
PyOS_ReadlineFunctionPointer = PyOS_GnuReadline;
|
||||||
|
PyOS_ReadlineInit();
|
||||||
|
}
|
||||||
|
already_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static RETSIGTYPE
|
||||||
|
onintr(sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
longjmp(jbuf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
PyOS_ReadlineInit()
|
||||||
|
{
|
||||||
|
/* Force rebind of TAB to insert-tab */
|
||||||
|
rl_readline_name = "python";
|
||||||
|
rl_initialize();
|
||||||
|
rl_bind_key('\t', rl_insert);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
PyOS_GnuReadline(prompt)
|
||||||
|
char *prompt;
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
char *p;
|
||||||
|
RETSIGTYPE (*old_inthandler)();
|
||||||
|
old_inthandler = signal(SIGINT, onintr);
|
||||||
|
if (setjmp(jbuf)) {
|
||||||
|
#ifdef HAVE_SIGRELSE
|
||||||
|
/* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
|
||||||
|
sigrelse(SIGINT);
|
||||||
|
#endif
|
||||||
|
signal(SIGINT, old_inthandler);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rl_event_hook = Py_input_hook;
|
||||||
|
p = readline(prompt);
|
||||||
|
signal(SIGINT, old_inthandler);
|
||||||
|
if (p == NULL) {
|
||||||
|
p = malloc(1);
|
||||||
|
if (p != NULL)
|
||||||
|
*p = '\0';
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
n = strlen(p);
|
||||||
|
if (n > 0)
|
||||||
|
add_history(p);
|
||||||
|
if ((p = realloc(p, n+2)) != NULL) {
|
||||||
|
p[n] = '\n';
|
||||||
|
p[n+1] = '\0';
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user