]> granicus.if.org Git - python/commitdiff
New mechanism for GNU readline interface, via module
authorGuido van Rossum <guido@python.org>
Tue, 5 Aug 1997 21:27:50 +0000 (21:27 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 5 Aug 1997 21:27:50 +0000 (21:27 +0000)
Modules/Setup.in
Modules/_tkinter.c
Modules/readline.c [new file with mode: 0644]

index 6acfa885e62542e2bd67edf49a9ccb7acd25f762..bb06b11ab7a23c5cb3714bcd2510bb1c2ca7744a 100644 (file)
@@ -120,6 +120,16 @@ signal signalmodule.c              # signal(2)
 
 #*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):
 
index 528c2296a815824a1b194be43111c1e6a0c7c76f..1f32c4a492fffb86bab3891a5349ef454e66959d 100644 (file)
@@ -1428,11 +1428,9 @@ static PyMethodDef moduleMethods[] =
        {NULL,                 NULL}
 };
 
-#ifdef WITH_READLINE
 static int
 EventHook()
 {
-       /* XXX Reset tty */
        if (errorInCmd) {
                errorInCmd = 0;
                PyErr_Restore(excInCmd, valInCmd, trbInCmd);
@@ -1443,7 +1441,6 @@ EventHook()
                Tcl_DoOneEvent(TCL_DONT_WAIT);
        return 0;
 }
-#endif /* WITH_READLINE */
 
 
 /* all errors will be checked in one fell swoop in init_tkinter() */
@@ -1476,9 +1473,7 @@ ins_string(d, name, val)
 void
 init_tkinter()
 {
-#ifdef WITH_READLINE
-       extern int (*rl_event_hook) ();
-#endif /* WITH_READLINE */
+       extern int (*Py_input_hook) ();
        PyObject *m, *d;
 
        Tkapp_Type.ob_type = &PyType_Type;
@@ -1502,9 +1497,8 @@ init_tkinter()
        ins_string(d, "TK_VERSION", TK_VERSION);
        ins_string(d, "TCL_VERSION", TCL_VERSION);
 
-#ifdef WITH_READLINE
-       rl_event_hook = EventHook;
-#endif /* WITH_READLINE */
+       if (Py_input_hook == NULL)
+               Py_input_hook = EventHook;
 
        if (PyErr_Occurred())
                Py_FatalError("can't initialize module _tkinter");
diff --git a/Modules/readline.c b/Modules/readline.c
new file mode 100644 (file)
index 0000000..8927630
--- /dev/null
@@ -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