home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Parser / myreadline.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  2.7 KB  |  122 lines

  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.  
  14. int (*PyOS_InputHook)(void) = NULL;
  15.  
  16. /* This function restarts a fgets() after an EINTR error occurred
  17.    except if PyOS_InterruptOccurred() returns true. */
  18.  
  19. static int
  20. my_fgets(char *buf, int len, FILE *fp)
  21. {
  22.     char *p;
  23.     for (;;) {
  24.         if (PyOS_InputHook != NULL)
  25.             (void)(PyOS_InputHook)();
  26.         errno = 0;
  27.         p = fgets(buf, len, fp);
  28.         if (p != NULL)
  29.             return 0; /* No error */
  30.         if (feof(fp)) {
  31.             return -1; /* EOF */
  32.         }
  33. #ifdef EINTR
  34.         if (errno == EINTR) {
  35.             if (PyOS_InterruptOccurred()) {
  36.                 return 1; /* Interrupt */
  37.             }
  38.             continue;
  39.         }
  40. #endif
  41.         if (PyOS_InterruptOccurred()) {
  42.             return 1; /* Interrupt */
  43.         }
  44.         return -2; /* Error */
  45.     }
  46.     /* NOTREACHED */
  47. }
  48.  
  49.  
  50. /* Readline implementation using fgets() */
  51.  
  52. char *
  53. PyOS_StdioReadline(char *prompt)
  54. {
  55.     size_t n;
  56.     char *p;
  57.     n = 100;
  58.     if ((p = PyMem_MALLOC(n)) == NULL)
  59.         return NULL;
  60.     fflush(stdout);
  61.     if (prompt)
  62.         fprintf(stderr, "%s", prompt);
  63.     fflush(stderr);
  64.     switch (my_fgets(p, (int)n, stdin)) {
  65.     case 0: /* Normal case */
  66.         break;
  67.     case 1: /* Interrupt */
  68.         PyMem_FREE(p);
  69.         return NULL;
  70.     case -1: /* EOF */
  71.     case -2: /* Error */
  72.     default: /* Shouldn't happen */
  73.         *p = '\0';
  74.         break;
  75.     }
  76. #ifdef MPW
  77.     /* Hack for MPW C where the prompt comes right back in the input */
  78.     /* XXX (Actually this would be rather nice on most systems...) */
  79.     n = strlen(prompt);
  80.     if (strncmp(p, prompt, n) == 0)
  81.         memmove(p, p + n, strlen(p) - n + 1);
  82. #endif
  83.     n = strlen(p);
  84.     while (n > 0 && p[n-1] != '\n') {
  85.         size_t incr = n+2;
  86.         p = PyMem_REALLOC(p, n + incr);
  87.         if (p == NULL)
  88.             return NULL;
  89.         if (incr > INT_MAX) {
  90.             PyErr_SetString(PyExc_OverflowError, "input line too long");
  91.         }
  92.         if (my_fgets(p+n, (int)incr, stdin) != 0)
  93.             break;
  94.         n += strlen(p+n);
  95.     }
  96.     return PyMem_REALLOC(p, n+1);
  97. }
  98.  
  99.  
  100. /* By initializing this function pointer, systems embedding Python can
  101.    override the readline function.
  102.  
  103.    Note: Python expects in return a buffer allocated with PyMem_Malloc. */
  104.  
  105. char *(*PyOS_ReadlineFunctionPointer)(char *);
  106.  
  107.  
  108. /* Interface used by tokenizer.c and bltinmodule.c */
  109.  
  110. char *
  111. PyOS_Readline(char *prompt)
  112. {
  113.     char *rv;
  114.     if (PyOS_ReadlineFunctionPointer == NULL) {
  115.             PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
  116.     }
  117.     Py_BEGIN_ALLOW_THREADS
  118.     rv = (*PyOS_ReadlineFunctionPointer)(prompt);
  119.     Py_END_ALLOW_THREADS
  120.     return rv;
  121. }
  122.