2222 */
2323
2424Input * input ;
25- char * prompt , * prompt2 ;
26-
2725Boolean ignoreeof = FALSE;
2826
2927
@@ -103,11 +101,8 @@ extern void unget(Input *in, int c) {
103101/* get -- get a character, filter out nulls */
104102static int get (Input * in ) {
105103 int c ;
106- Boolean uf = (in -> fill == ungetfill );
107104 while ((c = (in -> buf < in -> bufend ? * in -> buf ++ : (* in -> fill )(in ))) == '\0' )
108105 warn ("null character ignored" );
109- if (!uf && c != EOF )
110- addhistbuffer ((char )c );
111106 return c ;
112107}
113108
@@ -131,58 +126,9 @@ static int eoffill(Input UNUSED *in) {
131126 return EOF ;
132127}
133128
134- #if HAVE_READLINE
135- /* callreadline -- readline wrapper */
136- static char * callreadline (char * prompt0 ) {
137- char * volatile prompt = prompt0 ;
138- char * r ;
139- if (prompt == NULL )
140- prompt = "" ; /* bug fix for readline 2.0 */
141- rlsetup (FALSE);
142- interrupted = FALSE;
143- if (!setjmp (slowlabel )) {
144- slow = TRUE;
145- r = interrupted ? NULL : readline (prompt );
146- if (interrupted )
147- errno = EINTR ;
148- } else {
149- r = NULL ;
150- errno = EINTR ;
151- }
152- slow = FALSE;
153- SIGCHK ();
154- return r ;
155- }
156- #endif
157-
158129/* fdfill -- fill input buffer by reading from a file descriptor */
159130static int fdfill (Input * in ) {
160131 long nread ;
161- assert (in -> buf == in -> bufend );
162- assert (in -> fd >= 0 );
163-
164- #if HAVE_READLINE
165- if (in -> runflags & run_interactive && in -> fd == 0 ) {
166- char * rlinebuf = NULL ;
167- do {
168- rlinebuf = callreadline (prompt );
169- } while (rlinebuf == NULL && errno == EINTR );
170-
171- if (rlinebuf == NULL )
172- nread = 0 ;
173- else {
174- nread = strlen (rlinebuf ) + 1 ;
175- if (in -> buflen < (unsigned int )nread ) {
176- while (in -> buflen < (unsigned int )nread )
177- in -> buflen *= 2 ;
178- in -> bufbegin = erealloc (in -> bufbegin , in -> buflen );
179- }
180- memcpy (in -> bufbegin , rlinebuf , nread - 1 );
181- in -> bufbegin [nread - 1 ] = '\n' ;
182- efree (rlinebuf );
183- }
184- } else
185- #endif
186132 do {
187133 nread = eread (in -> fd , (char * ) in -> bufbegin , in -> buflen );
188134 SIGCHK ();
@@ -205,13 +151,69 @@ static int fdfill(Input *in) {
205151 return * in -> buf ++ ;
206152}
207153
154+ static List * fillcmd = NULL ;
155+
156+ static int cmdfill (Input * in ) {
157+ char * read ;
158+ List * result ;
159+ size_t nread ;
160+ int oldf ;
161+
162+ assert (in -> buf == in -> bufend );
163+ assert (in -> fd >= 0 );
164+
165+ if (fillcmd == NULL )
166+ return fdfill (in );
167+
168+ oldf = dup (0 );
169+ if (dup2 (in -> fd , 0 ) == -1 )
170+ fail ("$&parse" , "dup2: %s" , esstrerror (errno ));
171+
172+ ExceptionHandler
173+
174+ result = eval (fillcmd , NULL , 0 );
175+
176+ CatchException (e )
177+
178+ mvfd (oldf , 0 );
179+ throw (e );
180+
181+ EndExceptionHandler
182+
183+ mvfd (oldf , 0 );
184+
185+ if (result == NULL ) { /* eof */
186+ if (!ignoreeof ) {
187+ close (in -> fd );
188+ in -> fd = -1 ;
189+ in -> fill = eoffill ;
190+ in -> runflags &= ~run_interactive ;
191+ }
192+ return EOF ;
193+ }
194+ read = str ("%L\n" , result , " " );
195+
196+ if ((nread = strlen (read )) > in -> buflen ) {
197+ in -> bufbegin = erealloc (in -> bufbegin , nread );
198+ in -> buflen = nread ;
199+ }
200+ memcpy (in -> bufbegin , read , nread );
201+
202+ in -> buf = in -> bufbegin ;
203+ in -> bufend = & in -> buf [nread ];
204+
205+ return * in -> buf ++ ;
206+ }
208207
209208/*
210209 * the input loop
211210 */
212211
213- /* parse -- call yyparse(), but disable garbage collection and catch errors */
214- extern Tree * parse (char * pr1 , char * pr2 ) {
212+
213+ static Boolean parsing = FALSE;
214+
215+ /* parse -- call yyparse() and catch errors */
216+ extern Tree * parse (List * fc ) {
215217 int result ;
216218 assert (error == NULL );
217219
@@ -221,17 +223,26 @@ extern Tree *parse(char *pr1, char *pr2) {
221223 if (ISEOF (input ))
222224 throw (mklist (mkstr ("eof" ), NULL ));
223225
224- #if HAVE_READLINE
225- prompt = (pr1 == NULL ) ? "" : pr1 ;
226- #else
227- if (pr1 != NULL )
228- eprint ("%s" , pr1 );
229- #endif
230- prompt2 = pr2 ;
226+ if (parsing )
227+ fail ("$&parse" , "cannot perform nested parsing" );
228+
229+ fillcmd = fc ;
230+ parsing = TRUE;
231+
232+ ExceptionHandler
233+
234+ result = yyparse ();
235+
236+ CatchException (e )
237+
238+ parsing = FALSE;
239+ fillcmd = NULL ;
240+ throw (e );
241+
242+ EndExceptionHandler
231243
232- gcdisable ();
233- result = yyparse ();
234- gcenable ();
244+ parsing = FALSE;
245+ fillcmd = NULL ;
235246
236247 if (result || error != NULL ) {
237248 char * e ;
@@ -328,7 +339,7 @@ extern List *runfd(int fd, const char *name, int flags) {
328339
329340 memzero (& in , sizeof (Input ));
330341 in .lineno = 1 ;
331- in .fill = fdfill ;
342+ in .fill = cmdfill ;
332343 in .cleanup = fdcleanup ;
333344 in .fd = fd ;
334345 registerfd (& in .fd , TRUE);
@@ -391,7 +402,7 @@ extern Tree *parseinput(Input *in) {
391402 input = in ;
392403
393404 ExceptionHandler
394- result = parse (NULL , NULL );
405+ result = parse (NULL );
395406 if (get (in ) != EOF )
396407 fail ("$&parse" , "more than one value in term" );
397408 CatchException (e )
@@ -439,7 +450,7 @@ extern Boolean isinteractive(void) {
439450}
440451
441452extern Boolean isfromfd (void ) {
442- return input == NULL ? FALSE : (input -> fill == fdfill );
453+ return input == NULL ? FALSE : (input -> fill == fdfill || input -> fill == cmdfill );
443454}
444455
445456
@@ -452,7 +463,6 @@ extern void initinput(void) {
452463 input = NULL ;
453464
454465 /* declare the global roots */
466+ globalroot (& fillcmd );
455467 globalroot (& error ); /* parse errors */
456- globalroot (& prompt ); /* main prompt */
457- globalroot (& prompt2 ); /* secondary prompt */
458468}
0 commit comments