blob: 6451824ede05d305b3f439b4ce66bfe62404e7ce [file] [log] [blame]
Guido van Rossum6fa63431993-12-24 10:36:57 +00001
Guido van Rossumfbd64c81997-02-18 21:53:32 +00002/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
3 By default, or when stdin is not a tty device, we have a super
4 simple my_readline function using fgets.
5 Optionally, we can use the GNU readline library.
Guido van Rossum6fa63431993-12-24 10:36:57 +00006 my_readline() has a different return value from GNU readline():
7 - NULL if an interrupt occurred or if an error occurred
8 - a malloc'ed empty string if EOF was read
9 - a malloc'ed string ending in \n normally
10*/
11
Guido van Rossum8efa47b1998-08-27 19:43:43 +000012#include "Python.h"
Jack Jansen41aa8e52000-07-03 21:39:47 +000013#ifdef HAVE_LIMITS_H
14#include <limits.h>
15#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +000016
Thomas Wouters23c9e002000-07-22 19:20:54 +000017int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000018
19/* This function restarts a fgets() after an EINTR error occurred
20 except if PyOS_InterruptOccurred() returns true. */
21
22static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000023my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000024{
25 char *p;
26 for (;;) {
Guido van Rossum44620641997-08-11 18:57:29 +000027 if (PyOS_InputHook != NULL)
28 (void)(PyOS_InputHook)();
Guido van Rossumfbd64c81997-02-18 21:53:32 +000029 errno = 0;
30 p = fgets(buf, len, fp);
31 if (p != NULL)
32 return 0; /* No error */
33 if (feof(fp)) {
34 return -1; /* EOF */
35 }
36#ifdef EINTR
37 if (errno == EINTR) {
38 if (PyOS_InterruptOccurred()) {
39 return 1; /* Interrupt */
40 }
41 continue;
42 }
43#endif
44 if (PyOS_InterruptOccurred()) {
45 return 1; /* Interrupt */
46 }
47 return -2; /* Error */
48 }
49 /* NOTREACHED */
50}
51
52
53/* Readline implementation using fgets() */
54
55char *
Thomas Wouters23c9e002000-07-22 19:20:54 +000056PyOS_StdioReadline(char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000057{
Guido van Rossum6da34342000-06-28 22:00:02 +000058 size_t n;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000059 char *p;
Guido van Rossum6fa63431993-12-24 10:36:57 +000060 n = 100;
Guido van Rossumb18618d2000-05-03 23:44:39 +000061 if ((p = PyMem_MALLOC(n)) == NULL)
Guido van Rossum6fa63431993-12-24 10:36:57 +000062 return NULL;
Guido van Rossumc7fea2f1996-01-12 01:30:55 +000063 fflush(stdout);
Guido van Rossum6fa63431993-12-24 10:36:57 +000064 if (prompt)
65 fprintf(stderr, "%s", prompt);
Guido van Rossumc7fea2f1996-01-12 01:30:55 +000066 fflush(stderr);
Guido van Rossum6da34342000-06-28 22:00:02 +000067 switch (my_fgets(p, (int)n, stdin)) {
Guido van Rossumb6775db1994-08-01 11:34:53 +000068 case 0: /* Normal case */
69 break;
70 case 1: /* Interrupt */
Guido van Rossumb18618d2000-05-03 23:44:39 +000071 PyMem_FREE(p);
Guido van Rossum6fa63431993-12-24 10:36:57 +000072 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +000073 case -1: /* EOF */
74 case -2: /* Error */
75 default: /* Shouldn't happen */
76 *p = '\0';
77 break;
Guido van Rossum6fa63431993-12-24 10:36:57 +000078 }
Guido van Rossumb6775db1994-08-01 11:34:53 +000079#ifdef MPW
80 /* Hack for MPW C where the prompt comes right back in the input */
81 /* XXX (Actually this would be rather nice on most systems...) */
82 n = strlen(prompt);
83 if (strncmp(p, prompt, n) == 0)
84 memmove(p, p + n, strlen(p) - n + 1);
85#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +000086 n = strlen(p);
87 while (n > 0 && p[n-1] != '\n') {
Guido van Rossum6da34342000-06-28 22:00:02 +000088 size_t incr = n+2;
Guido van Rossumb18618d2000-05-03 23:44:39 +000089 p = PyMem_REALLOC(p, n + incr);
Guido van Rossum6fa63431993-12-24 10:36:57 +000090 if (p == NULL)
91 return NULL;
Guido van Rossum6da34342000-06-28 22:00:02 +000092 if (incr > INT_MAX) {
93 PyErr_SetString(PyExc_OverflowError, "input line too long");
94 }
95 if (my_fgets(p+n, (int)incr, stdin) != 0)
Guido van Rossum6fa63431993-12-24 10:36:57 +000096 break;
97 n += strlen(p+n);
98 }
Guido van Rossumb18618d2000-05-03 23:44:39 +000099 return PyMem_REALLOC(p, n+1);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000100}
101
102
103/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000104 override the readline function.
105
106 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000107
Tim Petersdbd9ba62000-07-09 03:09:57 +0000108char *(*PyOS_ReadlineFunctionPointer)(char *);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000109
110
111/* Interface used by tokenizer.c and bltinmodule.c */
112
113char *
Thomas Wouters23c9e002000-07-22 19:20:54 +0000114PyOS_Readline(char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000115{
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000116 char *rv;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000117 if (PyOS_ReadlineFunctionPointer == NULL) {
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000118 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
119 }
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000120 Py_BEGIN_ALLOW_THREADS
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000121 rv = (*PyOS_ReadlineFunctionPointer)(prompt);
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000122 Py_END_ALLOW_THREADS
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000123 return rv;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000124}