int stuff(char *fn) { FILE *in; char *buf; off_t len; if (!(in = fopen(unmeta(fn), "r"))) { zerr("can't open %s", fn); return 1; } fseek(in, 0, 2); len = ftell(in); fseek(in, 0, 0); buf = (char *)zalloc(len + 1); if (!(fread(buf, len, 1, in))) { zerr("read error on %s", fn); fclose(in); zfree(buf, len + 1); return 1; } fclose(in); buf[len] = '\0'; fwrite(buf, len, 1, stderr); fflush(stderr); inputsetline(metafy(buf, len, META_REALLOC), INP_FREE); return 0; }
mod_export void inpush(char *str, int flags, Alias inalias) { if (!instack) { /* Initial stack allocation */ instack = (struct instacks *)zalloc(instacksz*sizeof(struct instacks)); instacktop = instack; } instacktop->buf = inbuf; instacktop->bufptr = inbufptr; instacktop->bufleft = inbufleft; instacktop->bufct = inbufct; inbufflags &= ~(INP_ALCONT|INP_HISTCONT); if (flags & (INP_ALIAS|INP_HIST)) { /* * Text is expansion for history or alias, so continue * back to old level when done. Also mark stack top * as alias continuation so as to back up if necessary, * and mark alias as in use. */ flags |= INP_CONT|INP_ALIAS; if (flags & INP_HIST) instacktop->flags = inbufflags | INP_HISTCONT; else instacktop->flags = inbufflags | INP_ALCONT; if ((instacktop->alias = inalias)) inalias->inuse = 1; } else { /* If we are continuing an alias expansion, record the alias * expansion in new set of flags (do we need this?) */ if (((instacktop->flags = inbufflags) & INP_ALIAS) && (flags & INP_CONT)) flags |= INP_ALIAS; } instacktop++; if (instacktop == instack + instacksz) { /* Expand the stack */ instack = (struct instacks *) realloc(instack, (instacksz + INSTACK_EXPAND)*sizeof(struct instacks)); instacktop = instack + instacksz; instacksz += INSTACK_EXPAND; } /* * We maintain the entry above the highest one with real * text as a flag to inungetc() that it can stop re-pushing the stack. */ instacktop->flags = 0; inbufpush = inbuf = NULL; inputsetline(str, flags); }
static int inputline(void) { char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL; int context = ZLCON_LINE_START; /* If reading code interactively, work out the prompts. */ if (interact && isset(SHINSTDIN)) { if (!isfirstln) { ingetcpmptl = &prompt2; if (rprompt2) ingetcpmptr = &rprompt2; context = ZLCON_LINE_CONT; } else { ingetcpmptl = &prompt; if (rprompt) ingetcpmptr = &rprompt; } } if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) { /* * If not using zle, read the line straight from the input file. * Possibly we don't get the whole line at once: in that case, * we get another chunk with the next call to inputline(). */ if (interact && isset(SHINSTDIN)) { /* * We may still be interactive (e.g. running under emacs), * so output a prompt if necessary. We don't know enough * about the input device to be able to handle an rprompt, * though. */ char *pptbuf; int pptlen; pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL, 0, NULL, NULL, NULL), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); } ingetcline = shingetline(); } else { /* * Since we may have to read multiple lines before getting * a complete piece of input, we tell zle not to restore the * original tty settings after reading each chunk. Instead, * this is done when the history mechanism for the current input * terminates, which is not until we have the whole input. * This is supposed to minimise problems on systems that clobber * typeahead when the terminal settings are altered. * pws 1998/03/12 */ int flags = ZLRF_HISTORY|ZLRF_NOSETTY; if (isset(IGNOREEOF)) flags |= ZLRF_IGNOREEOF; ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr, flags, context); histdone |= HISTFLAG_SETTY; } if (!ingetcline) { return lexstop = 1; } if (errflag) { free(ingetcline); errflag |= ERRFLAG_ERROR; return lexstop = 1; } if (isset(VERBOSE)) { /* Output the whole line read so far. */ zputs(ingetcline, stderr); fflush(stderr); } if (keyboardhackchar && *ingetcline && ingetcline[strlen(ingetcline) - 1] == '\n' && interact && isset(SHINSTDIN) && SHTTY != -1 && ingetcline[1]) { char *stripptr = ingetcline + strlen(ingetcline) - 2; if (*stripptr == keyboardhackchar) { /* Junk an unwanted character at the end of the line. (key too close to return key) */ int ct = 1; /* force odd */ char *ptr; if (keyboardhackchar == '\'' || keyboardhackchar == '"' || keyboardhackchar == '`') { /* * for the chars above, also require an odd count before * junking */ for (ct = 0, ptr = ingetcline; *ptr; ptr++) if (*ptr == keyboardhackchar) ct++; } if (ct & 1) { stripptr[0] = '\n'; stripptr[1] = '\0'; } } } isfirstch = 1; if ((inbufflags & INP_APPEND) && inbuf) { /* * We need new input but need to be able to back up * over the old input, so append this line. * Pushing the line onto the stack doesn't have the right * effect. * * This is quite a simple and inefficient fix, but currently * we only need it when backing up over a multi-line $((... * that turned out to be a command substitution rather than * a math substitution, which is a very special case. * So it's not worth rewriting. */ char *oinbuf = inbuf; int newlen = strlen(ingetcline); int oldlen = (int)(inbufptr - inbuf) + inbufleft; if (inbufflags & INP_FREE) { inbuf = realloc(inbuf, oldlen + newlen + 1); } else { inbuf = zalloc(oldlen + newlen + 1); memcpy(inbuf, oinbuf, oldlen); } inbufptr += inbuf - oinbuf; strcpy(inbuf + oldlen, ingetcline); free(ingetcline); inbufleft += newlen; inbufct += newlen; inbufflags |= INP_FREE; } else { /* Put this into the input channel. */ inputsetline(ingetcline, INP_FREE); } return 0; }
static int inputline(void) { char *ingetcline, **ingetcpmptl = NULL, **ingetcpmptr = NULL; int context = ZLCON_LINE_START; /* If reading code interactively, work out the prompts. */ if (interact && isset(SHINSTDIN)) { if (!isfirstln) { ingetcpmptl = &prompt2; if (rprompt2) ingetcpmptr = &rprompt2; context = ZLCON_LINE_CONT; } else { ingetcpmptl = &prompt; if (rprompt) ingetcpmptr = &rprompt; } } if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) { /* * If not using zle, read the line straight from the input file. * Possibly we don't get the whole line at once: in that case, * we get another chunk with the next call to inputline(). */ if (interact && isset(SHINSTDIN)) { /* * We may still be interactive (e.g. running under emacs), * so output a prompt if necessary. We don't know enough * about the input device to be able to handle an rprompt, * though. */ char *pptbuf; int pptlen; pptbuf = unmetafy(promptexpand(ingetcpmptl ? *ingetcpmptl : NULL, 0, NULL, NULL, NULL), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); } ingetcline = shingetline(); } else { /* * Since we may have to read multiple lines before getting * a complete piece of input, we tell zle not to restore the * original tty settings after reading each chunk. Instead, * this is done when the history mechanism for the current input * terminates, which is not until we have the whole input. * This is supposed to minimise problems on systems that clobber * typeahead when the terminal settings are altered. * pws 1998/03/12 */ int flags = ZLRF_HISTORY|ZLRF_NOSETTY; if (isset(IGNOREEOF)) flags |= ZLRF_IGNOREEOF; ingetcline = zleentry(ZLE_CMD_READ, ingetcpmptl, ingetcpmptr, flags, context); histdone |= HISTFLAG_SETTY; } if (!ingetcline) { return lexstop = 1; } if (errflag) { free(ingetcline); return lexstop = errflag = 1; } if (isset(VERBOSE)) { /* Output the whole line read so far. */ zputs(ingetcline, stderr); fflush(stderr); } if (keyboardhackchar && *ingetcline && ingetcline[strlen(ingetcline) - 1] == '\n' && interact && isset(SHINSTDIN) && SHTTY != -1 && ingetcline[1]) { char *stripptr = ingetcline + strlen(ingetcline) - 2; if (*stripptr == keyboardhackchar) { /* Junk an unwanted character at the end of the line. (key too close to return key) */ int ct = 1; /* force odd */ char *ptr; if (keyboardhackchar == '\'' || keyboardhackchar == '"' || keyboardhackchar == '`') { /* * for the chars above, also require an odd count before * junking */ for (ct = 0, ptr = ingetcline; *ptr; ptr++) if (*ptr == keyboardhackchar) ct++; } if (ct & 1) { stripptr[0] = '\n'; stripptr[1] = '\0'; } } } isfirstch = 1; /* Put this into the input channel. */ inputsetline(ingetcline, INP_FREE); return 0; }