home *** CD-ROM | disk | FTP | other *** search
-
- /* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
- By default, or when stdin is not a tty device, we have a super
- simple my_readline function using fgets.
- Optionally, we can use the GNU readline library.
- my_readline() has a different return value from GNU readline():
- - NULL if an interrupt occurred or if an error occurred
- - a malloc'ed empty string if EOF was read
- - a malloc'ed string ending in \n normally
- */
-
- #include "Python.h"
-
- int (*PyOS_InputHook)(void) = NULL;
-
- /* This function restarts a fgets() after an EINTR error occurred
- except if PyOS_InterruptOccurred() returns true. */
-
- static int
- my_fgets(char *buf, int len, FILE *fp)
- {
- char *p;
- for (;;) {
- if (PyOS_InputHook != NULL)
- (void)(PyOS_InputHook)();
- 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(char *prompt)
- {
- size_t n;
- char *p;
- n = 100;
- if ((p = PyMem_MALLOC(n)) == NULL)
- return NULL;
- fflush(stdout);
- if (prompt)
- fprintf(stderr, "%s", prompt);
- fflush(stderr);
- switch (my_fgets(p, (int)n, stdin)) {
- case 0: /* Normal case */
- break;
- case 1: /* Interrupt */
- PyMem_FREE(p);
- return NULL;
- case -1: /* EOF */
- case -2: /* Error */
- default: /* Shouldn't happen */
- *p = '\0';
- break;
- }
- #ifdef MPW
- /* Hack for MPW C where the prompt comes right back in the input */
- /* XXX (Actually this would be rather nice on most systems...) */
- n = strlen(prompt);
- if (strncmp(p, prompt, n) == 0)
- memmove(p, p + n, strlen(p) - n + 1);
- #endif
- n = strlen(p);
- while (n > 0 && p[n-1] != '\n') {
- size_t incr = n+2;
- p = PyMem_REALLOC(p, n + incr);
- if (p == NULL)
- return NULL;
- if (incr > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError, "input line too long");
- }
- if (my_fgets(p+n, (int)incr, stdin) != 0)
- break;
- n += strlen(p+n);
- }
- return PyMem_REALLOC(p, n+1);
- }
-
-
- /* By initializing this function pointer, systems embedding Python can
- override the readline function.
-
- Note: Python expects in return a buffer allocated with PyMem_Malloc. */
-
- char *(*PyOS_ReadlineFunctionPointer)(char *);
-
-
- /* Interface used by tokenizer.c and bltinmodule.c */
-
- char *
- PyOS_Readline(char *prompt)
- {
- char *rv;
- if (PyOS_ReadlineFunctionPointer == NULL) {
- PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
- }
- Py_BEGIN_ALLOW_THREADS
- rv = (*PyOS_ReadlineFunctionPointer)(prompt);
- Py_END_ALLOW_THREADS
- return rv;
- }
-