示例#1
0
int
get_intarg(char **s)
{
    char *t = get_strarg(*s + 1);
    char *p, sav;
    long ret;

    if (!*t)
	return -1;
    sav = *t;
    *t = '\0';
    p = dupstring(*s + 2);
    *s = t;
    *t = sav;
    if (parsestr(p))
	return -1;
    singsub(&p);
    if (errflag)
	return -1;
    ret = matheval(p);
    if (errflag)
	return -1;
    if (ret < 0)
	ret = -ret;
    return ret < 0 ? -ret : ret;
}
示例#2
0
文件: loop.c 项目: phy1729/zsh
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;
    int old_simple_pline = simple_pline;

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

    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;
	    simple_pline = old_simple_pline;
	    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;
		simple_pline = old_simple_pline;
		return 0;
	    }
	    if (htok) {
		execsubst(args);
		if (errflag) {
		    state->pc = end;
		    simple_pline = old_simple_pline;
		    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--;
    simple_pline = old_simple_pline;
    state->pc = end;
    return lastval;
}
示例#3
0
文件: cond.c 项目: AMDmi3/zsh
int
evalcond(Estate state, char *fromtest)
{
    struct stat *st;
    char *left, *right, *overridename, overridebuf[13];
    Wordcode pcode;
    wordcode code;
    int ctype, htok = 0, ret;

 rec:

    left = right = overridename = NULL;
    pcode = state->pc++;
    code = *pcode;
    ctype = WC_COND_TYPE(code);

    switch (ctype) {
    case COND_NOT:
	if (tracingcond)
	    fprintf(xtrerr, " %s", condstr[ctype]);
	ret = evalcond(state, fromtest);
	if (ret == 2)
	    return ret;
	else
	    return !ret;
    case COND_AND:
	if (!(ret = evalcond(state, fromtest))) {
	    if (tracingcond)
		fprintf(xtrerr, " %s", condstr[ctype]);
	    goto rec;
	} else {
	    state->pc = pcode + (WC_COND_SKIP(code) + 1);
	    return ret;
	}
    case COND_OR:
	if ((ret = evalcond(state, fromtest)) == 1) {
	    if (tracingcond)
		fprintf(xtrerr, " %s", condstr[ctype]);
	    goto rec;
	} else {
	    state->pc = pcode + (WC_COND_SKIP(code) + 1);
	    return ret;
	}
    case COND_REGEX:
	{
	    char *modname = isset(REMATCHPCRE) ? "zsh/pcre" : "zsh/regex";
	    sprintf(overridename = overridebuf, "-%s-match", modname+4);
	    (void)ensurefeature(modname, "C:", overridename+1);
	    ctype = COND_MODI;
	}
	/*FALLTHROUGH*/
    case COND_MOD:
    case COND_MODI:
	{
	    Conddef cd;
	    char *name = overridename, *errname;
	    char **strs;
	    int l = WC_COND_SKIP(code);

	    if (name == NULL)
		name = ecgetstr(state, EC_NODUP, NULL);
	    if (ctype == COND_MOD)
		strs = ecgetarr(state, l, EC_DUP, NULL);
	    else {
		char *sbuf[3];

		sbuf[0] = ecgetstr(state, EC_NODUP, NULL);
		sbuf[1] = ecgetstr(state, EC_NODUP, NULL);
		sbuf[2] = NULL;

		strs = arrdup(sbuf);
		l = 2;
	    }
	    if (name && name[0] == '-')
		errname = name;
	    else if (strs[0] && *strs[0] == '-')
		errname = strs[0];
	    else
		errname = "<null>";
	    if (name && name[0] == '-' &&
		(cd = getconddef((ctype == COND_MODI), name + 1, 1))) {
		if (ctype == COND_MOD &&
		    (l < cd->min || (cd->max >= 0 && l > cd->max))) {
		    zwarnnam(fromtest, "unknown condition: %s", name);
		    return 2;
		}
		if (tracingcond)
		    tracemodcond(name, strs, ctype == COND_MODI);
		return !cd->handler(strs, cd->condid);
	    }
	    else {
		char *s = strs[0];

		if (overridename) {
		    /*
		     * Standard regex function not available: this
		     * is a hard error.
		     */
		    zerrnam(fromtest, "%s not available for regex",
			     overridename);
		    return 2;
		}

		strs[0] = dupstring(name);
		name = s;

		if (name && name[0] == '-' &&
		    (cd = getconddef(0, name + 1, 1))) {
		    if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
			zwarnnam(fromtest, "unknown condition: %s",
				 errname);
			return 2;
		    }
		    if (tracingcond)
			tracemodcond(name, strs, ctype == COND_MODI);
		    return !cd->handler(strs, cd->condid);
		} else {
		    zwarnnam(fromtest,
			     "unknown condition: %s",
			     errname);
		}
	    }
	    /* module not found, error */
	    return 2;
	}
    }
    left = ecgetstr(state, EC_DUPTOK, &htok);
    if (htok) {
	cond_subst(&left, !fromtest);
	untokenize(left);
    }
    if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRNEQ) {
	right = ecgetstr(state, EC_DUPTOK, &htok);
	if (htok) {
	    cond_subst(&right, !fromtest);
	    untokenize(right);
	}
    }
    if (tracingcond) {
	if (ctype < COND_MOD) {
	    fputc(' ',xtrerr);
	    quotedzputs(left, xtrerr);
	    fprintf(xtrerr, " %s ", condstr[ctype]);
	    if (ctype == COND_STREQ || ctype == COND_STRNEQ) {
		char *rt = dupstring(ecrawstr(state->prog, state->pc, NULL));
		cond_subst(&rt, !fromtest);
		quote_tokenized_output(rt, xtrerr);
	    }
	    else
		quotedzputs((char *)right, xtrerr);
	} else {
	    fprintf(xtrerr, " -%c ", ctype);
	    quotedzputs(left, xtrerr);
	}
    }

    if (ctype >= COND_EQ && ctype <= COND_GE) {
	mnumber mn1, mn2;
	if (fromtest) {
	    /*
	     * For test and [, the expressions must be base 10 integers,
	     * not integer expressions.
	     */
	    char *eptr, *err;

	    mn1.u.l = zstrtol(left, &eptr, 10);
	    if (!*eptr)
	    {
		mn2.u.l = zstrtol(right, &eptr, 10);
		err = right;
	    }
	    else
		err = left;

	    if (*eptr)
	    {
		zwarnnam(fromtest, "integer expression expected: %s", err);
		return 2;
	    }

	    mn1.type = mn2.type = MN_INTEGER;
	} else {
	    mn1 = matheval(left);
	    mn2 = matheval(right);
	}

	if (((mn1.type|mn2.type) & (MN_INTEGER|MN_FLOAT)) ==
	    (MN_INTEGER|MN_FLOAT)) {
	    /* promote to float */
	    if (mn1.type & MN_INTEGER) {
		mn1.type = MN_FLOAT;
		mn1.u.d = (double)mn1.u.l;
	    }
	    if (mn2.type & MN_INTEGER) {
		mn2.type = MN_FLOAT;
		mn2.u.d = (double)mn2.u.l;
	    }
	}
	switch(ctype) {
	case COND_EQ:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d == mn2.u.d) :
		     (mn1.u.l == mn2.u.l));
	case COND_NE:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d != mn2.u.d) :
		     (mn1.u.l != mn2.u.l));
	case COND_LT:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d < mn2.u.d) :
		     (mn1.u.l < mn2.u.l));
	case COND_GT:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d > mn2.u.d) :
		     (mn1.u.l > mn2.u.l));
	case COND_LE:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d <= mn2.u.d) :
		     (mn1.u.l <= mn2.u.l));
	case COND_GE:
	    return !((mn1.type & MN_FLOAT) ? (mn1.u.d >= mn2.u.d) :
		     (mn1.u.l >= mn2.u.l));
	}
    }

    switch (ctype) {
    case COND_STREQ:
    case COND_STRNEQ:
	{
	    int test, npat = state->pc[1];
	    Patprog pprog = state->prog->pats[npat];

	    if (pprog == dummy_patprog1 || pprog == dummy_patprog2) {
		char *opat;
		int save;

		right = dupstring(opat = ecrawstr(state->prog, state->pc,
						  &htok));
		singsub(&right);
		save = (!(state->prog->flags & EF_HEAP) &&
			!strcmp(opat, right) && pprog != dummy_patprog2);

		if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
					 NULL))) {
		    zwarnnam(fromtest, "bad pattern: %s", right);
		    return 2;
		}
		else if (save)
		    state->prog->pats[npat] = pprog;
	    }
	    state->pc += 2;
	    test = (pprog && pattry(pprog, left));

	    return !(ctype == COND_STREQ ? test : !test);
	}
    case COND_STRLT:
	return !(strcmp(left, right) < 0);
    case COND_STRGTR:
	return !(strcmp(left, right) > 0);
    case 'e':
    case 'a':
	return (!doaccess(left, F_OK));
    case 'b':
	return (!S_ISBLK(dostat(left)));
    case 'c':
	return (!S_ISCHR(dostat(left)));
    case 'd':
	return (!S_ISDIR(dostat(left)));
    case 'f':
	return (!S_ISREG(dostat(left)));
    case 'g':
	return (!(dostat(left) & S_ISGID));
    case 'k':
	return (!(dostat(left) & S_ISVTX));
    case 'n':
	return (!strlen(left));
    case 'o':
	return (optison(fromtest, left));
    case 'p':
	return (!S_ISFIFO(dostat(left)));
    case 'r':
	return (!doaccess(left, R_OK));
    case 's':
	return !((st = getstat(left)) && !!(st->st_size));
    case 'S':
	return (!S_ISSOCK(dostat(left)));
    case 'u':
	return (!(dostat(left) & S_ISUID));
    case 'w':
	return (!doaccess(left, W_OK));
    case 'x':
	if (privasserted()) {
	    mode_t mode = dostat(left);
	    return !((mode & S_IXUGO) || S_ISDIR(mode));
	}
	return !doaccess(left, X_OK);
    case 'z':
	return !!(strlen(left));
    case 'h':
    case 'L':
	return (!S_ISLNK(dolstat(left)));
    case 'O':
	return !((st = getstat(left)) && st->st_uid == geteuid());
    case 'G':
	return !((st = getstat(left)) && st->st_gid == getegid());
    case 'N':
