blob: dd00077d0ee839e58c70504f28ff3414d8d963c1 [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#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
Guido van Rossum6fa63431993-12-24 10:36:57 +000039#include <stdio.h>
40#include <string.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <errno.h>
Guido van Rossum6fa63431993-12-24 10:36:57 +000042
Guido van Rossumb6775db1994-08-01 11:34:53 +000043#include "myproto.h"
Guido van Rossum6fa63431993-12-24 10:36:57 +000044#include "mymalloc.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000045#include "intrcheck.h"
Guido van Rossum6fa63431993-12-24 10:36:57 +000046
Guido van Rossumb6775db1994-08-01 11:34:53 +000047#ifdef WITH_READLINE
Guido van Rossum6fa63431993-12-24 10:36:57 +000048
49extern char *readline();
50
51#include <setjmp.h>
52#include <signal.h>
53
54static jmp_buf jbuf;
55
56/* ARGSUSED */
57static RETSIGTYPE
58onintr(sig)
59 int sig;
60{
61 longjmp(jbuf, 1);
62}
63
Guido van Rossumb6775db1994-08-01 11:34:53 +000064#else /* !WITH_READLINE */
65
66/* This function restarts a fgets() after an EINTR error occurred
67 except if intrcheck() returns true. */
68
69static int
70my_fgets(buf, len, fp)
71 char *buf;
72 int len;
73 FILE *fp;
74{
75 char *p;
76 for (;;) {
77 errno = 0;
78 p = fgets(buf, len, fp);
79 if (p != NULL)
80 return 0; /* No error */
81 if (feof(fp)) {
82 return -1; /* EOF */
83 }
84#ifdef EINTR
85 if (errno == EINTR) {
86 if (intrcheck()) {
87 return 1; /* Interrupt */
88 }
89 continue;
90 }
91#endif
92 if (intrcheck()) {
93 return 1; /* Interrupt */
94 }
95 return -2; /* Error */
96 }
97 /* NOTREACHED */
98}
99
100#endif /* WITH_READLINE */
101
Guido van Rossum6fa63431993-12-24 10:36:57 +0000102
103char *
104my_readline(prompt)
105 char *prompt;
106{
107 int n;
108 char *p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000109#ifdef WITH_READLINE
Guido van Rossum6fa63431993-12-24 10:36:57 +0000110 RETSIGTYPE (*old_inthandler)();
111 static int been_here;
112 if (!been_here) {
113 /* Force rebind of TAB to insert-tab */
114 extern int rl_insert();
115 rl_bind_key('\t', rl_insert);
116 been_here++;
117 }
118 old_inthandler = signal(SIGINT, onintr);
119 if (setjmp(jbuf)) {
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000120#ifdef HAVE_SIGRELSE
121 /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */
122 sigrelse(SIGINT);
123#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000124 signal(SIGINT, old_inthandler);
125 return NULL;
126 }
127 p = readline(prompt);
128 signal(SIGINT, old_inthandler);
129 if (p == NULL) {
130 p = malloc(1);
131 if (p != NULL)
132 *p = '\0';
133 return p;
134 }
135 n = strlen(p);
136 if (n > 0)
137 add_history(p);
138 if ((p = realloc(p, n+2)) != NULL) {
139 p[n] = '\n';
140 p[n+1] = '\0';
141 }
142 return p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143#else /* !WITH_READLINE */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000144 n = 100;
145 if ((p = malloc(n)) == NULL)
146 return NULL;
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000147 fflush(stdout);
Guido van Rossum6fa63431993-12-24 10:36:57 +0000148 if (prompt)
149 fprintf(stderr, "%s", prompt);
Guido van Rossumc7fea2f1996-01-12 01:30:55 +0000150 fflush(stderr);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000151 switch (my_fgets(p, n, stdin)) {
152 case 0: /* Normal case */
153 break;
154 case 1: /* Interrupt */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000155 free(p);
156 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157 case -1: /* EOF */
158 case -2: /* Error */
159 default: /* Shouldn't happen */
160 *p = '\0';
161 break;
Guido van Rossum6fa63431993-12-24 10:36:57 +0000162 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000163#ifdef MPW
164 /* Hack for MPW C where the prompt comes right back in the input */
165 /* XXX (Actually this would be rather nice on most systems...) */
166 n = strlen(prompt);
167 if (strncmp(p, prompt, n) == 0)
168 memmove(p, p + n, strlen(p) - n + 1);
169#endif
Guido van Rossum6fa63431993-12-24 10:36:57 +0000170 n = strlen(p);
171 while (n > 0 && p[n-1] != '\n') {
172 int incr = n+2;
173 p = realloc(p, n + incr);
174 if (p == NULL)
175 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176 if (my_fgets(p+n, incr, stdin) != 0)
Guido van Rossum6fa63431993-12-24 10:36:57 +0000177 break;
178 n += strlen(p+n);
179 }
180 return realloc(p, n+1);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#endif /* !WITH_READLINE */
Guido van Rossum6fa63431993-12-24 10:36:57 +0000182}