symbian-qemu-0.9.1-12/python-2.6.1/Parser/myreadline.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 
       
     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
       
    10 */
       
    11 
       
    12 #include "Python.h"
       
    13 #ifdef MS_WINDOWS
       
    14 #define WIN32_LEAN_AND_MEAN
       
    15 #include "windows.h"
       
    16 #endif /* MS_WINDOWS */
       
    17 
       
    18 #ifdef __VMS
       
    19 extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
       
    20 #endif
       
    21 
       
    22 
       
    23 PyThreadState* _PyOS_ReadlineTState;
       
    24 
       
    25 #ifdef WITH_THREAD
       
    26 #include "pythread.h"
       
    27 static PyThread_type_lock _PyOS_ReadlineLock = NULL;
       
    28 #endif
       
    29 
       
    30 int (*PyOS_InputHook)(void) = NULL;
       
    31 
       
    32 #ifdef RISCOS
       
    33 int Py_RISCOSWimpFlag;
       
    34 #endif
       
    35 
       
    36 /* This function restarts a fgets() after an EINTR error occurred
       
    37    except if PyOS_InterruptOccurred() returns true. */
       
    38 
       
    39 static int
       
    40 my_fgets(char *buf, int len, FILE *fp)
       
    41 {
       
    42 	char *p;
       
    43 	for (;;) {
       
    44 		if (PyOS_InputHook != NULL)
       
    45 			(void)(PyOS_InputHook)();
       
    46 		errno = 0;
       
    47 		p = fgets(buf, len, fp);
       
    48 		if (p != NULL)
       
    49 			return 0; /* No error */
       
    50 #ifdef MS_WINDOWS
       
    51 		/* In the case of a Ctrl+C or some other external event 
       
    52 		   interrupting the operation:
       
    53 		   Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32 
       
    54 		   error code (and feof() returns TRUE).
       
    55 		   Win9x: Ctrl+C seems to have no effect on fgets() returning
       
    56 		   early - the signal handler is called, but the fgets()
       
    57 		   only returns "normally" (ie, when Enter hit or feof())
       
    58 		*/
       
    59 		if (GetLastError()==ERROR_OPERATION_ABORTED) {
       
    60 			/* Signals come asynchronously, so we sleep a brief 
       
    61 			   moment before checking if the handler has been 
       
    62 			   triggered (we cant just return 1 before the 
       
    63 			   signal handler has been called, as the later 
       
    64 			   signal may be treated as a separate interrupt).
       
    65 			*/
       
    66 			Sleep(1);
       
    67 			if (PyOS_InterruptOccurred()) {
       
    68 				return 1; /* Interrupt */
       
    69 			}
       
    70 			/* Either the sleep wasn't long enough (need a
       
    71 			   short loop retrying?) or not interrupted at all
       
    72 			   (in which case we should revisit the whole thing!)
       
    73 			   Logging some warning would be nice.  assert is not
       
    74 			   viable as under the debugger, the various dialogs
       
    75 			   mean the condition is not true.
       
    76 			*/
       
    77 		}
       
    78 #endif /* MS_WINDOWS */
       
    79 		if (feof(fp)) {
       
    80 			return -1; /* EOF */
       
    81 		}
       
    82 #ifdef EINTR
       
    83 		if (errno == EINTR) {
       
    84 			int s;
       
    85 #ifdef WITH_THREAD
       
    86 			PyEval_RestoreThread(_PyOS_ReadlineTState);
       
    87 #endif
       
    88 			s = PyErr_CheckSignals();
       
    89 #ifdef WITH_THREAD
       
    90 			PyEval_SaveThread();
       
    91 #endif
       
    92 			if (s < 0) {
       
    93 				return 1;
       
    94 			}
       
    95 		}
       
    96 #endif
       
    97 		if (PyOS_InterruptOccurred()) {
       
    98 			return 1; /* Interrupt */
       
    99 		}
       
   100 		return -2; /* Error */
       
   101 	}
       
   102 	/* NOTREACHED */
       
   103 }
       
   104 
       
   105 
       
   106 /* Readline implementation using fgets() */
       
   107 
       
   108 char *
       
   109 PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
       
   110 {
       
   111 	size_t n;
       
   112 	char *p;
       
   113 	n = 100;
       
   114 	if ((p = (char *)PyMem_MALLOC(n)) == NULL)
       
   115 		return NULL;
       
   116 	fflush(sys_stdout);
       
   117 #ifndef RISCOS
       
   118 	if (prompt)
       
   119 		fprintf(stderr, "%s", prompt);
       
   120 #else
       
   121 	if (prompt) {
       
   122 		if(Py_RISCOSWimpFlag)
       
   123 			fprintf(stderr, "\x0cr%s\x0c", prompt);
       
   124 		else
       
   125 			fprintf(stderr, "%s", prompt);
       
   126 	}
       
   127 #endif
       
   128 	fflush(stderr);
       
   129 	switch (my_fgets(p, (int)n, sys_stdin)) {
       
   130 	case 0: /* Normal case */
       
   131 		break;
       
   132 	case 1: /* Interrupt */
       
   133 		PyMem_FREE(p);
       
   134 		return NULL;
       
   135 	case -1: /* EOF */
       
   136 	case -2: /* Error */
       
   137 	default: /* Shouldn't happen */
       
   138 		*p = '\0';
       
   139 		break;
       
   140 	}
       
   141 	n = strlen(p);
       
   142 	while (n > 0 && p[n-1] != '\n') {
       
   143 		size_t incr = n+2;
       
   144 		p = (char *)PyMem_REALLOC(p, n + incr);
       
   145 		if (p == NULL)
       
   146 			return NULL;
       
   147 		if (incr > INT_MAX) {
       
   148 			PyErr_SetString(PyExc_OverflowError, "input line too long");
       
   149 		}
       
   150 		if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
       
   151 			break;
       
   152 		n += strlen(p+n);
       
   153 	}
       
   154 	return (char *)PyMem_REALLOC(p, n+1);
       
   155 }
       
   156 
       
   157 
       
   158 /* By initializing this function pointer, systems embedding Python can
       
   159    override the readline function.
       
   160 
       
   161    Note: Python expects in return a buffer allocated with PyMem_Malloc. */
       
   162 
       
   163 char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
       
   164 
       
   165 
       
   166 /* Interface used by tokenizer.c and bltinmodule.c */
       
   167 
       
   168 char *
       
   169 PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
       
   170 {
       
   171 	char *rv;
       
   172 
       
   173 	if (_PyOS_ReadlineTState == PyThreadState_GET()) {
       
   174 		PyErr_SetString(PyExc_RuntimeError,
       
   175 				"can't re-enter readline");
       
   176 		return NULL;
       
   177 	}
       
   178 	
       
   179 
       
   180 	if (PyOS_ReadlineFunctionPointer == NULL) {
       
   181 #ifdef __VMS
       
   182                 PyOS_ReadlineFunctionPointer = vms__StdioReadline;
       
   183 #else
       
   184                 PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
       
   185 #endif
       
   186 	}
       
   187 	
       
   188 #ifdef WITH_THREAD
       
   189 	if (_PyOS_ReadlineLock == NULL) {
       
   190 		_PyOS_ReadlineLock = PyThread_allocate_lock();		
       
   191 	}
       
   192 #endif
       
   193 
       
   194 	_PyOS_ReadlineTState = PyThreadState_GET();
       
   195 	Py_BEGIN_ALLOW_THREADS
       
   196 #ifdef WITH_THREAD
       
   197 	PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
       
   198 #endif
       
   199 
       
   200         /* This is needed to handle the unlikely case that the
       
   201          * interpreter is in interactive mode *and* stdin/out are not
       
   202          * a tty.  This can happen, for example if python is run like
       
   203          * this: python -i < test1.py
       
   204          */
       
   205         if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
       
   206                 rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
       
   207         else
       
   208                 rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
       
   209                                                      prompt);
       
   210 	Py_END_ALLOW_THREADS
       
   211 
       
   212 #ifdef WITH_THREAD
       
   213 	PyThread_release_lock(_PyOS_ReadlineLock);
       
   214 #endif
       
   215 
       
   216 	_PyOS_ReadlineTState = NULL;
       
   217 
       
   218 	return rv;
       
   219 }