Ejemplo n.º 1
0
Archivo: loop.c Proyecto: phy1729/zsh
int
execwhile(Estate state, UNUSED(int do_exec))
{
    Wordcode end, loop;
    wordcode code = state->pc[-1];
    int olderrexit, oldval, isuntil = (WC_WHILE_TYPE(code) == WC_WHILE_UNTIL);
    int old_simple_pline = simple_pline;

    end = state->pc + WC_WHILE_SKIP(code);
    olderrexit = noerrexit;
    oldval = 0;
    pushheap();
    cmdpush(isuntil ? CS_UNTIL : CS_WHILE);
    loops++;
    loop = state->pc;

    if (loop[0] == WC_END && loop[1] == WC_END) {

        /* This is an empty loop.  Make sure the signal handler sets the
        * flags and then just wait for someone hitting ^C. */

        simple_pline = 1;

        while (!breaks)
            ;
        breaks--;

        simple_pline = old_simple_pline;
    } else
        for (;;) {
            state->pc = loop;
            noerrexit = 1;

	    /* In case the test condition is a functional no-op,
	     * make sure signal handlers recognize ^C to end the loop. */
	    simple_pline = 1;

            execlist(state, 1, 0);

	    simple_pline = old_simple_pline;
            noerrexit = olderrexit;
            if (!((lastval == 0) ^ isuntil)) {
                if (breaks)
                    breaks--;
                lastval = oldval;
                break;
            }
            if (retflag) {
                lastval = oldval;
                break;
            }

	    /* In case the loop body is also a functional no-op,
	     * make sure signal handlers recognize ^C as above. */
	    simple_pline = 1;

            execlist(state, 1, 0);

	    simple_pline = old_simple_pline;
            if (breaks) {
                breaks--;
                if (breaks || !contflag)
                    break;
                contflag = 0;
            }
            if (errflag) {
                lastval = 1;
                break;
            }
            if (retflag)
                break;
            freeheap();
            oldval = lastval;
        }
    cmdpop();
    popheap();
    loops--;
    state->pc = end;
    return lastval;
}
Ejemplo n.º 2
0
Archivo: loop.c Proyecto: 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;
}
Ejemplo n.º 3
0
void
zlecore(void)
{
    Keymap km;
#if !defined(HAVE_POLL) && defined(HAVE_SELECT)
    struct timeval tv;
    fd_set foofd;

    FD_ZERO(&foofd);
#endif

    pushheap();

    /*
     * A widget function may decide to exit the shell.
     * We never exit directly from functions, to allow
     * the shell to tidy up, so we have to test for
     * that explicitly.
     */
    while (!done && !errflag && !exit_pending) {
	UNMETACHECK();

	statusline = NULL;
	vilinerange = 0;
	reselectkeymap();
	selectlocalmap(invicmdmode() && region_active && (km = openkeymap("visual"))
	    ? km : NULL);
	bindk = getkeycmd();
	selectlocalmap(NULL);
	if (bindk) {
	    if (!zlell && isfirstln && !(zlereadflags & ZLRF_IGNOREEOF) &&
		lastchar == eofchar) {
		/*
		 * Slight hack: this relies on getkeycmd returning
		 * a value for the EOF character.  However,
		 * undefined-key is fine.  That's necessary because
		 * otherwise we can't distinguish this case from
		 * a ^C.
		 */
		eofsent = 1;
		break;
	    }
	    if (execzlefunc(bindk, zlenoargs, 0)) {
		handlefeep(zlenoargs);
		if (eofsent)
		    break;
	    }
	    handleprefixes();
	    /* for vi mode, make sure the cursor isn't somewhere illegal */
	    if (invicmdmode() && zlecs > findbol() &&
		(zlecs == zlell || zleline[zlecs] == ZWC('\n')))
		DECCS();
	    handleundo();
	} else {
	    errflag |= ERRFLAG_ERROR;
	    break;
	}
#ifdef HAVE_POLL
	if (baud && !(lastcmd & ZLE_MENUCMP)) {
	    struct pollfd pfd;
	    int to = cost * costmult / 1000; /* milliseconds */

	    if (to > 500)
		to = 500;
	    pfd.fd = SHTTY;
	    pfd.events = POLLIN;
	    if (!kungetct && poll(&pfd, 1, to) <= 0)
		zrefresh();
	} else
#else
# ifdef HAVE_SELECT
	if (baud && !(lastcmd & ZLE_MENUCMP)) {
	    FD_SET(SHTTY, &foofd);
	    tv.tv_sec = 0;
	    if ((tv.tv_usec = cost * costmult) > 500000)
		tv.tv_usec = 500000;
	    if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd,
				    NULL, NULL, &tv) <= 0)
		zrefresh();
	} else
