| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | /* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.
 | 
					
						
							|  |  |  |    By default, or when stdin is not a tty device, we have a super | 
					
						
							|  |  |  |    simple my_readline function using fgets. | 
					
						
							|  |  |  |    Optionally, we can use the GNU readline library. | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  |    my_readline() has a different return value from GNU readline(): | 
					
						
							|  |  |  |    - NULL if an interrupt occurred or if an error occurred | 
					
						
							|  |  |  |    - a malloc'ed empty string if EOF was read | 
					
						
							|  |  |  |    - a malloc'ed string ending in \n normally | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-08-27 19:43:43 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2002-07-14 23:12:29 +00:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | #define WIN32_LEAN_AND_MEAN
 | 
					
						
							|  |  |  | #include "windows.h"
 | 
					
						
							|  |  |  | #endif /* MS_WINDOWS */
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-22 19:20:54 +00:00
										 |  |  | int (*PyOS_InputHook)(void) = NULL; | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-03-02 06:34:14 +00:00
										 |  |  | #ifdef RISCOS
 | 
					
						
							|  |  |  | int Py_RISCOSWimpFlag; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | /* This function restarts a fgets() after an EINTR error occurred
 | 
					
						
							|  |  |  |    except if PyOS_InterruptOccurred() returns true. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2000-07-22 19:20:54 +00:00
										 |  |  | my_fgets(char *buf, int len, FILE *fp) | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	char *p; | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											1997-08-11 18:57:29 +00:00
										 |  |  | 		if (PyOS_InputHook != NULL) | 
					
						
							|  |  |  | 			(void)(PyOS_InputHook)(); | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 		errno = 0; | 
					
						
							|  |  |  | 		p = fgets(buf, len, fp); | 
					
						
							|  |  |  | 		if (p != NULL) | 
					
						
							|  |  |  | 			return 0; /* No error */ | 
					
						
							| 
									
										
										
										
											2002-07-14 23:12:29 +00:00
										 |  |  | #ifdef MS_WINDOWS
 | 
					
						
							|  |  |  | 		/* In the case of a Ctrl+C or some other external event 
 | 
					
						
							|  |  |  | 		   interrupting the operation: | 
					
						
							|  |  |  | 		   Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32  | 
					
						
							|  |  |  | 		   error code (and feof() returns TRUE). | 
					
						
							|  |  |  | 		   Win9x: Ctrl+C seems to have no effect on fgets() returning | 
					
						
							|  |  |  | 		   early - the signal handler is called, but the fgets() | 
					
						
							|  |  |  | 		   only returns "normally" (ie, when Enter hit or feof()) | 
					
						
							|  |  |  | 		*/ | 
					
						
							|  |  |  | 		if (GetLastError()==ERROR_OPERATION_ABORTED) { | 
					
						
							|  |  |  | 			/* Signals come asynchronously, so we sleep a brief 
 | 
					
						
							|  |  |  | 			   moment before checking if the handler has been  | 
					
						
							|  |  |  | 			   triggered (we cant just return 1 before the  | 
					
						
							|  |  |  | 			   signal handler has been called, as the later  | 
					
						
							|  |  |  | 			   signal may be treated as a separate interrupt). | 
					
						
							|  |  |  | 			*/ | 
					
						
							|  |  |  | 			Sleep(1); | 
					
						
							|  |  |  | 			if (PyOS_InterruptOccurred()) { | 
					
						
							|  |  |  | 				return 1; /* Interrupt */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* Either the sleep wasn't long enough (need a
 | 
					
						
							|  |  |  | 			   short loop retrying?) or not interrupted at all | 
					
						
							|  |  |  | 			   (in which case we should revisit the whole thing!) | 
					
						
							|  |  |  | 			   Logging some warning would be nice.  assert is not | 
					
						
							|  |  |  | 			   viable as under the debugger, the various dialogs | 
					
						
							|  |  |  | 			   mean the condition is not true. | 
					
						
							|  |  |  | 			*/ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif /* MS_WINDOWS */
 | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 		if (feof(fp)) { | 
					
						
							|  |  |  | 			return -1; /* EOF */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #ifdef EINTR
 | 
					
						
							|  |  |  | 		if (errno == EINTR) { | 
					
						
							|  |  |  | 			if (PyOS_InterruptOccurred()) { | 
					
						
							|  |  |  | 				return 1; /* Interrupt */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		if (PyOS_InterruptOccurred()) { | 
					
						
							|  |  |  | 			return 1; /* Interrupt */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return -2; /* Error */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* NOTREACHED */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Readline implementation using fgets() */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							| 
									
										
										
										
											2000-07-22 19:20:54 +00:00
										 |  |  | PyOS_StdioReadline(char *prompt) | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2000-06-28 22:00:02 +00:00
										 |  |  | 	size_t n; | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 	char *p; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 	n = 100; | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 	if ((p = PyMem_MALLOC(n)) == NULL) | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1996-01-12 01:30:55 +00:00
										 |  |  | 	fflush(stdout); | 
					
						
							| 
									
										
										
										
											2001-03-02 06:34:14 +00:00
										 |  |  | #ifndef RISCOS
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 	if (prompt) | 
					
						
							|  |  |  | 		fprintf(stderr, "%s", prompt); | 
					
						
							| 
									
										
										
										
											2001-03-02 06:34:14 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	if (prompt) { | 
					
						
							|  |  |  | 		if(Py_RISCOSWimpFlag) | 
					
						
							|  |  |  | 			fprintf(stderr, "\x0cr%s\x0c", prompt); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			fprintf(stderr, "%s", prompt); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-01-12 01:30:55 +00:00
										 |  |  | 	fflush(stderr); | 
					
						
							| 
									
										
										
										
											2000-06-28 22:00:02 +00:00
										 |  |  | 	switch (my_fgets(p, (int)n, stdin)) { | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	case 0: /* Normal case */ | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: /* Interrupt */ | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 		PyMem_FREE(p); | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | 	case -1: /* EOF */ | 
					
						
							|  |  |  | 	case -2: /* Error */ | 
					
						
							|  |  |  | 	default: /* Shouldn't happen */ | 
					
						
							|  |  |  | 		*p = '\0'; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-08-01 11:34:53 +00:00
										 |  |  | #ifdef MPW
 | 
					
						
							|  |  |  | 	/* Hack for MPW C where the prompt comes right back in the input */ | 
					
						
							|  |  |  | 	/* XXX (Actually this would be rather nice on most systems...) */ | 
					
						
							|  |  |  | 	n = strlen(prompt); | 
					
						
							|  |  |  | 	if (strncmp(p, prompt, n) == 0) | 
					
						
							|  |  |  | 		memmove(p, p + n, strlen(p) - n + 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 	n = strlen(p); | 
					
						
							|  |  |  | 	while (n > 0 && p[n-1] != '\n') { | 
					
						
							| 
									
										
										
										
											2000-06-28 22:00:02 +00:00
										 |  |  | 		size_t incr = n+2; | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 		p = PyMem_REALLOC(p, n + incr); | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 		if (p == NULL) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2000-06-28 22:00:02 +00:00
										 |  |  | 		if (incr > INT_MAX) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_OverflowError, "input line too long"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (my_fgets(p+n, (int)incr, stdin) != 0) | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		n += strlen(p+n); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  | 	return PyMem_REALLOC(p, n+1); | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* By initializing this function pointer, systems embedding Python can
 | 
					
						
							| 
									
										
										
										
											2000-05-03 23:44:39 +00:00
										 |  |  |    override the readline function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Note: Python expects in return a buffer allocated with PyMem_Malloc. */ | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-07-09 03:09:57 +00:00
										 |  |  | char *(*PyOS_ReadlineFunctionPointer)(char *); | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Interface used by tokenizer.c and bltinmodule.c */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							| 
									
										
										
										
											2000-07-22 19:20:54 +00:00
										 |  |  | PyOS_Readline(char *prompt) | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1998-08-29 16:03:27 +00:00
										 |  |  | 	char *rv; | 
					
						
							| 
									
										
										
										
											1997-02-18 21:53:32 +00:00
										 |  |  | 	if (PyOS_ReadlineFunctionPointer == NULL) { | 
					
						
							|  |  |  | 			PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1998-08-27 19:43:43 +00:00
										 |  |  | 	Py_BEGIN_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											1998-08-29 16:03:27 +00:00
										 |  |  | 	rv = (*PyOS_ReadlineFunctionPointer)(prompt); | 
					
						
							| 
									
										
										
										
											1998-08-27 19:43:43 +00:00
										 |  |  | 	Py_END_ALLOW_THREADS | 
					
						
							| 
									
										
										
										
											1998-08-29 16:03:27 +00:00
										 |  |  | 	return rv; | 
					
						
							| 
									
										
										
										
											1993-12-24 10:36:57 +00:00
										 |  |  | } |