blob: fcc4667d7f64ffcb495b3d98e9d66fa8573b4ccc [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
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +000018#ifdef __VMS
19extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
20#endif
21
Thomas Wouters23c9e002000-07-22 19:20:54 +000022int (*PyOS_InputHook)(void) = NULL;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000023
Guido van Rossum48a680c2001-03-02 06:34:14 +000024#ifdef RISCOS
25int Py_RISCOSWimpFlag;
26#endif
27
Guido van Rossumfbd64c81997-02-18 21:53:32 +000028/* This function restarts a fgets() after an EINTR error occurred
29 except if PyOS_InterruptOccurred() returns true. */
30
31static int
Thomas Wouters23c9e002000-07-22 19:20:54 +000032my_fgets(char *buf, int len, FILE *fp)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000033{
34 char *p;
35 for (;;) {
Guido van Rossum44620641997-08-11 18:57:29 +000036 if (PyOS_InputHook != NULL)
37 (void)(PyOS_InputHook)();
Guido van Rossumfbd64c81997-02-18 21:53:32 +000038 errno = 0;
39 p = fgets(buf, len, fp);
40 if (p != NULL)
41 return 0; /* No error */
Mark Hammond2f10cb82002-07-14 23:12:29 +000042#ifdef MS_WINDOWS
43 /* In the case of a Ctrl+C or some other external event
44 interrupting the operation:
45 Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
46 error code (and feof() returns TRUE).
47 Win9x: Ctrl+C seems to have no effect on fgets() returning
48 early - the signal handler is called, but the fgets()
49 only returns "normally" (ie, when Enter hit or feof())
50 */
51 if (GetLastError()==ERROR_OPERATION_ABORTED) {
52 /* Signals come asynchronously, so we sleep a brief
53 moment before checking if the handler has been
54 triggered (we cant just return 1 before the
55 signal handler has been called, as the later
56 signal may be treated as a separate interrupt).
57 */
58 Sleep(1);
59 if (PyOS_InterruptOccurred()) {
60 return 1; /* Interrupt */
61 }
62 /* Either the sleep wasn't long enough (need a
63 short loop retrying?) or not interrupted at all
64 (in which case we should revisit the whole thing!)
65 Logging some warning would be nice. assert is not
66 viable as under the debugger, the various dialogs
67 mean the condition is not true.
68 */
69 }
70#endif /* MS_WINDOWS */
Guido van Rossumfbd64c81997-02-18 21:53:32 +000071 if (feof(fp)) {
72 return -1; /* EOF */
73 }
74#ifdef EINTR
75 if (errno == EINTR) {
76 if (PyOS_InterruptOccurred()) {
77 return 1; /* Interrupt */
78 }
79 continue;
80 }
81#endif
82 if (PyOS_InterruptOccurred()) {
83 return 1; /* Interrupt */
84 }
85 return -2; /* Error */
86 }
87 /* NOTREACHED */
88}
89
90
91/* Readline implementation using fgets() */
92
93char *
Martin v. Löwis566f6af2002-10-26 14:39:10 +000094PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +000095{
Guido van Rossum6da34342000-06-28 22:00:02 +000096 size_t n;
Guido van Rossumfbd64c81997-02-18 21:53:32 +000097 char *p;
Guido van Rossum6fa63431993-12-24 10:36:57 +000098 n = 100;
Guido van Rossumb18618d2000-05-03 23:44:39 +000099 if ((p = PyMem_MALLOC(n)) == NULL)
Guido van Rossum6fa63431993-12-24 10:36:57 +0000100 return NULL;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000101 fflush(sys_stdout);
Guido van Rossum48a680c2001-03-02 06:34:14 +0000102#ifndef RISCOS
Guido van Rossum6fa63431993-12-24 10:36:57 +0000103 if (prompt)
104 fprintf(stderr, "%s", prompt);
Guido van Rossum48a680c2001-03-02 06:34:14 +0000105#else
106 if (prompt) {
107 if(Py_RISCOSWimpFlag)
108 fprintf(stderr, "\x0cr%s\x0c", prompt);
109 else
110 fprintf(stderr, "%s", prompt);
111 }
112#endif
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000113 fflush(stderr);
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000114 switch (my_fgets(p, (int)n, sys_stdin)) {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115 case 0: /* Normal case */
116 break;
117 case 1: /* Interrupt */
Guido van Rossumb18618d2000-05-03 23:44:39 +0000118 PyMem_FREE(p);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000119 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000120 case -1: /* EOF */
121 case -2: /* Error */
122 default: /* Shouldn't happen */
123 *p = '\0';
124 break;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000125 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000126#ifdef MPW
127 /* Hack for MPW C where the prompt comes right back in the input */
128 /* XXX (Actually this would be rather nice on most systems...) */
129 n = strlen(prompt);
130 if (strncmp(p, prompt, n) == 0)
131 memmove(p, p + n, strlen(p) - n + 1);
132#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000133 n = strlen(p);
134 while (n > 0 && p[n-1] != '\n') {
Guido van Rossum6da34342000-06-28 22:00:02 +0000135 size_t incr = n+2;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000136 p = PyMem_REALLOC(p, n + incr);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000137 if (p == NULL)
138 return NULL;
Guido van Rossum6da34342000-06-28 22:00:02 +0000139 if (incr > INT_MAX) {
140 PyErr_SetString(PyExc_OverflowError, "input line too long");
141 }
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000142 if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
Guido van Rossum6fa63431993-12-24 10:36:57 +0000143 break;
144 n += strlen(p+n);
145 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000146 return PyMem_REALLOC(p, n+1);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000147}
148
149
150/* By initializing this function pointer, systems embedding Python can
Guido van Rossumb18618d2000-05-03 23:44:39 +0000151 override the readline function.
152
153 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000154
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000155char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000156
157
158/* Interface used by tokenizer.c and bltinmodule.c */
159
160char *
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000161PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000162{
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000163 char *rv;
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000164
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000165 if (PyOS_ReadlineFunctionPointer == NULL) {
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000166#ifdef __VMS
167 PyOS_ReadlineFunctionPointer = vms__StdioReadline;
168#else
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000169 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000170#endif
Guido van Rossumfbd64c81997-02-18 21:53:32 +0000171 }
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000172
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000173 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis566f6af2002-10-26 14:39:10 +0000174
175 /* This is needed to handle the unlikely case that the
176 * interpreter is in interactive mode *and* stdin/out are not
177 * a tty. This can happen, for example if python is run like
178 * this: python -i < test1.py
179 */
180 if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
181 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
182 else
183 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
184 prompt);
Guido van Rossum8efa47b1998-08-27 19:43:43 +0000185 Py_END_ALLOW_THREADS
Guido van Rossum80c7bcf1998-08-29 16:03:27 +0000186 return rv;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000187}