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; }
char * zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) { char *s, **bracket; int old_errno = errno; int tmout = getiparam("TMOUT"); #if defined(HAVE_POLL) || defined(HAVE_SELECT) /* may not be set, but that's OK since getiparam() returns 0 == off */ baud = getiparam("BAUD"); costmult = (baud) ? 3840000L / baud : 0; #endif /* ZLE doesn't currently work recursively. This is needed in case a * * select loop is used in a function called from ZLE. vared handles * * this differently itself. */ if(zleactive) { char *pptbuf; int pptlen; pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, &pmpt_attr), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); return shingetline(); } /* * The current status is what we need if we are going * to display a prompt. We'll remember it here for * use further in. */ pre_zle_status = lastval; keytimeout = (time_t)getiparam("KEYTIMEOUT"); if (!shout) { if (SHTTY != -1) init_shout(); if (!shout) return NULL; /* We could be smarter and default to a system read. */ /* If we just got a new shout, make sure the terminal is set up. */ if (termflags & TERM_UNKNOWN) init_term(); } fflush(shout); fflush(stderr); intr(); insmode = unset(OVERSTRIKE); eofsent = 0; resetneeded = 0; fetchttyinfo = 0; trashedzle = 0; raw_lp = lp; lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr); raw_rp = rp; rpmpt_attr = pmpt_attr; rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL, &rpmpt_attr); free_prepostdisplay(); zlereadflags = flags; zlecontext = context; histline = curhist; vistartchange = -1; zleline = (ZLE_STRING_T)zalloc(((linesz = 256) + 2) * ZLE_CHAR_SIZE); *zleline = ZWC('\0'); virangeflag = lastcmd = done = zlecs = zlell = mark = 0; vichgflag = 0; viinsbegin = 0; statusline = NULL; selectkeymap("main", 1); initundo(); fixsuffix(); if ((s = getlinknode(bufstack))) { setline(s, ZSL_TOEND); zsfree(s); if (stackcs != -1) { zlecs = stackcs; stackcs = -1; if (zlecs > zlell) zlecs = zlell; CCLEFT(); } if (stackhist != -1) { histline = stackhist; stackhist = -1; } handleundo(); } /* * If main is linked to the viins keymap, we need to register * explicitly that we're now in vi insert mode as there's * no user operation to indicate this. */ if (openkeymap("main") == openkeymap("viins")) viinsert_init(); selectlocalmap(NULL); if (isset(PROMPTCR)) putc('\r', shout); if (tmout) alarm(tmout); /* * On some windowing systems we may enter this function before the * terminal is fully opened and sized, resulting in an infinite * series of SIGWINCH when the handler prints the prompt before we * have done so here. Therefore, hold any such signal until the * first full refresh has completed. The important bit is that the * handler must not see zleactive = 1 until ZLE really is active. * See the end of adjustwinsize() in Src/utils.c */ queue_signals(); zleactive = 1; resetneeded = 1; /* * Start of the main zle read. * Fully reset error conditions, including user interrupt. */ errflag = retflag = 0; lastcol = -1; initmodifier(&zmod); prefixflag = 0; zrefresh(); unqueue_signals(); /* Should now be safe to acknowledge SIGWINCH */ zlecallhook(init, NULL); if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2) fputs(*bracket, shout); zrefresh(); zlecore(); if (errflag) setsparam((zlecontext == ZLCON_VARED) ? "ZLE_VARED_ABORTED" : "ZLE_LINE_ABORTED", zlegetline(NULL, NULL)); if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2) fputs(bracket[1], shout); if (done && !exit_pending && !errflag) zlecallhook(finish, NULL); statusline = NULL; invalidatelist(); trashzle(); free(lpromptbuf); free(rpromptbuf); zleactive = zlereadflags = lastlistlen = zlecontext = 0; alarm(0); freeundo(); if (eofsent || errflag || exit_pending) { s = NULL; } else { zleline[zlell++] = ZWC('\n'); s = zlegetline(NULL, NULL); } free(zleline); zleline = NULL; forget_edits(); errno = old_errno; /* highlight no longer valid */ set_region_highlight(NULL, NULL); return s; }
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; }
char * zleread(char **lp, char **rp, int flags, int context) { char *s; int old_errno = errno; int tmout = getiparam("TMOUT"); #if defined(HAVE_POLL) || defined(HAVE_SELECT) /* may not be set, but that's OK since getiparam() returns 0 == off */ baud = getiparam("BAUD"); costmult = (baud) ? 3840000L / baud : 0; #endif /* ZLE doesn't currently work recursively. This is needed in case a * * select loop is used in a function called from ZLE. vared handles * * this differently itself. */ if(zleactive) { char *pptbuf; int pptlen; pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL, &pmpt_attr), &pptlen); write_loop(2, pptbuf, pptlen); free(pptbuf); return shingetline(); } /* * The current status is what we need if we are going * to display a prompt. We'll remember it here for * use further in. */ pre_zle_status = lastval; keytimeout = (time_t)getiparam("KEYTIMEOUT"); if (!shout) { if (SHTTY != -1) init_shout(); if (!shout) return NULL; /* We could be smarter and default to a system read. */ /* If we just got a new shout, make sure the terminal is set up. */ if (termflags & TERM_UNKNOWN) init_term(); } fflush(shout); fflush(stderr); intr(); insmode = unset(OVERSTRIKE); eofsent = 0; resetneeded = 0; fetchttyinfo = 0; trashedzle = 0; raw_lp = lp; lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr); raw_rp = rp; rpmpt_attr = pmpt_attr; rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL, &rpmpt_attr); free_prepostdisplay(); zlereadflags = flags; zlecontext = context; histline = curhist; undoing = 1; zleline = (ZLE_STRING_T)zalloc(((linesz = 256) + 2) * ZLE_CHAR_SIZE); *zleline = ZWC('\0'); virangeflag = lastcmd = done = zlecs = zlell = mark = 0; vichgflag = 0; viinsbegin = 0; statusline = NULL; selectkeymap("main", 1); selectlocalmap(NULL); fixsuffix(); if ((s = getlinknode(bufstack))) { setline(s, ZSL_TOEND); zsfree(s); if (stackcs != -1) { zlecs = stackcs; stackcs = -1; if (zlecs > zlell) zlecs = zlell; CCLEFT(); } if (stackhist != -1) { histline = stackhist; stackhist = -1; } } initundo(); if (isset(PROMPTCR)) putc('\r', shout); if (tmout) alarm(tmout); zleactive = 1; resetneeded = 1; errflag = retflag = 0; lastcol = -1; initmodifier(&zmod); prefixflag = 0; zrefresh(); zlecallhook("zle-line-init", NULL); zlecore(); if (errflag) setsparam("ZLE_LINE_ABORTED", zlegetline(NULL, NULL)); if (done && !exit_pending && !errflag) zlecallhook("zle-line-finish", NULL); statusline = NULL; invalidatelist(); trashzle(); free(lpromptbuf); free(rpromptbuf); zleactive = zlereadflags = lastlistlen = zlecontext = 0; alarm(0); freeundo(); if (eofsent) { s = NULL; } else { zleline[zlell++] = ZWC('\n'); s = zlegetline(NULL, NULL); } free(zleline); zleline = NULL; forget_edits(); errno = old_errno; /* highlight no longer valid */ set_region_highlight(NULL, NULL); return s; }