Skip to content

Commit e59c3ba

Browse files
committed
New mechanism for GNU readline interface, via module
1 parent 1f9d022 commit e59c3ba

File tree

3 files changed

+135
-9
lines changed

3 files changed

+135
-9
lines changed

‎Modules/Setup.in‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,16 @@ signal signalmodule.c # signal(2)
120120

121121
#*shared*
122122

123+
# GNU readline. Unlike previous Python incarnations, GNU readline is
124+
# now incorporated in an optional module, configured in the Setup file
125+
# instead of by a configure script switch. You may have to insert a
126+
# -L option pointing to the directory where libreadline.* lives,
127+
# and you may have to change -ltermcap to -ltermlib or perhaps remove
128+
# it, depending on your system -- see the GNU readline instructions.
129+
# It's okay for this to be a shared library, too.
130+
131+
#readline readline.c -lreadline -ltermcap
132+
123133

124134
# Modules that should always be present (non UNIX dependent):
125135

‎Modules/_tkinter.c‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,11 +1428,9 @@ static PyMethodDef moduleMethods[] =
14281428
{NULL, NULL}
14291429
};
14301430

1431-
#ifdef WITH_READLINE
14321431
static int
14331432
EventHook()
14341433
{
1435-
/* XXX Reset tty */
14361434
if (errorInCmd) {
14371435
errorInCmd = 0;
14381436
PyErr_Restore(excInCmd, valInCmd, trbInCmd);
@@ -1443,7 +1441,6 @@ EventHook()
14431441
Tcl_DoOneEvent(TCL_DONT_WAIT);
14441442
return 0;
14451443
}
1446-
#endif /* WITH_READLINE */
14471444

14481445

14491446
/* all errors will be checked in one fell swoop in init_tkinter() */
@@ -1476,9 +1473,7 @@ ins_string(d, name, val)
14761473
void
14771474
init_tkinter()
14781475
{
1479-
#ifdef WITH_READLINE
1480-
extern int (*rl_event_hook) ();
1481-
#endif /* WITH_READLINE */
1476+
extern int (*Py_input_hook) ();
14821477
PyObject *m, *d;
14831478

14841479
Tkapp_Type.ob_type = &PyType_Type;
@@ -1502,9 +1497,8 @@ init_tkinter()
15021497
ins_string(d, "TK_VERSION", TK_VERSION);
15031498
ins_string(d, "TCL_VERSION", TCL_VERSION);
15041499

1505-
#ifdef WITH_READLINE
1506-
rl_event_hook = EventHook;
1507-
#endif /* WITH_READLINE */
1500+
if (Py_input_hook == NULL)
1501+
Py_input_hook = EventHook;
15081502

15091503
if (PyErr_Occurred())
15101504
Py_FatalError("can't initialize module _tkinter");

‎Modules/readline.c‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/* The readline module makes GNU readline available to Python. It
2+
* has ideas contributed by Lee Busby, LLNL, and William Magro,
3+
* Cornell Theory Center.
4+
*/
5+
6+
#ifdef __cplusplus
7+
extern "C" {
8+
#endif
9+
10+
#include "Python.h"
11+
#include <setjmp.h>
12+
#include <signal.h>
13+
14+
/* Routines needed from outside (but not declared in a header file). */
15+
extern int (*Py_input_hook)();
16+
extern char *readline();
17+
extern int rl_initialize();
18+
extern int rl_insert();
19+
extern int rl_bind_key();
20+
extern void add_history();
21+
extern char *rl_readline_name;
22+
extern int (*rl_event_hook)();
23+
extern char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));
24+
25+
/* This module's initialization routine */
26+
void initreadline (void);
27+
28+
static void PyOS_ReadlineInit();
29+
static RETSIGTYPE onintr();
30+
static char *PyOS_GnuReadline();
31+
static jmp_buf jbuf;
32+
static PyObject *ReadlineError;
33+
static int already_initialized = 0;
34+
static char readline_module_documentation[] =
35+
"Readline Module, version0.0"
36+
;
37+
38+
static struct PyMethodDef readline_methods[] =
39+
{
40+
{ 0, 0 }
41+
};
42+
43+
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
44+
45+
/* Initialize the module. Actually, that's all you can or need to do. */
46+
void initreadline (void)
47+
{
48+
PyObject *m, *d;
49+
50+
if (already_initialized)
51+
return;
52+
m = Py_InitModule4 ("readline", readline_methods,
53+
readline_module_documentation,
54+
(PyObject *) 0, PYTHON_API_VERSION);
55+
d = PyModule_GetDict (m);
56+
ReadlineError = PyString_FromString ("Readline.error");
57+
PyDict_SetItemString (d, "error", ReadlineError);
58+
if (PyErr_Occurred ()) {
59+
Py_FatalError ("Cannot initialize module readline");
60+
}
61+
if (isatty(fileno(stdin))){
62+
PyOS_ReadlineFunctionPointer = PyOS_GnuReadline;
63+
PyOS_ReadlineInit();
64+
}
65+
already_initialized = 1;
66+
}
67+
68+
/* ARGSUSED */
69+
static RETSIGTYPE
70+
onintr(sig)
71+
int sig;
72+
{
73+
longjmp(jbuf, 1);
74+
}
75+
76+
static void
77+
PyOS_ReadlineInit()
78+
{
79+
/* Force rebind of TAB to insert-tab */
80+
rl_readline_name = "python";
81+
rl_initialize();
82+
rl_bind_key('\t', rl_insert);
83+
}
84+
85+
static char *
86+
PyOS_GnuReadline(prompt)
87+
char *prompt;
88+
{
89+
int n;
90+
char *p;
91+
RETSIGTYPE (*old_inthandler)();
92+
old_inthandler = signal(SIGINT, onintr);
93+
if (setjmp(jbuf)) {
94+
#ifdef HAVE_SIGRELSE
95+
/* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
96+
sigrelse(SIGINT);
97+
#endif
98+
signal(SIGINT, old_inthandler);
99+
return NULL;
100+
}
101+
rl_event_hook = Py_input_hook;
102+
p = readline(prompt);
103+
signal(SIGINT, old_inthandler);
104+
if (p == NULL) {
105+
p = malloc(1);
106+
if (p != NULL)
107+
*p = '\0';
108+
return p;
109+
}
110+
n = strlen(p);
111+
if (n > 0)
112+
add_history(p);
113+
if ((p = realloc(p, n+2)) != NULL) {
114+
p[n] = '\n';
115+
p[n+1] = '\0';
116+
}
117+
return p;
118+
}
119+
120+
#ifdef __cplusplus
121+
}
122+
#endif

0 commit comments

Comments
 (0)