#if defined(GET_ST_MTIME_NSEC) && defined(GET_ST_ATIME_NSEC)
	if (!(st = getstat(left)))
	    return 1;
        return (st->st_atime == st->st_mtime) ?
        	GET_ST_ATIME_NSEC(*st) > GET_ST_MTIME_NSEC(*st) :
        	st->st_atime > st->st_mtime;
#else
	return !((st = getstat(left)) && st->st_atime <= st->st_mtime);
#endif
    case 't':
	return !isatty(mathevali(left));
    case COND_NT:
    case COND_OT:
	{
	    time_t a;
#ifdef GET_ST_MTIME_NSEC
	    long nsecs;
#endif

	    if (!(st = getstat(left)))
		return 1;
	    a = st->st_mtime;
#ifdef GET_ST_MTIME_NSEC
	    nsecs = GET_ST_MTIME_NSEC(*st);
#endif
	    if (!(st = getstat(right)))
		return 1;
#ifdef GET_ST_MTIME_NSEC
	    if (a == st->st_mtime) {
                return !((ctype == COND_NT) ? nsecs > GET_ST_MTIME_NSEC(*st) :
                        nsecs < GET_ST_MTIME_NSEC(*st));
	    }
#endif
	    return !((ctype == COND_NT) ? a > st->st_mtime : a < st->st_mtime);
	}
    case COND_EF:
	{
	    dev_t d;
	    ino_t i;

	    if (!(st = getstat(left)))
		return 1;
	    d = st->st_dev;
	    i = st->st_ino;
	    if (!(st = getstat(right)))
		return 1;
	    return !(d == st->st_dev && i == st->st_ino);
	}
    default:
	zwarnnam(fromtest, "bad cond code");
	return 2;
    }
}
示例#4
0
文件: system.c 项目: Jaharmi/zsh
static int
bin_sysread(char *nam, char **args, Options ops, UNUSED(int func))
{
    int infd = 0, outfd = -1, bufsize = SYSREAD_BUFSIZE, count;
    char *outvar = NULL, *countvar = NULL, *inbuf;

    /* -i: input file descriptor if not stdin */
    if (OPT_ISSET(ops, 'i')) {
	infd = getposint(OPT_ARG(ops, 'i'), nam);
	if (infd < 0)
	    return 1;
    }

    /* -o: output file descriptor, else store in REPLY */
    if (OPT_ISSET(ops, 'o')) {
	if (*args) {
	    zwarnnam(nam, "no argument allowed with -o");
	    return 1;
	}
	outfd = getposint(OPT_ARG(ops, 'o'), nam);
	if (outfd < 0)
	    return 1;
    }

    /* -s: buffer size if not default SYSREAD_BUFSIZE */
    if (OPT_ISSET(ops, 's')) {
	bufsize = getposint(OPT_ARG(ops, 's'), nam);
	if (bufsize < 0)
	    return 1;
    }

    /* -c: name of variable to store count of transferred bytes */
    if (OPT_ISSET(ops, 'c')) {
	countvar = OPT_ARG(ops, 'c');
	if (!isident(countvar)) {
	    zwarnnam(nam, "not an identifier: %s", countvar);
	    return 1;
	}
    }

    if (*args) {
	/*
	 * Variable in which to store result if doing a plain read.
	 * Default variable if not specified is REPLY.
	 * If writing, only stuff we couldn't write is stored here,
	 * no default in that case (we just discard it if no variable).
	 */
	outvar = *args;
	if (!isident(outvar)) {
	    zwarnnam(nam, "not an identifier: %s", outvar);
	    return 1;
	}
    }

    inbuf = zhalloc(bufsize);

#if defined(HAVE_POLL) || defined(HAVE_SELECT)
    /* -t: timeout */
    if (OPT_ISSET(ops, 't'))
    {
# ifdef HAVE_POLL
	struct pollfd poll_fd;
	mnumber to_mn;
	int to_int, ret;

	poll_fd.fd = infd;
	poll_fd.events = POLLIN;

	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;
	if (to_mn.type == MN_FLOAT)
	    to_int = (int) (1000 * to_mn.u.d);
	else
	    to_int = 1000 * (int)to_mn.u.l;

	while ((ret = poll(&poll_fd, 1, to_int)) < 0) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# else
	/* using select */
	struct timeval select_tv;
	fd_set fds;
	mnumber to_mn;
	int ret;

	FD_ZERO(&fds);
	FD_SET(infd, &fds);
	to_mn = matheval(OPT_ARG(ops, 't'));
	if (errflag)
	    return 1;

	if (to_mn.type == MN_FLOAT) {
	    select_tv.tv_sec = (int) to_mn.u.d;
	    select_tv.tv_usec =
		(int) ((to_mn.u.d - select_tv.tv_sec) * 1e6);
	} else {
	    select_tv.tv_sec = (int) to_mn.u.l;
	    select_tv.tv_usec = 0;
	}

	while ((ret = select(infd+1, (SELECT_ARG_2_T) &fds,
			     NULL, NULL,&select_tv)) < 1) {
	    if (errno != EINTR || errflag || retflag || breaks || contflag)
		break;
	}
	if (ret <= 0) {
	    /* treat non-timeout error as error on read */
	    return ret ? 2 : 4;
	}
# endif
    }
#endif

    while ((count = read(infd, inbuf, bufsize)) < 0) {
	if (errno != EINTR || errflag || retflag || breaks || contflag)
	    break;
    }
    if (countvar)
	setiparam(countvar, count);
    if (count < 0)
	return 2;

    if (outfd >= 0) {
	if (!count)
	    return 5;
	while (count > 0) {
	    int ret;

	    ret = write(outfd, inbuf, count);
	    if (ret < 0) {
		if (errno == EINTR && !errflag &&
		    !retflag && !breaks && !contflag)
		    continue;
		if (outvar)
		    setsparam(outvar, metafy(inbuf, count, META_DUP));
		if (countvar)
		    setiparam(countvar, count);
		return 3;
	    }
	    inbuf += ret;
	    count -= ret;
	}
	return 0;
    }

    if (!outvar)
	    outvar = "REPLY";
    /* do this even if we read zero bytes */
    setsparam(outvar, metafy(inbuf, count, META_DUP));

    return count ? 0 : 5;
}