Exemplo n.º 1
0
mod_export char *
parse_subscript(char *s, int sub)
{
    int l = strlen(s), err;
    char *t;

    if (!*s || *s == ']')
	return 0;
    lexsave();
    untokenize(t = dupstring(s));
    inpush(t, 0, NULL);
    strinbeg(0);
    len = 0;
    bptr = tokstr = s;
    bsiz = l + 1;
    err = dquote_parse(']', sub);
    if (err) {
	err = *bptr;
	*bptr = 0;
	untokenize(s);
	*bptr = err;
	s = 0;
    } else
	s = bptr;
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty.");
    lexrestore();
    return s;
}
Exemplo n.º 2
0
Arquivo: lex.c Projeto: netroby/zsh
mod_export char *
parse_subscript(char *s, int sub, int endchar)
{
    int l = strlen(s), err;
    char *t;

    if (!*s || *s == endchar)
	return 0;
    zcontext_save();
    untokenize(t = dupstring(s));
    inpush(t, 0, NULL);
    strinbeg(0);
    lexbuf.len = 0;
    lexbuf.ptr = tokstr = s;
    lexbuf.siz = l + 1;
    err = dquote_parse(endchar, sub);
    if (err) {
	err = *lexbuf.ptr;
	*lexbuf.ptr = '\0';
	untokenize(s);
	*lexbuf.ptr = err;
	s = NULL;
    } else {
	s = lexbuf.ptr;
    }
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty.");
    zcontext_restore();
    return s;
}
Exemplo n.º 3
0
char *
getjobtext(Eprog prog, Wordcode c)
{
    static char jbuf[JOBTEXTSIZE];

    struct estate s;

    if (!c)
	c = prog->prog;

    useeprog(prog);		/* mark as used */
    s.prog = prog;
    s.pc = c;
    s.strs = prog->strs;

    tindent = 0;
    tnewlins = 0;
    tbuf = NULL;
    tptr = jbuf;
    tlim = tptr + JOBTEXTSIZE - 1;
    tjob = 1;
    gettext2(&s);
    *tptr = '\0';
    freeeprog(prog);		/* mark as unused */
    untokenize(jbuf);
    return jbuf;
}
Exemplo n.º 4
0
Arquivo: math.c Projeto: brandt/zsh
static mnumber
setmathvar(struct mathvalue *mvp, mnumber v)
{
    if (mvp->pval) {
	/*
	 * This value may have been hanging around for a while.
	 * Be ultra-paranoid in checking the variable is still valid.
	 */
	char *s = mvp->lval, *ptr;
	Param pm;
	DPUTS(!mvp->lval, "no variable name but variable value in math");
	if ((ptr = strchr(s, '[')))
	    s = dupstrpfx(s, ptr - s);
	pm = (Param) paramtab->getnode(paramtab, s);
	if (pm == mvp->pval->pm) {
	    if (noeval)
		return v;
	    setnumvalue(mvp->pval, v);
	    return v;
	}
	/* Different parameter, start again from scratch */
	mvp->pval = NULL;
    }
    if (!mvp->lval) {
	zerr("lvalue required");
	v.type = MN_INTEGER;
	v.u.l = 0;
	return v;
    }
    if (noeval)
	return v;
    untokenize(mvp->lval);
    setnparam(mvp->lval, v);
    return v;
}
Exemplo n.º 5
0
mod_export char *
getpermtext(Eprog prog, Wordcode c, int start_indent)
{
    struct estate s;

    if (!c)
	c = prog->prog;

    useeprog(prog);		/* mark as used */

    s.prog = prog;
    s.pc = c;
    s.strs = prog->strs;

    tindent = start_indent;
    tnewlins = 1;
    tbuf = (char *)zalloc(tsiz = 32);
    tptr = tbuf;
    tlim = tbuf + tsiz;
    tjob = 0;
    if (prog->len)
	gettext2(&s);
    *tptr = '\0';
    freeeprog(prog);		/* mark as unused */
    untokenize(tbuf);
    return tbuf;
}
Exemplo n.º 6
0
Arquivo: lex.c Projeto: AMDmi3/zsh
mod_export char *
parse_subscript(char *s, int sub, int endchar)
{
    int l = strlen(s), err, toklen;
    char *t;

    if (!*s || *s == endchar)
	return 0;
    zcontext_save();
    untokenize(t = dupstring(s));
    inpush(t, 0, NULL);
    strinbeg(0);
    /*
     * Warning to Future Generations:
     *
     * This way of passing the subscript through the lexer is brittle.
     * Code above this for several layers assumes that when we tokenise
     * the input it goes into the same place as the original string.
     * However, the lexer may overwrite later bits of the string or
     * reallocate it, in particular when expanding aliaes.  To get
     * around this, we copy the string and then copy it back.  This is a
     * bit more robust but still relies on the underlying assumption of
     * length preservation.
     */
    lexbuf.len = 0;
    lexbuf.ptr = tokstr = dupstring(s);
    lexbuf.siz = l + 1;
    err = dquote_parse(endchar, sub);
    toklen = (int)(lexbuf.ptr - tokstr);
    DPUTS(toklen > l, "Bad length for parsed subscript");
    memcpy(s, tokstr, toklen);
    if (err) {
	char *strend = s + toklen;
	err = *strend;
	*strend = '\0';
	untokenize(s);
	*strend = err;
	s = NULL;
    } else {
	s += toklen;
    }
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subscript: cmdstack not empty.");
    zcontext_restore();
    return s;
}
Exemplo n.º 7
0
Arquivo: cond.c Projeto: AMDmi3/zsh
mod_export zlong
cond_val(char **args, int num)
{
    char *s = args[num];

    if (has_token(s)) {
	singsub(&s);
	untokenize(s);
    }
    return mathevali(s);
}
Exemplo n.º 8
0
Arquivo: cond.c Projeto: AMDmi3/zsh
mod_export char *
cond_str(char **args, int num, int raw)
{
    char *s = args[num];

    if (has_token(s)) {
	singsub(&s);
	if (!raw)
	    untokenize(s);
    }
    return s;
}
Exemplo n.º 9
0
mod_export int
parse_subst_string(char *s)
{
    int c, l = strlen(s), err, olen, lexstop_ret;

    if (!*s || !strcmp(s, nulstring))
	return 0;
    lexsave();
    untokenize(s);
    inpush(dupstring(s), 0, NULL);
    strinbeg(0);
    len = 0;
    bptr = tokstr = s;
    bsiz = l + 1;
    c = hgetc();
    lexstop_ret = lexstop;
    c = gettokstr(c, 1);
    err = errflag;
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty.");
    olen = len;
    lexrestore();
    errflag = err;
    if (c == LEXERR) {
	untokenize(s);
	return 1;
    }
#ifdef DEBUG
    if (c != STRING || olen != l || errflag) {
	fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n",
		olen < l ? "len < l" : errflag ? "errflag" : "c != STRING");
	fflush(stderr);
	untokenize(s);
	return 1;
    }