# endif
#endif
	    if (!kungetct)
		zrefresh();

	freeheap();
    }

    region_active = 0;
    popheap();
}
Ejemplo n.º 4
0
int
exectry(Estate state, int do_exec)
{
    Wordcode end, always;
    int endval;
    int save_retflag, save_breaks, save_contflag;
    zlong save_try_errflag, save_try_tryflag, save_try_interrupt;

    end = state->pc + WC_TRY_SKIP(state->pc[-1]);
    always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
    state->pc++;
    pushheap();
    cmdpush(CS_CURSH);

    /* The :try clause */
    save_try_tryflag = try_tryflag;
    try_tryflag = 1;

    execlist(state, 1, do_exec);

    try_tryflag = save_try_tryflag;

    /* Don't record errflag here, may be reset.  However, */
    /* endval should show failure when there is an error. */
    endval = lastval ? lastval : errflag;

    freeheap();

    cmdpop();
    cmdpush(CS_ALWAYS);

    /* The always clause. */
    save_try_errflag = try_errflag;
    save_try_interrupt = try_interrupt;
    try_errflag = (zlong)(errflag & ERRFLAG_ERROR);
    try_interrupt = (zlong)((errflag & ERRFLAG_INT) ? 1 : 0);
    /* We need to reset all errors to allow the block to execute */
    errflag = 0;
    save_retflag = retflag;
    retflag = 0;
    save_breaks = breaks;
    breaks = 0;
    save_contflag = contflag;
    contflag = 0;

    state->pc = always;
    execlist(state, 1, do_exec);

    if (try_errflag)
	errflag |= ERRFLAG_ERROR;
    else
	errflag &= ~ERRFLAG_ERROR;
    if (try_interrupt)
	errflag |= ERRFLAG_INT;
    else
	errflag &= ~ERRFLAG_INT;
    try_errflag = save_try_errflag;
    try_interrupt = save_try_interrupt;
    if (!retflag)
	retflag = save_retflag;
    if (!breaks)
	breaks = save_breaks;
    if (!contflag)
	contflag = save_contflag;

    cmdpop();
    popheap();
    state->pc = end;

    return endval;
}
Ejemplo n.º 5
0
int
execfor(Estate state, int do_exec)
{
    Wordcode end, loop;
    wordcode code = state->pc[-1];
    int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
    int last = 0;
    char *name, *str, *cond = NULL, *advance = NULL;
    zlong val = 0;
    LinkList vars = NULL, args = NULL;

    end = state->pc + WC_FOR_SKIP(code);

    if (iscond) {
	str = dupstring(ecgetstr(state, EC_NODUP, NULL));
	singsub(&str);
	if (isset(XTRACE)) {
	    char *str2 = dupstring(str);
	    untokenize(str2);
	    printprompt4();
	    fprintf(xtrerr, "%s\n", str2);
	    fflush(xtrerr);
	}
	if (!errflag)
	    matheval(str);
	if (errflag) {
	    state->pc = end;
	    return 1;
	}
	cond = ecgetstr(state, EC_NODUP, &ctok);
	advance = ecgetstr(state, EC_NODUP, &atok);
    } else {
	vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);

	if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
	    int htok = 0;

	    if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
		state->pc = end;
		return 0;
	    }
	    if (htok) {
		execsubst(args);
		if (errflag) {
		    state->pc = end;
		    return 1;
		}
	    }
	} else {
	    char **x;

	    args = newlinklist();
	    for (x = pparams; *x; x++)
		addlinknode(args, dupstring(*x));
	}
    }

    if (!args || empty(args))
	lastval = 0;

    loops++;
    pushheap();
    cmdpush(CS_FOR);
    loop = state->pc;
    while (!last) {
	if (iscond) {
	    if (ctok) {
		str = dupstring(cond);
		singsub(&str);
	    } else
		str = cond;
	    if (!errflag) {
		while (iblank(*str))
		    str++;
		if (*str) {
		    if (isset(XTRACE)) {
			printprompt4();
			fprintf(xtrerr, "%s\n", str);
			fflush(xtrerr);
		    }
		    val = mathevali(str);
		} else
		    val = 1;
	    }
	    if (errflag) {
		if (breaks)
		    breaks--;
		lastval = 1;
		break;
	    }
	    if (!val)
		break;
	} else {
	    LinkNode node;
	    int count = 0;
	    for (node = firstnode(vars); node; incnode(node))
	    {
		name = (char *)getdata(node);
		if (!args || !(str = (char *) ugetnode(args)))
		{
		    if (count) { 
			str = "";
			last = 1;
		    } else
			break;
		}
		if (isset(XTRACE)) {
		    printprompt4();
		    fprintf(xtrerr, "%s=%s\n", name, str);
		    fflush(xtrerr);
		}
		setsparam(name, ztrdup(str));
		count++;
	    }
	    if (!count)
		break;
	}
	state->pc = loop;
	execlist(state, 1, do_exec && args && empty(args));
	if (breaks) {
	    breaks--;
	    if (breaks || !contflag)
		break;
	    contflag = 0;
	}
	if (retflag)
	    break;
	if (iscond && !errflag) {
	    if (atok) {
		str = dupstring(advance);
		singsub(&str);
	    } else
		str = advance;
	    if (isset(XTRACE)) {
		printprompt4();
		fprintf(xtrerr, "%s\n", str);
		fflush(xtrerr);
	    }
	    if (!errflag)
		matheval(str);
	}
	if (errflag) {
	    if (breaks)
		breaks--;
	    lastval = 1;
	    break;
	}
	freeheap();
    }
    popheap();
    cmdpop();
    loops--;
    state->pc = end;
    return lastval;
}
Ejemplo n.º 6
0
Archivo: sort.c Proyecto: AMDmi3/zsh
mod_export void
strmetasort(char **array, int sortwhat, int *unmetalenp)
{
    char **arrptr;
    /*
     * Array of elements containing stuff to sort.  Note sortptrarr
     * is an array of pointers, since that's more efficient
     * for qsort() to manipulate.  sortarr is the array of
     * structures.
     */
    SortElt *sortptrarr, *sortptrarrptr;
    SortElt sortarr, sortarrptr;
    int oldsortdir, oldsortnumeric, nsort;

    nsort = arrlen(array);
    if (nsort < 2)
	return;

    pushheap();

    sortptrarr = (SortElt *) zhalloc(nsort * sizeof(SortElt));
    sortarr = (SortElt) zhalloc(nsort * sizeof(struct sortelt));
    for (arrptr = array, sortptrarrptr = sortptrarr, sortarrptr = sortarr;
	 *arrptr; arrptr++, sortptrarrptr++, sortarrptr++) {
	char *metaptr;
	int needlen, needalloc;
	*sortptrarrptr = sortarrptr;
	sortarrptr->orig = *arrptr;

	if (unmetalenp) {
	    /*
	     * Already unmetafied.  We just need to check for
	     * embededded nulls.
	     */
	    int count = unmetalenp[arrptr-array];
	    /* Remember this length for sorted array */
	    sortarrptr->origlen = count;
	    for (metaptr = *arrptr; *metaptr != '\0' && count--; metaptr++)
		;
	    /* *metaptr must now be \0, even if we reached the end */
	    needlen = (count != 0);
	} else {
	    /*
	     * Not yet unmetafied.  See if it needs unmetafying.
	     * If it doesn't, there can't be any embedded nulls,
	     * since these are metafied.
	     */
	    needlen = 0;
	    for (metaptr = *arrptr; *metaptr && *metaptr != Meta;
		 metaptr++);
	}
	/*
	 * See if we need to do some special checking.
	 * Either we're going to need to copy it to transform it,
	 * or we need to unmetafy it.
	 */
	if ((needalloc = (sortwhat &
			  (SORTIT_IGNORING_CASE|SORTIT_IGNORING_BACKSLASHES)))
	    || *metaptr == Meta) {
	    char *s, *t, *src = *arrptr, *dst;
	    int len;
	    sortarrptr->cmp = dst =
		(char *)zhalloc(((sortwhat & SORTIT_IGNORING_CASE)?2:1)*strlen(src)+1);

	    if (unmetalenp) {
		/* Already unmetafied and we have the length. */
		len = unmetalenp[arrptr-array];
	    } else if (*metaptr != '\0') {
		/*
		 * Needs unmetafying.  We need to check for
		 * embedded nulls while we do this.
		 */
		char *t = dst + (metaptr - src);

		if (metaptr != src)
		    memcpy(dst, src, metaptr - src);
		while ((*t = *metaptr++)) {
		    if (*t++ == Meta) {
			if ((t[-1] = *metaptr++ ^ 32) == '\0')
			    needlen = 1;
		    }
		}
		len = t - dst;
		src = dst;
	    } else {
		/*
		 * Doesn't need unmetafying.
		 * This means metaptr is the NULL at the
		 * end of the string, so we have the length, and
		 * there are no embedded nulls, so we don't
		 * need the length later.
		 * We're only copying the string to transform it
		 * below.
		 */
		len = metaptr - src;
	    }
	    if (sortwhat & SORTIT_IGNORING_CASE) {
		char *send = src + len;
#ifdef MULTIBYTE_SUPPORT
		if (isset(MULTIBYTE)) {
		    /*
		     * Lower the case the hard way.  Convert to a wide
		     * character, process that, and convert back.  We
		     * don't assume the characters have the same
		     * multibyte length.  We can't use casemodify()
		     * because we have unmetafied data, which may have
		     * been passed down to use.
		     */
		    mbstate_t mbsin, mbsout;
		    int clen;
		    wchar_t wc;
		    memset(&mbsin, 0, sizeof(mbstate_t));
		    memset(&mbsout, 0, sizeof(mbstate_t));

		    for (s = src, t = dst; s < send; ) {
			clen = mbrtowc(&wc, s, send-s, &mbsin);
			if (clen < 0) {
			    /* invalid or unfinished: treat as single bytes */
			    while (s < send)
				*t++ = tulower(*s++);
			    break;
			}
			if (clen == 0) {
			    /* embedded null */
			    *t++ = '\0';
			    s++;
			    continue;
			}
			s += clen;
			wc = towlower(wc);
			clen = wcrtomb(t, wc, &mbsout);
			t += clen;
			DPUTS(clen < 0, "Bad conversion when lowering case");
		    }
		    *t = '\0';
		    len = t - dst;
		} else
#endif
		    for (s = src, t = dst; s < send; )
			*t++ = tulower(*s++);
		src = dst;
	    }
	    if (sortwhat & SORTIT_IGNORING_BACKSLASHES) {
                char *end = src + len + 1;
		/* copy null byte, so increment length */
		for (s = src, t = dst; s < end; ) {
		    if (*s == '\\') {
			s++;
			len--;
		    }
		    *t++ = *s++;
		}
	    }
	    /* Do we need to store the length (embedded null)? */
	    sortarrptr->len = needlen ? len : -1;
	} else {
	    /*
	     * We can use the string as is, although it's possible
	     * we still need to take account of an embedded null.
	     */
	    sortarrptr->cmp = *arrptr;
	    sortarrptr->len = needlen ? unmetalenp[arrptr-array] : -1;
	}
    }
    /*
     * We probably don't need to restore the following, but it's pretty cheap.
     */
    oldsortdir = sortdir;
    oldsortnumeric = sortnumeric;

    sortdir = (sortwhat & SORTIT_BACKWARDS) ? -1 : 1;
    sortnumeric = (sortwhat & SORTIT_NUMERICALLY) ? 1 : 0;

    qsort(sortptrarr, nsort, sizeof(SortElt), eltpcmp);

    sortnumeric = oldsortnumeric;
    sortdir = oldsortdir;
    for (arrptr = array, sortptrarrptr = sortptrarr; nsort--; ) {
	if (unmetalenp)
	    unmetalenp[arrptr-array] = (*sortptrarrptr)->origlen;
	*arrptr++ = (*sortptrarrptr++)->orig;
    }

    popheap();
}