Пример #1
0
void
reexpandprompt(void)
{
    static int reexpanding;

    if (!reexpanding++) {
	/*
	 * If we're displaying a status in the prompt, it
	 * needs to be the toplevel one, not the one from
	 * any status set within the local zle function.
	 */
	int local_lastval = lastval;
	lastval = pre_zle_status;

	free(lpromptbuf);
	lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL,
				  &pmpt_attr);
	rpmpt_attr = pmpt_attr;
	free(rpromptbuf);
	rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL,
				  &rpmpt_attr);
	lastval = local_lastval;
    }
    reexpanding--;
}
Пример #2
0
/* Parse the argument for %F and %K */
static int
parsecolorchar(int arg, int is_fg)
{
    if (bv->fm[1] == '{') {
	char *ep;
	bv->fm += 2; /* skip over F{ */
	if ((ep = strchr(bv->fm, '}'))) {
	    char oc = *ep, *col, *coll;
	    *ep = '\0';
	    /* expand the contents of the argument so you can use
	     * %v for example */
	    coll = col = promptexpand(bv->fm, 0, NULL, NULL, NULL);
	    *ep = oc;
	    arg = match_colour((const char **)&coll, is_fg, 0);
	    free(col);
	    bv->fm = ep;
	} else {
	    arg = match_colour((const char **)&bv->fm, is_fg, 0);
	    if (*bv->fm != '}')
		bv->fm--;
	}
    } else
	arg = match_colour(NULL, 1, arg);
    return arg;
}
Пример #3
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);
	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;
}
Пример #4
0
Файл: loop.c Проект: phy1729/zsh
int
execselect(Estate state, UNUSED(int do_exec))
{
    Wordcode end, loop;
    wordcode code = state->pc[-1];
    char *str, *s, *name;
    LinkNode n;
    int i, usezle;
    FILE *inp;
    size_t more;
    LinkList args;
    int old_simple_pline = simple_pline;

    /* See comments in execwhile() */
    simple_pline = 1;

    end = state->pc + WC_FOR_SKIP(code);
    name = ecgetstr(state, EC_NODUP, NULL);

    if (WC_SELECT_TYPE(code) == WC_SELECT_PPARAM) {
	char **x;

	args = newlinklist();
	for (x = pparams; *x; x++)
	    addlinknode(args, dupstring(*x));
    } else {
	int htok = 0;

	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
	    state->pc = end;
	    simple_pline = old_simple_pline;
	    return 0;
	}
	if (htok) {
	    execsubst(args);
	    if (errflag) {
		state->pc = end;
		simple_pline = old_simple_pline;
		return 1;
	    }
	}
    }
    if (!args || empty(args)) {
	state->pc = end;
	simple_pline = old_simple_pline;
	return 0;
    }
    loops++;

    pushheap();
    cmdpush(CS_SELECT);
    usezle = interact && SHTTY != -1 && isset(USEZLE);
    inp = fdopen(dup(usezle ? SHTTY : 0), "r");
    more = selectlist(args, 0);
    loop = state->pc;
    for (;;) {
	for (;;) {
	    if (empty(bufstack)) {
	    	if (usezle) {
		    int oef = errflag;

		    isfirstln = 1;
		    str = zleentry(ZLE_CMD_READ, &prompt3, NULL,
				   0, ZLCON_SELECT);
		    if (errflag)
			str = NULL;
		    /* Keep any user interrupt error status */
		    errflag = oef | (errflag & ERRFLAG_INT);
	    	} else {
		    str = promptexpand(prompt3, 0, NULL, NULL, NULL);
		    zputs(str, stderr);
		    free(str);
		    fflush(stderr);
		    str = fgets(zhalloc(256), 256, inp);
	    	}
	    } else
		str = (char *)getlinknode(bufstack);
            if (!str && !errflag)
                setsparam("REPLY", ztrdup("")); /* EOF (user pressed Ctrl+D) */
	    if (!str || errflag) {
		if (breaks)
		    breaks--;
		fprintf(stderr, "\n");
		fflush(stderr);
		goto done;
	    }
	    if ((s = strchr(str, '\n')))
		*s = '\0';
	    if (*str)
	      break;
	    more = selectlist(args, more);
	}
	setsparam("REPLY", ztrdup(str));
	i = atoi(str);
	if (!i)
	    str = "";
	else {
	    for (i--, n = firstnode(args); n && i; incnode(n), i--);
	    if (n)
		str = (char *) getdata(n);
	    else
		str = "";
	}
	setsparam(name, ztrdup(str));
	state->pc = loop;
	execlist(state, 1, 0);
	freeheap();
	if (breaks) {
	    breaks--;
	    if (breaks || !contflag)
		break;
	    contflag = 0;
	}
	if (retflag || errflag)
	    break;
    }
  done:
    cmdpop();
    popheap();
    fclose(inp);
    loops--;
    simple_pline = old_simple_pline;
    state->pc = end;
    return lastval;
}
Пример #5
0
Файл: input.c Проект: Osse/zsh
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;
}
Пример #6
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;
}
Пример #7
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;
}