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
14 #define WIN32_LEAN_AND_MEAN
16 #endif /* MS_WINDOWS */
19 extern char* vms__StdioReadline(FILE *sys_stdin
, FILE *sys_stdout
, char *prompt
);
22 int (*PyOS_InputHook
)(void) = NULL
;
25 int Py_RISCOSWimpFlag
;
28 /* This function restarts a fgets() after an EINTR error occurred
29 except if PyOS_InterruptOccurred() returns true. */
32 my_fgets(char *buf
, int len
, FILE *fp
)
36 if (PyOS_InputHook
!= NULL
)
37 (void)(PyOS_InputHook
)();
39 p
= fgets(buf
, len
, fp
);
41 return 0; /* No error */
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())
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).
59 if (PyOS_InterruptOccurred()) {
60 return 1; /* Interrupt */
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.
70 #endif /* MS_WINDOWS */
76 if (PyOS_InterruptOccurred()) {
77 return 1; /* Interrupt */
82 if (PyOS_InterruptOccurred()) {
83 return 1; /* Interrupt */
85 return -2; /* Error */
91 /* Readline implementation using fgets() */
94 PyOS_StdioReadline(FILE *sys_stdin
, FILE *sys_stdout
, char *prompt
)
99 if ((p
= PyMem_MALLOC(n
)) == NULL
)
104 fprintf(stderr
, "%s", prompt
);
107 if(Py_RISCOSWimpFlag
)
108 fprintf(stderr
, "\x0cr%s\x0c", prompt
);
110 fprintf(stderr
, "%s", prompt
);
114 switch (my_fgets(p
, (int)n
, sys_stdin
)) {
115 case 0: /* Normal case */
117 case 1: /* Interrupt */
122 default: /* Shouldn't happen */
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...) */
130 if (strncmp(p
, prompt
, n
) == 0)
131 memmove(p
, p
+ n
, strlen(p
) - n
+ 1);
134 while (n
> 0 && p
[n
-1] != '\n') {
136 p
= PyMem_REALLOC(p
, n
+ incr
);
139 if (incr
> INT_MAX
) {
140 PyErr_SetString(PyExc_OverflowError
, "input line too long");
142 if (my_fgets(p
+n
, (int)incr
, sys_stdin
) != 0)
146 return PyMem_REALLOC(p
, n
+1);
150 /* By initializing this function pointer, systems embedding Python can
151 override the readline function.
153 Note: Python expects in return a buffer allocated with PyMem_Malloc. */
155 char *(*PyOS_ReadlineFunctionPointer
)(FILE *, FILE *, char *);
158 /* Interface used by tokenizer.c and bltinmodule.c */
161 PyOS_Readline(FILE *sys_stdin
, FILE *sys_stdout
, char *prompt
)
165 if (PyOS_ReadlineFunctionPointer
== NULL
) {
167 PyOS_ReadlineFunctionPointer
= vms__StdioReadline
;
169 PyOS_ReadlineFunctionPointer
= PyOS_StdioReadline
;
173 Py_BEGIN_ALLOW_THREADS
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
180 if (!isatty (fileno (sys_stdin
)) || !isatty (fileno (sys_stdout
)))
181 rv
= PyOS_StdioReadline (sys_stdin
, sys_stdout
, prompt
);
183 rv
= (*PyOS_ReadlineFunctionPointer
)(sys_stdin
, sys_stdout
,