blob: 556caac2c4961d26f44161c1963aca870ee212d2 [file] [log] [blame]
Guido van Rossum6fa63431993-12-24 10:36:57 +00001/***********************************************************
Guido van Rossumb9f8d6e1995-01-04 19:08:09 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum6fa63431993-12-24 10:36:57 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Readline interface for tokenizer.c.
26 By default, we have a super simple my_readline function.
27 Optionally, we can use the GNU readline library (to be found in the
28 bash distribution).
29 my_readline() has a different return value from GNU readline():
30 - NULL if an interrupt occurred or if an error occurred
31 - a malloc'ed empty string if EOF was read
32 - a malloc'ed string ending in \n normally
33*/
34
Guido van Rossumb6775db1994-08-01 11:34:53 +000035#include "config.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Guido van Rossum6fa63431993-12-24 10:36:57 +000037#include <stdio.h>
38#include <string.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#include <errno.h>
Guido van Rossum6fa63431993-12-24 10:36:57 +000040
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include "myproto.h"
Guido van Rossum6fa63431993-12-24 10:36:57 +000042#include "mymalloc.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000043#include "intrcheck.h"
Guido van Rossum6fa63431993-12-24 10:36:57 +000044
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#ifdef WITH_READLINE
Guido van Rossum6fa63431993-12-24 10:36:57 +000046
47extern char *readline();
Guido van Rossum0bc253d1996-09-13 04:09:26 +000048extern int rl_initialize();
49extern int rl_insert();
50extern char *rl_readline_name;
Guido van Rossum6fa63431993-12-24 10:36:57 +000051
52#include <setjmp.h>
53#include <signal.h>
54
55static jmp_buf jbuf;
56
57/* ARGSUSED */
58static RETSIGTYPE
59onintr(sig)
60 int sig;
61{
62 longjmp(jbuf, 1);
63}
64
Guido van Rossumb6775db1994-08-01 11:34:53 +000065#else /* !WITH_READLINE */
66
67/* This function restarts a fgets() after an EINTR error occurred
68 except if intrcheck() returns true. */
69
70static int
71my_fgets(buf, len, fp)
72 char *buf;
73 int len;
74 FILE *fp;
75{
76 char *p;
77 for (;;) {
78 errno = 0;
79 p = fgets(buf, len, fp);
80 if (p != NULL)
81 return 0; /* No error */
82 if (feof(fp)) {
83 return -1; /* EOF */
84 }
85#ifdef EINTR
86 if (errno == EINTR) {
87 if (intrcheck()) {
88 return 1; /* Interrupt */
89 }
90 continue;
91 }
92#endif
93 if (intrcheck()) {
94 return 1; /* Interrupt */
95 }
96 return -2; /* Error */
97 }
98 /* NOTREACHED */
99}
100
101#endif /* WITH_READLINE */
102
Guido van Rossum6fa63431993-12-24 10:36:57 +0000103
Guido van Rossum9ea917e1996-05-24 20:44:12 +0000104#ifdef WITH_READLINE
Guido van Rossumadf87691996-04-09 02:45:31 +0000105void
106PyOS_ReadlineInit()
107{
108 static int been_here;
109 if (!been_here) {
110 /* Force rebind of TAB to insert-tab */
Guido van Rossum0bc253d1996-09-13 04:09:26 +0000111 rl_readline_name = "python";
112 rl_initialize();
Guido van Rossumadf87691996-04-09 02:45:31 +0000113 rl_bind_key('\t', rl_insert);
114 been_here++;
115 }
116}
Guido van Rossum9ea917e1996-05-24 20:44:12 +0000117#endif
Guido van Rossumadf87691996-04-09 02:45:31 +0000118
119
Guido van Rossum6fa63431993-12-24 10:36:57 +0000120char *
121my_readline(prompt)
122 char *prompt;
123{
124 int n;
125 char *p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000126#ifdef WITH_READLINE
Guido van Rossum6fa63431993-12-24 10:36:57 +0000127 RETSIGTYPE (*old_inthandler)();
Guido van Rossumadf87691996-04-09 02:45:31 +0000128 PyOS_ReadlineInit();
Guido van Rossum6fa63431993-12-24 10:36:57 +0000129 old_inthandler = signal(SIGINT, onintr);
130 if (setjmp(jbuf)) {
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000131#ifdef HAVE_SIGRELSE
132 /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
133 sigrelse(SIGINT);
134#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000135 signal(SIGINT, old_inthandler);
136 return NULL;
137 }
138 p = readline(prompt);
139 signal(SIGINT, old_inthandler);
140 if (p == NULL) {
141 p = malloc(1);
142 if (p != NULL)
143 *p = '\0';
144 return p;
145 }
146 n = strlen(p);
147 if (n > 0)
148 add_history(p);
149 if ((p = realloc(p, n+2)) != NULL) {
150 p[n] = '\n';
151 p[n+1] = '\0';
152 }
153 return p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154#else /* !WITH_READLINE */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000155 n = 100;
156 if ((p = malloc(n)) == NULL)
157 return NULL;
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000158 fflush(stdout);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000159 if (prompt)
160 fprintf(stderr, "%s", prompt);
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000161 fflush(stderr);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162 switch (my_fgets(p, n, stdin)) {
163 case 0: /* Normal case */
164 break;
165 case 1: /* Interrupt */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000166 free(p);
167 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168 case -1: /* EOF */
169 case -2: /* Error */
170 default: /* Shouldn't happen */
171 *p = '\0';
172 break;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000173 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef MPW
175 /* Hack for MPW C where the prompt comes right back in the input */
176 /* XXX (Actually this would be rather nice on most systems...) */
177 n = strlen(prompt);
178 if (strncmp(p, prompt, n) == 0)
179 memmove(p, p + n, strlen(p) - n + 1);
180#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000181 n = strlen(p);
182 while (n > 0 && p[n-1] != '\n') {
183 int incr = n+2;
184 p = realloc(p, n + incr);
185 if (p == NULL)
186 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187 if (my_fgets(p+n, incr, stdin) != 0)
Guido van Rossum6fa63431993-12-24 10:36:57 +0000188 break;
189 n += strlen(p+n);
190 }
191 return realloc(p, n+1);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#endif /* !WITH_READLINE */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000193}