
/* 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;

/* 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);
	if (prompt)
		fprintf(stderr, "%s", prompt);
	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;
}
