Apparently the code to forestall Tk eating events was too aggressive (Tk user input...
[python/dscho.git] / Parser / myreadline.c
blob10e39e53685b8edf629af75269e67d2406a7c3a8
2 /* 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.
6 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
12 #include "Python.h"
14 int (*PyOS_InputHook)(void) = NULL;
16 #ifdef RISCOS
17 int Py_RISCOSWimpFlag;
18 #endif
20 /* This function restarts a fgets() after an EINTR error occurred
21 except if PyOS_InterruptOccurred() returns true. */
23 static int
24 my_fgets(char *buf, int len, FILE *fp)
26 char *p;
27 for (;;) {
28 if (PyOS_InputHook != NULL)
29 (void)(PyOS_InputHook)();
30 errno = 0;
31 p = fgets(buf, len, fp);
32 if (p != NULL)
33 return 0; /* No error */
34 if (feof(fp)) {
35 return -1; /* EOF */
37 #ifdef EINTR
38 if (errno == EINTR) {
39 if (PyOS_InterruptOccurred()) {
40 return 1; /* Interrupt */
42 continue;
44 #endif
45 if (PyOS_InterruptOccurred()) {
46 return 1; /* Interrupt */
48 return -2; /* Error */
50 /* NOTREACHED */
54 /* Readline implementation using fgets() */
56 char *
57 PyOS_StdioReadline(char *prompt)
59 size_t n;
60 char *p;
61 n = 100;
62 if ((p = PyMem_MALLOC(n)) == NULL)
63 return NULL;
64 fflush(stdout);
65 #ifndef RISCOS
66 if (prompt)
67 fprintf(stderr, "%s", prompt);
68 #else
69 if (prompt) {
70 if(Py_RISCOSWimpFlag)
71 fprintf(stderr, "\x0cr%s\x0c", prompt);
72 else
73 fprintf(stderr, "%s", prompt);
75 #endif
76 fflush(stderr);
77 switch (my_fgets(p, (int)n, stdin)) {
78 case 0: /* Normal case */
79 break;
80 case 1: /* Interrupt */
81 PyMem_FREE(p);
82 return NULL;
83 case -1: /* EOF */
84 case -2: /* Error */
85 default: /* Shouldn't happen */
86 *p = '\0';
87 break;
89 #ifdef MPW
90 /* Hack for MPW C where the prompt comes right back in the input */
91 /* XXX (Actually this would be rather nice on most systems...) */
92 n = strlen(prompt);
93 if (strncmp(p, prompt, n) == 0)
94 memmove(p, p + n, strlen(p) - n + 1);
95 #endif
96 n = strlen(p);
97 while (n > 0 && p[n-1] != '\n') {
98 size_t incr = n+2;
99 p = PyMem_REALLOC(p, n + incr);
100 if (p == NULL)
101 return NULL;
102 if (incr > INT_MAX) {
103 PyErr_SetString(PyExc_OverflowError, "input line too long");
105 if (my_fgets(p+n, (int)incr, stdin) != 0)
106 break;
107 n += strlen(p+n);
109 return PyMem_REALLOC(p, n+1);
113 /* By initializing this function pointer, systems embedding Python can
114 override the readline function.
116 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
118 char *(*PyOS_ReadlineFunctionPointer)(char *);
121 /* Interface used by tokenizer.c and bltinmodule.c */
123 char *
124 PyOS_Readline(char *prompt)
126 char *rv;
127 if (PyOS_ReadlineFunctionPointer == NULL) {
128 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
130 Py_BEGIN_ALLOW_THREADS
131 rv = (*PyOS_ReadlineFunctionPointer)(prompt);
132 Py_END_ALLOW_THREADS
133 return rv;