Commit fbd64c87 authored by Guido van Rossum's avatar Guido van Rossum

Restructured quite a bit, hopefully Lee Busby will find this useful.

Also grandly renamed.

Here's the new interface:

When WITH_READLINE is defined, two functions are defined:

  - PyOS_GnuReadline (what used to be my_readline() with WITH_READLINE)
  - PyOS_ReadlineInit (for Dave Ascher)

Always, these functions are defined:

  - PyOS_StdioReadline (what used to be my_readline() without WITH_READLINE)
  - PyOS_Readline (the interface used by tokenizer.c and [raw_]input().

There's a global function pointer PyOS_ReadlineFunctionPointer,
initialized to NULL.  When PyOS_Readline finds this to be NULL, it
sets it to either PyOS_GnuReadline or PyOS_StdioReadline depending on
which one makes more sense (i.e. it uses GNU only if it is defined
*and* stdin is indeed a tty device).

An embedding program that has its own wishes can set the function
pointer to a function of its own design.  It should take a char*
prompt argument (which may be NULL) and return a string *ending in a
\n character* -- or "" for EOF or NULL for a user interrupt.

--Guido van Rossum (home page: http://www.python.org/~guido/)
parent 384d2490
...@@ -29,16 +29,18 @@ PERFORMANCE OF THIS SOFTWARE. ...@@ -29,16 +29,18 @@ PERFORMANCE OF THIS SOFTWARE.
******************************************************************/ ******************************************************************/
/* Readline interface for tokenizer.c. /* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
By default, we have a super simple my_readline function. By default, or when stdin is not a tty device, we have a super
Optionally, we can use the GNU readline library (to be found in the simple my_readline function using fgets.
bash distribution). Optionally, we can use the GNU readline library.
my_readline() has a different return value from GNU readline(): my_readline() has a different return value from GNU readline():
- NULL if an interrupt occurred or if an error occurred - NULL if an interrupt occurred or if an error occurred
- a malloc'ed empty string if EOF was read - a malloc'ed empty string if EOF was read
- a malloc'ed string ending in \n normally - a malloc'ed string ending in \n normally
*/ */
#define Py_USE_NEW_NAMES 1
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
...@@ -49,6 +51,7 @@ PERFORMANCE OF THIS SOFTWARE. ...@@ -49,6 +51,7 @@ PERFORMANCE OF THIS SOFTWARE.
#include "mymalloc.h" #include "mymalloc.h"
#include "intrcheck.h" #include "intrcheck.h"
#ifdef WITH_READLINE #ifdef WITH_READLINE
extern char *readline(); extern char *readline();
...@@ -71,46 +74,6 @@ onintr(sig) ...@@ -71,46 +74,6 @@ onintr(sig)
longjmp(jbuf, 1); longjmp(jbuf, 1);
} }
#else /* !WITH_READLINE */
/* This function restarts a fgets() after an EINTR error occurred
except if intrcheck() returns true. */
static int
my_fgets(buf, len, fp)
char *buf;
int len;
FILE *fp;
{
char *p;
for (;;) {
errno = 0;
p = fgets(buf, len, fp);
if (p != NULL)
return 0; /* No error */
if (feof(fp)) {
return -1; /* EOF */
}
#ifdef EINTR
if (errno == EINTR) {
if (intrcheck()) {
return 1; /* Interrupt */
}
continue;
}
#endif
if (intrcheck()) {
return 1; /* Interrupt */
}
return -2; /* Error */
}
/* NOTREACHED */
}
#endif /* WITH_READLINE */
#ifdef WITH_READLINE
void void
PyOS_ReadlineInit() PyOS_ReadlineInit()
{ {
...@@ -123,16 +86,13 @@ PyOS_ReadlineInit() ...@@ -123,16 +86,13 @@ PyOS_ReadlineInit()
been_here++; been_here++;
} }
} }
#endif
char * char *
my_readline(prompt) PyOS_GnuReadline(prompt)
char *prompt; char *prompt;
{ {
int n; int n;
char *p; char *p;
#ifdef WITH_READLINE
RETSIGTYPE (*old_inthandler)(); RETSIGTYPE (*old_inthandler)();
PyOS_ReadlineInit(); PyOS_ReadlineInit();
old_inthandler = signal(SIGINT, onintr); old_inthandler = signal(SIGINT, onintr);
...@@ -160,7 +120,54 @@ my_readline(prompt) ...@@ -160,7 +120,54 @@ my_readline(prompt)
p[n+1] = '\0'; p[n+1] = '\0';
} }
return p; return p;
#else /* !WITH_READLINE */ }
#endif /* !WITH_READLINE */
/* This function restarts a fgets() after an EINTR error occurred
except if PyOS_InterruptOccurred() returns true. */
static int
my_fgets(buf, len, fp)
char *buf;
int len;
FILE *fp;
{
char *p;
for (;;) {
errno = 0;
p = fgets(buf, len, fp);
if (p != NULL)
return 0; /* No error */
if (feof(fp)) {
return -1; /* EOF */
}
#ifdef EINTR
if (errno == EINTR) {
if (PyOS_InterruptOccurred()) {
return 1; /* Interrupt */
}
continue;
}
#endif
if (PyOS_InterruptOccurred()) {
return 1; /* Interrupt */
}
return -2; /* Error */
}
/* NOTREACHED */
}
/* Readline implementation using fgets() */
char *
PyOS_StdioReadline(prompt)
char *prompt;
{
int n;
char *p;
n = 100; n = 100;
if ((p = malloc(n)) == NULL) if ((p = malloc(n)) == NULL)
return NULL; return NULL;
...@@ -198,5 +205,30 @@ my_readline(prompt) ...@@ -198,5 +205,30 @@ my_readline(prompt)
n += strlen(p+n); n += strlen(p+n);
} }
return realloc(p, n+1); return realloc(p, n+1);
#endif /* !WITH_READLINE */ }
/* By initializing this function pointer, systems embedding Python can
override the readline function. */
char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *));
/* Interface used by tokenizer.c and bltinmodule.c */
char *
PyOS_Readline(prompt)
char *prompt;
{
int n;
char *p;
if (PyOS_ReadlineFunctionPointer == NULL) {
#ifdef WITH_READLINE
if (isatty(fileno(stdin)))
PyOS_ReadlineFunctionPointer = PyOS_GnuReadline;
else
#endif
PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
}
return (*PyOS_ReadlineFunctionPointer)(prompt);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment