symbian-qemu-0.9.1-12/python-2.6.1/Parser/myreadline.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Parser/myreadline.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,219 @@
+
+/* 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.
+   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
+*/
+
+#include "Python.h"
+#ifdef MS_WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#endif /* MS_WINDOWS */
+
+#ifdef __VMS
+extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
+#endif
+
+
+PyThreadState* _PyOS_ReadlineTState;
+
+#ifdef WITH_THREAD
+#include "pythread.h"
+static PyThread_type_lock _PyOS_ReadlineLock = NULL;
+#endif
+
+int (*PyOS_InputHook)(void) = NULL;
+
+#ifdef RISCOS
+int Py_RISCOSWimpFlag;
+#endif
+
+/* This function restarts a fgets() after an EINTR error occurred
+   except if PyOS_InterruptOccurred() returns true. */
+
+static int
+my_fgets(char *buf, int len, FILE *fp)
+{
+	char *p;
+	for (;;) {
+		if (PyOS_InputHook != NULL)
+			(void)(PyOS_InputHook)();
+		errno = 0;
+		p = fgets(buf, len, fp);
+		if (p != NULL)
+			return 0; /* No error */
+#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 */
+		if (feof(fp)) {
+			return -1; /* EOF */
+		}
+#ifdef EINTR
+		if (errno == EINTR) {
+			int s;
+#ifdef WITH_THREAD
+			PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
+			s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
+			PyEval_SaveThread();
+#endif
+			if (s < 0) {
+				return 1;
+			}
+		}
+#endif
+		if (PyOS_InterruptOccurred()) {
+			return 1; /* Interrupt */
+		}
+		return -2; /* Error */
+	}
+	/* NOTREACHED */
+}
+
+
+/* Readline implementation using fgets() */
+
+char *
+PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	size_t n;
+	char *p;
+	n = 100;
+	if ((p = (char *)PyMem_MALLOC(n)) == NULL)
+		return NULL;
+	fflush(sys_stdout);
+#ifndef RISCOS
+	if (prompt)
+		fprintf(stderr, "%s", prompt);
+#else
+	if (prompt) {
+		if(Py_RISCOSWimpFlag)
+			fprintf(stderr, "\x0cr%s\x0c", prompt);
+		else
+			fprintf(stderr, "%s", prompt);
+	}
+#endif
+	fflush(stderr);
+	switch (my_fgets(p, (int)n, sys_stdin)) {
+	case 0: /* Normal case */
+		break;
+	case 1: /* Interrupt */
+		PyMem_FREE(p);
+		return NULL;
+	case -1: /* EOF */
+	case -2: /* Error */
+	default: /* Shouldn't happen */
+		*p = '\0';
+		break;
+	}
+	n = strlen(p);
+	while (n > 0 && p[n-1] != '\n') {
+		size_t incr = n+2;
+		p = (char *)PyMem_REALLOC(p, n + incr);
+		if (p == NULL)
+			return NULL;
+		if (incr > INT_MAX) {
+			PyErr_SetString(PyExc_OverflowError, "input line too long");
+		}
+		if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
+			break;
+		n += strlen(p+n);
+	}
+	return (char *)PyMem_REALLOC(p, n+1);
+}
+
+
+/* By initializing this function pointer, systems embedding Python can
+   override the readline function.
+
+   Note: Python expects in return a buffer allocated with PyMem_Malloc. */
+
+char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
+
+
+/* Interface used by tokenizer.c and bltinmodule.c */
+
+char *
+PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
+{
+	char *rv;
+
+	if (_PyOS_ReadlineTState == PyThreadState_GET()) {
+		PyErr_SetString(PyExc_RuntimeError,
+				"can't re-enter readline");
+		return NULL;
+	}
+	
+
+	if (PyOS_ReadlineFunctionPointer == NULL) {
+#ifdef __VMS
+                PyOS_ReadlineFunctionPointer = vms__StdioReadline;
+#else
+                PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
+#endif
+	}
+	
+#ifdef WITH_THREAD
+	if (_PyOS_ReadlineLock == NULL) {
+		_PyOS_ReadlineLock = PyThread_allocate_lock();		
+	}
+#endif
+
+	_PyOS_ReadlineTState = PyThreadState_GET();
+	Py_BEGIN_ALLOW_THREADS
+#ifdef WITH_THREAD
+	PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
+#endif
+
+        /* This is needed to handle the unlikely case that the
+         * interpreter is in interactive mode *and* stdin/out are not
+         * a tty.  This can happen, for example if python is run like
+         * this: python -i < test1.py
+         */
+        if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
+                rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
+        else
+                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
+                                                     prompt);
+	Py_END_ALLOW_THREADS
+
+#ifdef WITH_THREAD
+	PyThread_release_lock(_PyOS_ReadlineLock);
+#endif
+
+	_PyOS_ReadlineTState = NULL;
+
+	return rv;
+}