#endif
    return 0;
}
Exemplo n.º 10
0
mod_export int
parsestr(char *s)
{
    int err;

    if ((err = parsestrnoerr(s))) {
	untokenize(s);
	if (err > 32 && err < 127)
	    zerr("parse error near `%c'", NULL, err);
	else
	    zerr("parse error", NULL, 0);
    }
    return err;
}
Exemplo n.º 11
0
Arquivo: cond.c Projeto: AMDmi3/zsh
static void
tracemodcond(char *name, char **args, int inf)
{
    char **aptr;

    args = arrdup(args);
    for (aptr = args; *aptr; aptr++)
	untokenize(*aptr);
    if (inf) {
	fprintf(xtrerr, " %s %s %s", args[0], name, args[1]);
    } else {
	fprintf(xtrerr, " %s", name);
	while (*args)
	    fprintf(xtrerr, " %s", *args++);
    }
}
Exemplo n.º 12
0
Arquivo: lex.c Projeto: AMDmi3/zsh
mod_export int
parsestr(char **s)
{
    int err;

    if ((err = parsestrnoerr(s))) {
	untokenize(*s);
	if (!(errflag & ERRFLAG_INT)) {
	    if (err > 32 && err < 127)
		zerr("parse error near `%c'", err);
	    else
		zerr("parse error");
	}
    }
    return err;
}
Exemplo n.º 13
0
bool Triggerconf::checkItemCount (STRING_LIST path, unsigned int items)
{
	if (path.size () != items) {
		
		char buf [16];

#ifdef WIN32
		ultoa (items, buf, 10);
#else
		snprintf (buf, 10, "%d", items);
#endif
		
		setError ("path " + untokenize (path) + " does not contain " + string(buf) + " items");
		return false;
	
	} else
		return true;
}
Exemplo n.º 14
0
mod_export int
parsestrnoerr(char *s)
{
    int l = strlen(s), err;

    lexsave();
    untokenize(s);
    inpush(dupstring(s), 0, NULL);
    strinbeg(0);
    len = 0;
    bptr = tokstr = s;
    bsiz = l + 1;
    err = dquote_parse('\0', 1);
    *bptr = '\0';
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parsestr: cmdstack not empty.");
    lexrestore();
    return err;
}
Exemplo n.º 15
0
Arquivo: lex.c Projeto: AMDmi3/zsh
mod_export int
parsestrnoerr(char **s)
{
    int l = strlen(*s), err;

    zcontext_save();
    untokenize(*s);
    inpush(dupstring(*s), 0, NULL);
    strinbeg(0);
    lexbuf.len = 0;
    lexbuf.ptr = tokstr = *s;
    lexbuf.siz = l + 1;
    err = dquote_parse('\0', 1);
    if (tokstr)
	*s = tokstr;
    *lexbuf.ptr = '\0';
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parsestr: cmdstack not empty.");
    zcontext_restore();
    return err;
}
Exemplo n.º 16
0
Arquivo: lex.c Projeto: AMDmi3/zsh
mod_export int
parse_subst_string(char *s)
{
    int c, l = strlen(s), err;
    char *ptr;
    enum lextok ctok;

    if (!*s || !strcmp(s, nulstring))
	return 0;
    zcontext_save();
    untokenize(s);
    inpush(dupstring(s), 0, NULL);
    strinbeg(0);
    lexbuf.len = 0;
    lexbuf.ptr = tokstr = s;
    lexbuf.siz = l + 1;
    c = hgetc();
    ctok = gettokstr(c, 1);
    err = errflag;
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty.");
    zcontext_restore();
    /* Keep any interrupt error status */
    errflag = err | (errflag & ERRFLAG_INT);
    if (ctok == LEXERR) {
	untokenize(s);
	return 1;
    }
#ifdef DEBUG
    /*
     * Historical note: we used to check here for olen (the value of lexbuf.len
     * before zcontext_restore()) == l, but that's not necessarily the case if
     * we stripped an RCQUOTE.
     */
    if (ctok != STRING || (errflag && !noerrs)) {
	fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n",
		errflag ? "errflag" : "ctok != STRING");
	fflush(stderr);
	untokenize(s);
	return 1;
    }
