+++ /dev/null
-\r
-/* Readline interface for tokenizer.c and [raw_]input() in bltinmodule.c.\r
- By default, or when stdin is not a tty device, we have a super\r
- simple my_readline function using fgets.\r
- Optionally, we can use the GNU readline library.\r
- my_readline() has a different return value from GNU readline():\r
- - NULL if an interrupt occurred or if an error occurred\r
- - a malloc'ed empty string if EOF was read\r
- - a malloc'ed string ending in \n normally\r
-*/\r
-\r
-#include "Python.h"\r
-#ifdef MS_WINDOWS\r
-#define WIN32_LEAN_AND_MEAN\r
-#include "windows.h"\r
-#endif /* MS_WINDOWS */\r
-\r
-#ifdef __VMS\r
-extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);\r
-#endif\r
-\r
-\r
-PyThreadState* _PyOS_ReadlineTState;\r
-\r
-#ifdef WITH_THREAD\r
-#include "pythread.h"\r
-static PyThread_type_lock _PyOS_ReadlineLock = NULL;\r
-#endif\r
-\r
-int (*PyOS_InputHook)(void) = NULL;\r
-\r
-#ifdef RISCOS\r
-int Py_RISCOSWimpFlag;\r
-#endif\r
-\r
-/* This function restarts a fgets() after an EINTR error occurred\r
- except if PyOS_InterruptOccurred() returns true. */\r
-\r
-static int\r
-my_fgets(char *buf, int len, FILE *fp)\r
-{\r
- char *p;\r
-#ifdef MS_WINDOWS\r
- int i;\r
-#endif\r
-\r
- while (1) {\r
- if (PyOS_InputHook != NULL)\r
- (void)(PyOS_InputHook)();\r
- errno = 0;\r
- clearerr(fp);\r
- p = fgets(buf, len, fp);\r
- if (p != NULL)\r
- return 0; /* No error */\r
-#ifdef MS_WINDOWS\r
- /* Ctrl-C anywhere on the line or Ctrl-Z if the only character\r
- on a line will set ERROR_OPERATION_ABORTED. Under normal\r
- circumstances Ctrl-C will also have caused the SIGINT handler\r
- to fire. This signal fires in another thread and is not\r
- guaranteed to have occurred before this point in the code.\r
-\r
- Therefore: check in a small loop to see if the trigger has\r
- fired, in which case assume this is a Ctrl-C event. If it\r
- hasn't fired within 10ms assume that this is a Ctrl-Z on its\r
- own or that the signal isn't going to fire for some other\r
- reason and drop through to check for EOF.\r
- */\r
- if (GetLastError()==ERROR_OPERATION_ABORTED) {\r
- for (i = 0; i < 10; i++) {\r
- if (PyOS_InterruptOccurred())\r
- return 1;\r
- Sleep(1);\r
- }\r
- }\r
-#endif /* MS_WINDOWS */\r
- if (feof(fp)) {\r
- clearerr(fp);\r
- return -1; /* EOF */\r
- }\r
-#ifdef EINTR\r
- if (errno == EINTR) {\r
- int s;\r
-#ifdef WITH_THREAD\r
- PyEval_RestoreThread(_PyOS_ReadlineTState);\r
-#endif\r
- s = PyErr_CheckSignals();\r
-#ifdef WITH_THREAD\r
- PyEval_SaveThread();\r
-#endif\r
- if (s < 0)\r
- return 1;\r
- /* try again */\r
- continue;\r
- }\r
-#endif\r
- if (PyOS_InterruptOccurred()) {\r
- return 1; /* Interrupt */\r
- }\r
- return -2; /* Error */\r
- }\r
- /* NOTREACHED */\r
-}\r
-\r
-\r
-/* Readline implementation using fgets() */\r
-\r
-char *\r
-PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)\r
-{\r
- size_t n;\r
- char *p;\r
- n = 100;\r
- if ((p = (char *)PyMem_MALLOC(n)) == NULL)\r
- return NULL;\r
- fflush(sys_stdout);\r
-#ifndef RISCOS\r
- if (prompt)\r
- fprintf(stderr, "%s", prompt);\r
-#else\r
- if (prompt) {\r
- if(Py_RISCOSWimpFlag)\r
- fprintf(stderr, "\x0cr%s\x0c", prompt);\r
- else\r
- fprintf(stderr, "%s", prompt);\r
- }\r
-#endif\r
- fflush(stderr);\r
- switch (my_fgets(p, (int)n, sys_stdin)) {\r
- case 0: /* Normal case */\r
- break;\r
- case 1: /* Interrupt */\r
- PyMem_FREE(p);\r
- return NULL;\r
- case -1: /* EOF */\r
- case -2: /* Error */\r
- default: /* Shouldn't happen */\r
- *p = '\0';\r
- break;\r
- }\r
- n = strlen(p);\r
- while (n > 0 && p[n-1] != '\n') {\r
- size_t incr = n+2;\r
- p = (char *)PyMem_REALLOC(p, n + incr);\r
- if (p == NULL)\r
- return NULL;\r
- if (incr > INT_MAX) {\r
- PyErr_SetString(PyExc_OverflowError, "input line too long");\r
- }\r
- if (my_fgets(p+n, (int)incr, sys_stdin) != 0)\r
- break;\r
- n += strlen(p+n);\r
- }\r
- return (char *)PyMem_REALLOC(p, n+1);\r
-}\r
-\r
-\r
-/* By initializing this function pointer, systems embedding Python can\r
- override the readline function.\r
-\r
- Note: Python expects in return a buffer allocated with PyMem_Malloc. */\r
-\r
-char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);\r
-\r
-\r
-/* Interface used by tokenizer.c and bltinmodule.c */\r
-\r
-char *\r
-PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)\r
-{\r
- char *rv;\r
-\r
- if (_PyOS_ReadlineTState == PyThreadState_GET()) {\r
- PyErr_SetString(PyExc_RuntimeError,\r
- "can't re-enter readline");\r
- return NULL;\r
- }\r
-\r
-\r
- if (PyOS_ReadlineFunctionPointer == NULL) {\r
-#ifdef __VMS\r
- PyOS_ReadlineFunctionPointer = vms__StdioReadline;\r
-#else\r
- PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;\r
-#endif\r
- }\r
-\r
-#ifdef WITH_THREAD\r
- if (_PyOS_ReadlineLock == NULL) {\r
- _PyOS_ReadlineLock = PyThread_allocate_lock();\r
- }\r
-#endif\r
-\r
- _PyOS_ReadlineTState = PyThreadState_GET();\r
- Py_BEGIN_ALLOW_THREADS\r
-#ifdef WITH_THREAD\r
- PyThread_acquire_lock(_PyOS_ReadlineLock, 1);\r
-#endif\r
-\r
- /* This is needed to handle the unlikely case that the\r
- * interpreter is in interactive mode *and* stdin/out are not\r
- * a tty. This can happen, for example if python is run like\r
- * this: python -i < test1.py\r
- */\r
- if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))\r
- rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);\r
- else\r
- rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,\r
- prompt);\r
- Py_END_ALLOW_THREADS\r
-\r
-#ifdef WITH_THREAD\r
- PyThread_release_lock(_PyOS_ReadlineLock);\r
-#endif\r
-\r
- _PyOS_ReadlineTState = NULL;\r
-\r
- return rv;\r
-}\r