1/*
2 * input.c - read and store lines of input
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30
31/*
32 * This file deals with input buffering, supplying characters to the
33 * history expansion code a character at a time.  Input is stored on a
34 * stack, which allows insertion of strings into the input, possibly with
35 * flags marking the end of alias expansion, with minimal copying of
36 * strings.  The same stack is used to record the fact that the input
37 * is a history or alias expansion and to store the alias while it is in use.
38 *
39 * Input is taken either from zle, if appropriate, or read directly from
40 * the input file, or may be supplied by some other part of the shell (such
41 * as `eval' or $(...) substitution).  In the last case, it should be
42 * supplied by pushing a new level onto the stack, via inpush(input_string,
43 * flag, alias); if the current input really needs to be altered, use
44 * inputsetline(input_string, flag).  `Flag' can include or's of INP_FREE
45 * (if the input string is to be freed when used), INP_CONT (if the input
46 * is to continue onto what's already in the input queue), INP_ALIAS
47 * (push supplied alias onto stack) or INP_HIST (ditto, but used to
48 * mark history expansion).  `alias' is ignored unless INP_ALIAS or
49 * INP_HIST is supplied.  INP_ALIAS is always set if INP_HIST is.
50 *
51 * Note that the input string is itself used as the input buffer: it is not
52 * copied, nor is it every written back to, so using a constant string
53 * should work.  Consequently, when passing areas of memory from the heap
54 * it is necessary that that heap last as long as the operation of reading
55 * the string.  After the string is read, the stack should be popped with
56 * inpop(), which effectively flushes any unread input as well as restoring
57 * the previous input state.
58 *
59 * The internal flag INP_ALCONT shows that the stack element was pushed
60 * by an alias expansion; it should not be needed elsewhere.
61 *
62 * The global variable inalmore is set to indicate aliases should
63 * continue to be expanded because the last alias expansion ended
64 * in a space.  It is only reset after a complete word was read
65 * without expanding a new alias, in exalias().
66 *
67 * PWS 1996/12/10
68 */
69
70#ifdef HAVE_STDIO_H
71#include <stdio.h>
72#endif
73
74#include "zsh.mdh"
75#include "input.pro"
76
77/* the shell input fd */
78
79/**/
80int SHIN;
81
82/* buffered shell input for non-interactive shells */
83
84/**/
85FILE *bshin;
86
87/* != 0 means we are reading input from a string */
88
89/**/
90int strin;
91
92/* total # of characters waiting to be read. */
93
94/**/
95mod_export int inbufct;
96
97/* the flags controlling the input routines in input.c: see INP_* in zsh.h */
98
99/**/
100int inbufflags;
101
102static char *inbuf;		/* Current input buffer */
103static char *inbufptr;		/* Pointer into input buffer */
104static char *inbufpush;		/* Character at which to re-push alias */
105static int inbufleft;		/* Characters left in current input
106				   stack element */
107
108
109 /* Input must be stacked since the input queue is used by
110  * various different parts of the shell.
111  */
112
113struct instacks {
114    char *buf, *bufptr;
115    Alias alias;
116    int bufleft, bufct, flags;
117};
118static struct instacks *instack, *instacktop;
119/*
120 * Input stack size.  We need to push the stack for aliases, history
121 * expansion, and reading from internal strings: only if these operations
122 * are nested do we need more than one extra level.  Thus we shouldn't need
123 * too much space as a rule.  Initially, INSTACK_INITIAL is allocated; if
124 * more is required, an extra INSTACK_EXPAND is added each time.
125 */
126#define INSTACK_INITIAL	4
127#define INSTACK_EXPAND	4
128
129static int instacksz = INSTACK_INITIAL;
130
131/* Read a line from bshin.  Convert tokens and   *
132 * null characters to Meta c^32 character pairs. */
133
134/**/
135mod_export char *
136shingetline(void)
137{
138    char *line = NULL;
139    int ll = 0;
140    int c;
141    char buf[BUFSIZ];
142    char *p;
143
144    p = buf;
145    for (;;) {
146	do {
147	    errno = 0;
148	    c = fgetc(bshin);
149	} while (c < 0 && errno == EINTR);
150	if (c < 0 || c == '\n') {
151	    if (c == '\n')
152		*p++ = '\n';
153	    if (p > buf) {
154		*p++ = '\0';
155		line = zrealloc(line, ll + (p - buf));
156		memcpy(line + ll, buf, p - buf);
157	    }
158	    return line;
159	}
160	if (imeta(c)) {
161	    *p++ = Meta;
162	    *p++ = c ^ 32;
163	} else
164	    *p++ = c;
165	if (p >= buf + BUFSIZ - 1) {
166	    line = zrealloc(line, ll + (p - buf) + 1);
167	    memcpy(line + ll, buf, p - buf);
168	    ll += p - buf;
169	    line[ll] = '\0';
170	    p = buf;
171	}
172    }
173}
174
175/* Get the next character from the input.
176 * Will call inputline() to get a new line where necessary.
177 */
178
179/**/
180int
181ingetc(void)
182{
183    int lastc;
184
185    if (lexstop)
186	return ' ';
187    for (;;) {
188	if (inbufleft) {
189	    inbufleft--;
190	    inbufct--;
191	    if (itok(lastc = STOUC(*inbufptr++)))
192		continue;
193	    if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n')
194		lineno++;
195	    return lastc;
196	}
197
198	/*
199	 * See if we have reached the end of input
200	 * (due to an error, or to reading from a single string).
201	 * Check the remaining characters left, since if there aren't
202	 * any we don't want to pop the stack---it'll mark any aliases
203	 * as not in use before we've finished processing.
204	 */
205	if (!inbufct && (strin || errflag)) {
206	    lexstop = 1;
207	    return ' ';
208	}
209	/* If the next element down the input stack is a continuation of
210	 * this, use it.
211	 */
212	if (inbufflags & INP_CONT) {
213	    inpoptop();
214	    continue;
215	}
216	/* As a last resort, get some more input */
217	if (inputline())
218	    return ' ';
219    }
220}
221
222/* Read a line from the current command stream and store it as input */
223
224/**/
225static int
226inputline(void)
227{
228    char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL;
229    int context = ZLCON_LINE_START;
230
231    /* If reading code interactively, work out the prompts. */
232    if (interact && isset(SHINSTDIN)) {
233	if (!isfirstln) {
234	    ingetcpmptl = &prompt2;
235	    if (rprompt2)
236		ingetcpmptr = &rprompt2;
237	    context = ZLCON_LINE_CONT;
238	}
239	else {
240	    ingetcpmptl = &prompt;
241	    if (rprompt)
242		ingetcpmptr = &rprompt;
243	}
244    }
245    if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
246	/*
247	 * If not using zle, read the line straight from the input file.
248	 * Possibly we don't get the whole line at once:  in that case,
249	 * we get another chunk with the next call to inputline().
250	 */
251
252	if (interact && isset(SHINSTDIN)) {
253	    /*
254	     * We may still be interactive (e.g. running under emacs),
255	     * so output a prompt if necessary.  We don't know enough
256	     * about the input device to be able to handle an rprompt,
257	     * though.
258	     */
259	    char *pptbuf;
260	    int pptlen;
261	    pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL,
262					   0, NULL, NULL, NULL), &pptlen);
263	    write_loop(2, pptbuf, pptlen);
264	    free(pptbuf);
265	}
266	ingetcline = shingetline();
267    } else {
268	/*
269	 * Since we may have to read multiple lines before getting
270	 * a complete piece of input, we tell zle not to restore the
271	 * original tty settings after reading each chunk.  Instead,
272	 * this is done when the history mechanism for the current input
273	 * terminates, which is not until we have the whole input.
274	 * This is supposed to minimise problems on systems that clobber
275	 * typeahead when the terminal settings are altered.
276	 *                     pws 1998/03/12
277	 */
278	int flags = ZLRF_HISTORY|ZLRF_NOSETTY;
279	if (isset(IGNOREEOF))
280	    flags |= ZLRF_IGNOREEOF;
281	ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr,
282			      flags, context);
283	histdone |= HISTFLAG_SETTY;
284    }
285    if (!ingetcline) {
286	return lexstop = 1;
287    }
288    if (errflag) {
289	free(ingetcline);
290	return lexstop = errflag = 1;
291    }
292    if (isset(VERBOSE)) {
293	/* Output the whole line read so far. */
294	zputs(ingetcline, stderr);
295	fflush(stderr);
296    }
297    if (keyboardhackchar && *ingetcline &&
298	ingetcline[strlen(ingetcline) - 1] == '\n' &&
299	interact && isset(SHINSTDIN) &&
300	SHTTY != -1 && ingetcline[1])
301    {
302	char *stripptr = ingetcline + strlen(ingetcline) - 2;
303	if (*stripptr == keyboardhackchar) {
304	    /* Junk an unwanted character at the end of the line.
305	       (key too close to return key) */
306	    int ct = 1;  /* force odd */
307	    char *ptr;
308
309	    if (keyboardhackchar == '\'' || keyboardhackchar == '"' ||
310		keyboardhackchar == '`') {
311		/*
312		 * for the chars above, also require an odd count before
313		 * junking
314		 */
315		for (ct = 0, ptr = ingetcline; *ptr; ptr++)
316		    if (*ptr == keyboardhackchar)
317			ct++;
318	    }
319	    if (ct & 1) {
320		stripptr[0] = '\n';
321		stripptr[1] = '\0';
322	    }
323	}
324    }
325    isfirstch = 1;
326    /* Put this into the input channel. */
327    inputsetline(ingetcline, INP_FREE);
328
329    return 0;
330}
331
332/*
333 * Put a string in the input queue:
334 * inbuf is only freeable if the flags include INP_FREE.
335 */
336
337/**/
338static void
339inputsetline(char *str, int flags)
340{
341    if ((inbufflags & INP_FREE) && inbuf) {
342	free(inbuf);
343    }
344    inbuf = inbufptr = str;
345    inbufleft = strlen(inbuf);
346
347    /*
348     * inbufct must reflect the total number of characters left,
349     * as it used by other parts of the shell, so we need to take account
350     * of whether the input stack continues, and whether there
351     * is an extra space to add on at the end.
352     */
353    if (flags & INP_CONT)
354	inbufct += inbufleft;
355    else
356	inbufct = inbufleft;
357    inbufflags = flags;
358}
359
360/*
361 * Backup one character of the input.
362 * The last character can always be backed up, provided we didn't just
363 * expand an alias or a history reference.
364 * In fact, the character is ignored and the previous character is used.
365 * (If that's wrong, the bug is in the calling code.  Use the #ifdef DEBUG
366 * code to check.)
367 */
368
369/**/
370void
371inungetc(int c)
372{
373    if (!lexstop) {
374	if (inbufptr != inbuf) {
375#ifdef DEBUG
376	    /* Just for debugging: enable only if foul play suspected. */
377	    if (inbufptr[-1] != (char) c)
378		fprintf(stderr, "Warning: backing up wrong character.\n");
379#endif
380	    /* Just decrement the pointer:  if it's not the same
381	     * character being pushed back, we're in trouble anyway.
382	     */
383	    inbufptr--;
384	    inbufct++;
385	    inbufleft++;
386	    if (((inbufflags & INP_LINENO) || !strin) && c == '\n')
387		lineno--;
388	}
389#ifdef DEBUG
390        else if (!(inbufflags & INP_CONT)) {
391	    /* Just for debugging */
392	    fprintf(stderr, "Attempt to inungetc() at start of input.\n");
393	}
394#endif
395	else {
396	    /*
397	     * The character is being backed up from a previous input stack
398	     * layer.  However, there was an expansion in the middle, so we
399	     * can't back up where we want to.  Instead, we just push it
400	     * onto the input stack as an extra character.
401	     */
402	    char *cback = (char *)zshcalloc(2);
403	    cback[0] = (char) c;
404	    inpush(cback, INP_FREE|INP_CONT, NULL);
405	}
406	/* If we are back at the start of a segment,
407	 * we may need to restore an alias popped from the stack.
408	 * Note this may be a dummy (history expansion) entry.
409	 */
410	if (inbufptr == inbufpush && inbufflags & INP_ALCONT) {
411	    /*
412	     * Go back up the stack over all entries which were alias
413	     * expansions and were pushed with nothing remaining to read.
414	     */
415	    do {
416		if (instacktop->alias)
417		    instacktop->alias->inuse = 1;
418		instacktop++;
419	    } while ((instacktop->flags & INP_ALCONT) && !instacktop->bufleft);
420	    inbufflags = INP_CONT|INP_ALIAS;
421	    inbufleft = 0;
422	    inbuf = inbufptr = "";
423	}
424    }
425}
426
427/* stuff a whole file into the input queue and print it */
428
429/**/
430int
431stuff(char *fn)
432{
433    FILE *in;
434    char *buf;
435    off_t len;
436
437    if (!(in = fopen(unmeta(fn), "r"))) {
438	zerr("can't open %s", fn);
439	return 1;
440    }
441    fseek(in, 0, 2);
442    len = ftell(in);
443    fseek(in, 0, 0);
444    buf = (char *)zalloc(len + 1);
445    if (!(fread(buf, len, 1, in))) {
446	zerr("read error on %s", fn);
447	fclose(in);
448	zfree(buf, len + 1);
449	return 1;
450    }
451    fclose(in);
452    buf[len] = '\0';
453    fwrite(buf, len, 1, stderr);
454    fflush(stderr);
455    inputsetline(metafy(buf, len, META_REALLOC), INP_FREE);
456    return 0;
457}
458
459/* flush input queue */
460
461/**/
462void
463inerrflush(void)
464{
465    while (!lexstop && inbufct)
466	ingetc();
467}
468
469/* Set some new input onto a new element of the input stack */
470
471/**/
472mod_export void
473inpush(char *str, int flags, Alias inalias)
474{
475    if (!instack) {
476	/* Initial stack allocation */
477	instack = (struct instacks *)zalloc(instacksz*sizeof(struct instacks));
478	instacktop = instack;
479    }
480
481    instacktop->buf = inbuf;
482    instacktop->bufptr = inbufptr;
483    instacktop->bufleft = inbufleft;
484    instacktop->bufct = inbufct;
485    inbufflags &= ~INP_ALCONT;
486    if (flags & (INP_ALIAS|INP_HIST)) {
487	/*
488	 * Text is expansion for history or alias, so continue
489	 * back to old level when done.  Also mark stack top
490	 * as alias continuation so as to back up if necessary,
491	 * and mark alias as in use.
492	 */
493	flags |= INP_CONT|INP_ALIAS;
494	instacktop->flags = inbufflags | INP_ALCONT;
495	if ((instacktop->alias = inalias))
496	    inalias->inuse = 1;
497    } else {
498	/* If we are continuing an alias expansion, record the alias
499	 * expansion in new set of flags (do we need this?)
500	 */
501	if (((instacktop->flags = inbufflags) & INP_ALIAS) &&
502	    (flags & INP_CONT))
503	    flags |= INP_ALIAS;
504    }
505
506    instacktop++;
507    if (instacktop == instack + instacksz) {
508	/* Expand the stack */
509	instack = (struct instacks *)
510	    realloc(instack,
511		    (instacksz + INSTACK_EXPAND)*sizeof(struct instacks));
512	instacktop = instack + instacksz;
513	instacksz += INSTACK_EXPAND;
514    }
515    /*
516     * We maintain the entry above the highest one with real
517     * text as a flag to inungetc() that it can stop re-pushing the stack.
518     */
519    instacktop->flags = 0;
520
521    inbufpush = inbuf = NULL;
522
523    inputsetline(str, flags);
524}
525
526/* Remove the top element of the stack */
527
528/**/
529static void
530inpoptop(void)
531{
532    if (inbuf && (inbufflags & INP_FREE))
533	free(inbuf);
534
535    instacktop--;
536
537    inbuf = instacktop->buf;
538    inbufptr = inbufpush = instacktop->bufptr;
539    inbufleft = instacktop->bufleft;
540    inbufct = instacktop->bufct;
541    inbufflags = instacktop->flags;
542
543    if (!(inbufflags & INP_ALCONT))
544	return;
545
546    if (instacktop->alias) {
547	char *t = instacktop->alias->text;
548	/* a real alias:  mark it as unused. */
549	instacktop->alias->inuse = 0;
550	if (*t && t[strlen(t) - 1] == ' ') {
551	    inalmore = 1;
552	    histbackword();
553	}
554    }
555}
556
557/* Remove the top element of the stack and all its continuations. */
558
559/**/
560mod_export void
561inpop(void)
562{
563    int remcont;
564
565    do {
566	remcont = inbufflags & INP_CONT;
567
568	inpoptop();
569    } while (remcont);
570}
571
572/*
573 * Expunge any aliases from the input stack; they shouldn't appear
574 * in the history and need to be flushed explicitly when we encounter
575 * an error.
576 */
577
578/**/
579void
580inpopalias(void)
581{
582    while (inbufflags & INP_ALIAS)
583	inpoptop();
584}
585
586
587/*
588 * Get pointer to remaining string to read.
589 */
590
591/**/
592char *
593ingetptr(void)
594{
595    return inbufptr;
596}
597