#endif
    /* Check for $'...' quoting.  This needs special handling. */
    for (ptr = s; *ptr; )
    {
	if (*ptr == String && ptr[1] == Snull)
	{
	    char *t;
	    int len, tlen, diff;
	    t = getkeystring(ptr + 2, &len, GETKEYS_DOLLARS_QUOTE, NULL);
	    len += 2;
	    tlen = strlen(t);
	    diff = len - tlen;
	    /*
	     * Yuk.
	     * parse_subst_string() currently handles strings in-place.
	     * That's not so easy to fix without knowing whether
	     * additional memory should come off the heap or
	     * otherwise.  So we cheat by copying the unquoted string
	     * into place, unless it's too long.  That's not the
	     * normal case, but I'm worried there are pathological
	     * cases with converting metafied multibyte strings.
	     * If someone can prove there aren't I will be very happy.
	     */
	    if (diff < 0) {
		DPUTS(1, "$'...' subst too long: fix get_parse_string()");
		return 1;
	    }
	    memcpy(ptr, t, tlen);
	    ptr += tlen;
	    if (diff > 0) {
		char *dptr = ptr;
		char *sptr = ptr + diff;
		while ((*dptr++ = *sptr++))
		    ;
	    }
	} else
	    ptr++;
    }
    return 0;
}
Exemplo n.º 17
0
Arquivo: loop.c Projeto: phy1729/zsh
int
execcase(Estate state, int do_exec)
{
    Wordcode end, next;
    wordcode code = state->pc[-1];
    char *word, *pat;
    int npat, save, nalts, ialt, patok;
    Patprog *spprog, pprog;

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

    word = ecgetstr(state, EC_DUP, NULL);
    singsub(&word);
    untokenize(word);

    cmdpush(CS_CASE);
    while (state->pc < end) {
	code = *state->pc++;
	if (wc_code(code) != WC_CASE)
	    break;

	save = 0;
	next = state->pc + WC_CASE_SKIP(code);
	nalts = *state->pc++;
	ialt = patok = 0;

	if (isset(XTRACE)) {
	    printprompt4();
	    fprintf(xtrerr, "case %s (", word);
	}

	while (!patok && nalts) {
	    npat = state->pc[1];
	    spprog = state->prog->pats + npat;
	    pprog = NULL;
	    pat = NULL;
	
	    if (isset(XTRACE)) {
		int htok = 0;
		pat = dupstring(ecrawstr(state->prog, state->pc, &htok));
		if (htok)
		    singsub(&pat);

		if (ialt++)
		    fprintf(stderr, " | ");
		quote_tokenized_output(pat, xtrerr);
	    }

	    if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2)
		pprog = *spprog;

	    if (!pprog) {
		if (!pat) {
		    char *opat;
		    int htok = 0;

		    pat = dupstring(opat = ecrawstr(state->prog,
						    state->pc, &htok));
		    if (htok)
			singsub(&pat);
		    save = (!(state->prog->flags & EF_HEAP) &&
			    !strcmp(pat, opat) && *spprog != dummy_patprog2);
		}
		if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC),
					 NULL)))
		    zerr("bad pattern: %s", pat);
		else if (save)
		    *spprog = pprog;
	    }
	    if (pprog && pattry(pprog, word))
		patok = 1;
	    state->pc += 2;
	    nalts--;
	}
	state->pc += 2 * nalts;
	if (isset(XTRACE)) {
	    fprintf(xtrerr, ")\n");
	    fflush(xtrerr);
	}
	if (patok) {
	    execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
				do_exec));
	    while (!retflag && wc_code(code) == WC_CASE &&
		   WC_CASE_TYPE(code) == WC_CASE_AND && state->pc < end) {
		state->pc = next;
		code = *state->pc++;
		next = state->pc + WC_CASE_SKIP(code);
		nalts = *state->pc++;
		state->pc += 2 * nalts;
		execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) &&
				    do_exec));
	    }
	    if (WC_CASE_TYPE(code) != WC_CASE_TESTAND)
		break;
	}
	state->pc = next;
    }
    cmdpop();

    state->pc = end;

    return lastval;
}
Exemplo n.º 18
0
Arquivo: loop.c Projeto: 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;
}
Exemplo n.º 19
0
Arquivo: cond.c Projeto: 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;
    }
}
Exemplo n.º 20
0
Arquivo: math.c Projeto: blueyed/zsh
static mnumber
setmathvar(struct mathvalue *mvp, mnumber v)
{
    Param pm;

    if (mvp->pval) {
	/*
	 * This value may have been hanging around for a while.
	 * Be ultra-paranoid in checking the variable is still valid.
	 */
	char *s = mvp->lval, *ptr;
	Param pm;
	DPUTS(!mvp->lval, "no variable name but variable value in math");
	if ((ptr = strchr(s, '[')))
	    s = dupstrpfx(s, ptr - s);
	pm = (Param) paramtab->getnode(paramtab, s);
	if (pm == mvp->pval->pm) {
	    if (noeval)
		return v;
	    setnumvalue(mvp->pval, v);
	    return v;
	}
	/* Different parameter, start again from scratch */
	mvp->pval = NULL;
    }
    if (!mvp->lval) {
	zerr("lvalue required");
	v.type = MN_INTEGER;
	v.u.l = 0;
	return v;
    }
    if (noeval)
	return v;
    untokenize(mvp->lval);
    pm = setnparam(mvp->lval, v);
    if (pm) {
	/*
	 * If we are performing an assignment, we return the
	 * number with the same type as the parameter we are
	 * assigning to, in the spirit of the way assignments
	 * in C work.  Note this was a change to long-standing
	 * zsh behaviour.
	 */
	switch (PM_TYPE(pm->node.flags)) {
	case PM_INTEGER:
	    if (v.type != MN_INTEGER) {
		v.u.l = (zlong)v.u.d;
		v.type = MN_INTEGER;
	    }
	    break;

	case PM_EFLOAT:
	case PM_FFLOAT:
	    if (v.type != MN_FLOAT) {
		v.u.d = (double)v.u.l;
		v.type = MN_FLOAT;
	    }
	    break;
	}
    }
    return v;
}