blob: 8fe25ecb8fe3c7ffdf9efb39a1b188ef4d4bd863 [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"
Mark Hammond2f10cb82002-07-14 23:12:29 +000013#ifdef MS_WINDOWS
14#define WIN32_LEAN_AND_MEAN
15#include "windows.h"
16#endif /* MS_WINDOWS */
Guido van Rossum6fa63431993-12-24 10:36:57 +000017
Thomas Wouters23c9e002000-07-22 19:20:54 +000018int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000019
Guido van Rossum48a680c2001-03-02 06:34:14 +000020#ifdef RISCOS
21int Py_RISCOSWimpFlag;
22#endif
23
Guido van Rossumfbd64c81997-02-18 21:53:32 +000024/* This function restarts a fgets() after an EINTR error occurred
25 except if PyOS_InterruptOccurred() returns true. */
26
27static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000028my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000029{
30 char *p;
31 for (;;) {
Guido van Rossum44620641997-08-11 18:57:29 +000032 if (PyOS_InputHook != NULL)
33 (void)(PyOS_InputHook)();
Guido van Rossumfbd64c81997-02-18 21:53:32 +000034 errno = 0;
35 p = fgets(buf, len, fp);
36 if (p != NULL)
37 return 0; /* No error */
Mark Hammond2f10cb82002-07-14 23:12:29 +000038#ifdef MS_WINDOWS
39 /* In the case of a Ctrl+C or some other external event
40 interrupting the operation:
41 Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
42 error code (and feof() returns TRUE).
43 Win9x: Ctrl+C seems to have no effect on fgets() returning
44 early - the signal handler is called, but the fgets()
45 only returns "normally" (ie, when Enter hit or feof())
46 */
47 if (GetLastError()==ERROR_OPERATION_ABORTED) {
48 /* Signals come asynchronously, so we sleep a brief
49 moment before checking if the handler has been
50 triggered (we cant just return 1 before the
51 signal handler has been called, as the later
52 signal may be treated as a separate interrupt).
53 */
54 Sleep(1);
55 if (PyOS_InterruptOccurred()) {
56 return 1; /* Interrupt */
57 }
58 /* Either the sleep wasn't long enough (need a
59 short loop retrying?) or not interrupted at all
60 (in which case we should revisit the whole thing!)
61 Logging some warning would be nice. assert is not
62 viable as under the debugger, the various dialogs
63 mean the condition is not true.
64 */
65 }
66#endif /* MS_WINDOWS */
Guido van Rossumfbd64c81997-02-18 21:53:32 +000067 if (feof(fp)) {
68 return -1; /* EOF */
69 }
70#ifdef EINTR
71 if (errno == EINTR) {
72 if (PyOS_InterruptOccurred()) {
73 return 1; /* Interrupt */
74 }
75 continue;
76 }
77#endif
78 if (PyOS_InterruptOccurred()) {
79 return 1; /* Interrupt */
80 }
81 return -2; /* Error */
82 }
83 /* NOTREACHED */
84}
85
86
87/* Readline implementation using fgets() */
88
89char *
Thomas Wouters23c9e002000-07-22 19:20:54 +000090PyOS_StdioReadline(char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000091{
Guido van Rossum6da34342000-06-28 22:00:02 +000092 size_t n;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000093 char *p;
Guido van Rossum6fa63431993-12-24 10:36:57 +000094 n = 100;
Guido van Rossumb18618d2000-05-03 23:44:39 +000095 if ((p = PyMem_MALLOC(n)) == NULL)
Guido van Rossum6fa63431993-12-24 10:36:57 +000096 return NULL;
Guido van Rossumc7fea2f1996-01-12 01:30:55 +000097 fflush(stdout);
Guido van Rossum48a680c2001-03-02 06:34:14 +000098#ifndef RISCOS
Guido van Rossum6fa63431993-12-24 10:36:57 +000099 if (prompt)
100 fprintf(stderr, "%s", prompt);
Guido van Rossum48a680c2001-03-02 06:34:14 +0000101#else
102 if (prompt) {
103 if(Py_RISCOSWimpFlag)
104 fprintf(stderr, "\x0cr%s\x0c", prompt);
105 else
106 fprintf(stderr, "%s", prompt);
107 }
108#endif
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000109 fflush(stderr);
Guido van Rossum6da34342000-06-28 22:00:02 +0000110 switch (my_fgets(p, (int)n, stdin)) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000111 case 0: /* Normal case */
112 break;
113 case 1: /* Interrupt */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000114 PyMem_FREE(p);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000115 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000116 case -1: /* EOF */
117 case -2: /* Error */
118 default: /* Shouldn't happen */
119 *p = '\0';
120 break;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000121 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000122#ifdef MPW
123 /* Hack for MPW C where the prompt comes right back in the input */
124 /* XXX (Actually this would be rather nice on most systems...) */
125 n = strlen(prompt);
126 if (strncmp(p, prompt, n) == 0)
127 memmove(p, p + n, strlen(p) - n + 1);
128#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000129 n = strlen(p);
130 while (n > 0 && p[n-1] != '\n') {
Guido van Rossum6da34342000-06-28 22:00:02 +0000131 size_t incr = n+2;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000132 p = PyMem_REALLOC(p, n + incr);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000133 if (p == NULL)
134 return NULL;
Guido van Rossum6da34342000-06-28 22:00:02 +0000135 if (incr > INT_MAX) {
136 PyErr_SetString(PyExc_OverflowError, "input line too long");
137 }
138 if (my_fgets(p+n, (int)incr, stdin) != 0)
Guido van Rossum6fa63431993-12-24 10:36:57 +0000139 break;
140 n += strlen(p+n);
141 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000142 return PyMem_REALLOC(p, n+1);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000143}
144
145
146/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000147 override the readline function.
148
149 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000150
Tim Petersdbd9ba62000-07-09 03:09:57 +0000151char *(*PyOS_ReadlineFunctionPointer)(char *);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000152
153
154/* Interface used by tokenizer.c and bltinmodule.c */
155
156char *
Thomas Wouters23c9e002000-07-22 19:20:54 +0000157PyOS_Readline(char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000158{
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000159 char *rv;
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000160 if (PyOS_ReadlineFunctionPointer == NULL) {
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000161 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
162 }
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000163 Py_BEGIN_ALLOW_THREADS
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000164 rv = (*PyOS_ReadlineFunctionPointer)(prompt);
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000165 Py_END_ALLOW_THREADS
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000166 return rv;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000167}