LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Parser - myreadline.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 67 0.0 %
Date: 2012-12-17 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /* This function restarts a fgets() after an EINTR error occurred
      33             :    except if PyOS_InterruptOccurred() returns true. */
      34             : 
      35             : static int
      36           0 : my_fgets(char *buf, int len, FILE *fp)
      37             : {
      38             : #ifdef MS_WINDOWS
      39             :     HANDLE hInterruptEvent;
      40             : #endif
      41             :     char *p;
      42             :     int err;
      43             :     while (1) {
      44           0 :         if (PyOS_InputHook != NULL)
      45           0 :             (void)(PyOS_InputHook)();
      46           0 :         errno = 0;
      47           0 :         clearerr(fp);
      48             :         if (_PyVerify_fd(fileno(fp)))
      49           0 :             p = fgets(buf, len, fp);
      50             :         else
      51             :             p = NULL;
      52           0 :         if (p != NULL)
      53           0 :             return 0; /* No error */
      54           0 :         err = errno;
      55             : #ifdef MS_WINDOWS
      56             :         /* Ctrl-C anywhere on the line or Ctrl-Z if the only character
      57             :            on a line will set ERROR_OPERATION_ABORTED. Under normal
      58             :            circumstances Ctrl-C will also have caused the SIGINT handler
      59             :            to fire which will have set the event object returned by
      60             :            _PyOS_SigintEvent. This signal fires in another thread and
      61             :            is not guaranteed to have occurred before this point in the
      62             :            code.
      63             : 
      64             :            Therefore: check whether the event is set with a small timeout.
      65             :            If it is, assume this is a Ctrl-C and reset the event. If it
      66             :            isn't set assume that this is a Ctrl-Z on its own and drop
      67             :            through to check for EOF.
      68             :         */
      69             :         if (GetLastError()==ERROR_OPERATION_ABORTED) {
      70             :             hInterruptEvent = _PyOS_SigintEvent();
      71             :             switch (WaitForSingleObject(hInterruptEvent, 10)) {
      72             :             case WAIT_OBJECT_0:
      73             :                 ResetEvent(hInterruptEvent);
      74             :                 return 1; /* Interrupt */
      75             :             case WAIT_FAILED:
      76             :                 return -2; /* Error */
      77             :             }
      78             :         }
      79             : #endif /* MS_WINDOWS */
      80           0 :         if (feof(fp)) {
      81           0 :             clearerr(fp);
      82           0 :             return -1; /* EOF */
      83             :         }
      84             : #ifdef EINTR
      85           0 :         if (err == EINTR) {
      86             :             int s;
      87             : #ifdef WITH_THREAD
      88           0 :             PyEval_RestoreThread(_PyOS_ReadlineTState);
      89             : #endif
      90           0 :             s = PyErr_CheckSignals();
      91             : #ifdef WITH_THREAD
      92           0 :             PyEval_SaveThread();
      93             : #endif
      94           0 :             if (s < 0)
      95           0 :                     return 1;
      96             :         /* try again */
      97           0 :             continue;
      98             :         }
      99             : #endif
     100           0 :         if (PyOS_InterruptOccurred()) {
     101           0 :             return 1; /* Interrupt */
     102             :         }
     103           0 :         return -2; /* Error */
     104           0 :     }
     105             :     /* NOTREACHED */
     106             : }
     107             : 
     108             : 
     109             : /* Readline implementation using fgets() */
     110             : 
     111             : char *
     112           0 : PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
     113             : {
     114             :     size_t n;
     115             :     char *p;
     116           0 :     n = 100;
     117           0 :     if ((p = (char *)PyMem_MALLOC(n)) == NULL)
     118           0 :         return NULL;
     119           0 :     fflush(sys_stdout);
     120           0 :     if (prompt)
     121           0 :         fprintf(stderr, "%s", prompt);
     122           0 :     fflush(stderr);
     123           0 :     switch (my_fgets(p, (int)n, sys_stdin)) {
     124             :     case 0: /* Normal case */
     125           0 :         break;
     126             :     case 1: /* Interrupt */
     127           0 :         PyMem_FREE(p);
     128           0 :         return NULL;
     129             :     case -1: /* EOF */
     130             :     case -2: /* Error */
     131             :     default: /* Shouldn't happen */
     132           0 :         *p = '\0';
     133           0 :         break;
     134             :     }
     135           0 :     n = strlen(p);
     136           0 :     while (n > 0 && p[n-1] != '\n') {
     137           0 :         size_t incr = n+2;
     138           0 :         p = (char *)PyMem_REALLOC(p, n + incr);
     139           0 :         if (p == NULL)
     140           0 :             return NULL;
     141           0 :         if (incr > INT_MAX) {
     142           0 :             PyErr_SetString(PyExc_OverflowError, "input line too long");
     143             :         }
     144           0 :         if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
     145           0 :             break;
     146           0 :         n += strlen(p+n);
     147             :     }
     148           0 :     return (char *)PyMem_REALLOC(p, n+1);
     149             : }
     150             : 
     151             : 
     152             : /* By initializing this function pointer, systems embedding Python can
     153             :    override the readline function.
     154             : 
     155             :    Note: Python expects in return a buffer allocated with PyMem_Malloc. */
     156             : 
     157             : char *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *);
     158             : 
     159             : 
     160             : /* Interface used by tokenizer.c and bltinmodule.c */
     161             : 
     162             : char *
     163           0 : PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
     164             : {
     165             :     char *rv;
     166             : 
     167           0 :     if (_PyOS_ReadlineTState == PyThreadState_GET()) {
     168           0 :         PyErr_SetString(PyExc_RuntimeError,
     169             :                         "can't re-enter readline");
     170           0 :         return NULL;
     171             :     }
     172             : 
     173             : 
     174           0 :     if (PyOS_ReadlineFunctionPointer == NULL) {
     175             : #ifdef __VMS
     176             :         PyOS_ReadlineFunctionPointer = vms__StdioReadline;
     177             : #else
     178           0 :         PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
     179             : #endif
     180             :     }
     181             : 
     182             : #ifdef WITH_THREAD
     183           0 :     if (_PyOS_ReadlineLock == NULL) {
     184           0 :         _PyOS_ReadlineLock = PyThread_allocate_lock();
     185             :     }
     186             : #endif
     187             : 
     188           0 :     _PyOS_ReadlineTState = PyThreadState_GET();
     189           0 :     Py_BEGIN_ALLOW_THREADS
     190             : #ifdef WITH_THREAD
     191           0 :     PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
     192             : #endif
     193             : 
     194             :     /* This is needed to handle the unlikely case that the
     195             :      * interpreter is in interactive mode *and* stdin/out are not
     196             :      * a tty.  This can happen, for example if python is run like
     197             :      * this: python -i < test1.py
     198             :      */
     199           0 :     if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
     200           0 :         rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
     201             :     else
     202           0 :         rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
     203             :                                              prompt);
     204           0 :     Py_END_ALLOW_THREADS
     205             : 
     206             : #ifdef WITH_THREAD
     207           0 :     PyThread_release_lock(_PyOS_ReadlineLock);
     208             : #endif
     209             : 
     210           0 :     _PyOS_ReadlineTState = NULL;
     211             : 
     212           0 :     return rv;
     213             : }

Generated by: LCOV version 1.10