Example #1
0
File: text.c Project: Mybelieve/zsh
static void
taddassign(wordcode code, Estate state, int typeset)
{
    /* name */
    taddstr(ecgetstr(state, EC_NODUP, NULL));
    /* value... maybe */
    if (WC_ASSIGN_TYPE2(code) == WC_ASSIGN_INC) {
	if (typeset) {
	    /* dummy assignment --- just var name */
	    (void)ecgetstr(state, EC_NODUP, NULL);
	    taddchr(' ');
	    return;
	}
	taddchr('+');
    }
    taddchr('=');
    if (WC_ASSIGN_TYPE(code) == WC_ASSIGN_ARRAY) {
	taddchr('(');
	taddlist(state, WC_ASSIGN_NUM(code));
	taddstr(") ");
    } else {
	taddstr(ecgetstr(state, EC_NODUP, NULL));
	taddchr(' ');
    }
}
Example #2
0
static void
taddlist(Estate state, int num)
{
    if (num) {
	while (num--) {
	    taddstr(ecgetstr(state, EC_NODUP, NULL));
	    taddchr(' ');
	}
	tptr--;
    }
}
Example #3
0
int
execrepeat(Estate state, UNUSED(int do_exec))
{
    Wordcode end, loop;
    wordcode code = state->pc[-1];
    int count, htok = 0;
    char *tmp;
    int old_simple_pline = simple_pline;

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

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

    lastval = 0;
    tmp = ecgetstr(state, EC_DUPTOK, &htok);
    if (htok)
	singsub(&tmp);
    count = mathevali(tmp);
    if (errflag)
	return 1;
    pushheap();
    cmdpush(CS_REPEAT);
    loops++;
    loop = state->pc;
    while (count-- > 0) {
	state->pc = loop;
	execlist(state, 1, 0);
	freeheap();
	if (breaks) {
	    breaks--;
	    if (breaks || !contflag)
		break;
	    contflag = 0;
	}
	if (errflag) {
	    lastval = 1;
	    break;
	}
	if (retflag)
	    break;
    }
    cmdpop();
    popheap();
    loops--;
    simple_pline = old_simple_pline;
    state->pc = end;
    this_noerrexit = 1;
    return lastval;
}
Example #4
0
int
execrepeat(Estate state, UNUSED(int do_exec))
{
    Wordcode end, loop;
    wordcode code = state->pc[-1];
    int count, htok = 0;
    char *tmp;

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

    lastval = 0;
    tmp = ecgetstr(state, EC_DUPTOK, &htok);
    if (htok)
	singsub(&tmp);
    count = atoi(tmp);
    pushheap();
    cmdpush(CS_REPEAT);
    loops++;
    loop = state->pc;
    while (count-- > 0) {
	state->pc = loop;
	execlist(state, 1, 0);
	freeheap();
	if (breaks) {
	    breaks--;
	    if (breaks || !contflag)
		break;
	    contflag = 0;
	}
	if (errflag) {
	    lastval = 1;
	    break;
	}
	if (retflag)
	    break;
    }
    cmdpop();
    popheap();
    loops--;
    state->pc = end;
    return lastval;
}
Example #5
0
static void
gettext2(Estate state)
{
    Tstack s, n;
    int stack = 0;
    wordcode code;

    while (1) {
	if (stack) {
	    if (!(s = tstack))
		break;
	    if (s->pop) {
		tstack = s->prev;
		s->prev = tfree;
		tfree = s;
	    }
	    code = s->code;
	    stack = 0;
	} else {
	    s = NULL;
	    code = *state->pc++;
	}
	switch (wc_code(code)) {
	case WC_LIST:
	    if (!s) {
		s = tpush(code, (WC_LIST_TYPE(code) & Z_END));
		stack = 0;
	    } else {
		if (WC_LIST_TYPE(code) & Z_ASYNC) {
		    taddstr(" &");
		    if (WC_LIST_TYPE(code) & Z_DISOWN)
			taddstr("|");
		}
		if (!(stack = (WC_LIST_TYPE(code) & Z_END))) {
		    if (tnewlins)
			taddnl(0);
		    else
			taddstr((WC_LIST_TYPE(code) & Z_ASYNC) ? " " : "; ");
		    s->code = *state->pc++;
		    s->pop = (WC_LIST_TYPE(s->code) & Z_END);
		}
	    }
	    if (!stack && (WC_LIST_TYPE(s->code) & Z_SIMPLE))
		state->pc++;
	    break;
	case WC_SUBLIST:
	    if (!s) {
                if (!(WC_SUBLIST_FLAGS(code) & WC_SUBLIST_SIMPLE) &&
                    wc_code(*state->pc) != WC_PIPE)
                    stack = -1;
		if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT)
		    taddstr(stack ? "!" : "! ");
		if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_COPROC)
		    taddstr(stack ? "coproc" : "coproc ");
		s = tpush(code, (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END));
	    } else {
		if (!(stack = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END))) {
		    taddstr((WC_SUBLIST_TYPE(code) == WC_SUBLIST_OR) ?
			    " || " : " && ");
		    s->code = *state->pc++;
		    s->pop = (WC_SUBLIST_TYPE(s->code) == WC_SUBLIST_END);
		    if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_NOT)
			taddstr("! ");
		    if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_COPROC)
			taddstr("coproc ");
		}
	    }
	    if (stack < 1 && (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_SIMPLE))
		state->pc++;
	    break;
	case WC_PIPE:
	    if (!s) {
		tpush(code, (WC_PIPE_TYPE(code) == WC_PIPE_END));
		if (WC_PIPE_TYPE(code) == WC_PIPE_MID)
		    state->pc++;
	    } else {
		if (!(stack = (WC_PIPE_TYPE(code) == WC_PIPE_END))) {
		    taddstr(" | ");
		    s->code = *state->pc++;
		    if (!(s->pop = (WC_PIPE_TYPE(s->code) == WC_PIPE_END)))
			state->pc++;
		}
	    }
	    break;
	case WC_REDIR:
	    if (!s) {
		state->pc--;
		n = tpush(code, 1);
		n->u._redir.list = ecgetredirs(state);
	    } else {
		getredirs(s->u._redir.list);
		stack = 1;
	    }
	    break;
	case WC_ASSIGN:
	    taddstr(ecgetstr(state, EC_NODUP, NULL));
	    if (WC_ASSIGN_TYPE2(code) == WC_ASSIGN_INC) taddchr('+');
	    taddchr('=');
	    if (WC_ASSIGN_TYPE(code) == WC_ASSIGN_ARRAY) {
		taddchr('(');
		taddlist(state, WC_ASSIGN_NUM(code));
		taddstr(") ");
	    } else {
		taddstr(ecgetstr(state, EC_NODUP, NULL));
		taddchr(' ');
	    }
	    break;
	case WC_SIMPLE:
	    taddlist(state, WC_SIMPLE_ARGC(code));
	    stack = 1;
	    break;
	case WC_SUBSH:
	    if (!s) {
		taddstr("(");
		tindent++;
		taddnl(1);
		n = tpush(code, 1);
		n->u._subsh.end = state->pc + WC_SUBSH_SKIP(code);
		/* skip word only use for try/always */
		state->pc++;
	    } else {
		state->pc = s->u._subsh.end;
		dec_tindent();
		/* semicolon is optional here but more standard */
		taddnl(0);
		taddstr(")");
		stack = 1;
	    }
	    break;
	case WC_CURSH:
	    if (!s) {
		taddstr("{");
		tindent++;
		taddnl(1);
		n = tpush(code, 1);
		n->u._subsh.end = state->pc + WC_CURSH_SKIP(code);
		/* skip word only use for try/always */
		state->pc++;
	    } else {
		state->pc = s->u._subsh.end;
		dec_tindent();
		/* semicolon is optional here but more standard */
		taddnl(0);
		taddstr("}");
		stack = 1;
	    }
	    break;
	case WC_TIMED:
	    if (!s) {
		taddstr("time");
		if (WC_TIMED_TYPE(code) == WC_TIMED_PIPE) {
		    taddchr(' ');
		    tindent++;
		    tpush(code, 1);
		} else
		    stack = 1;
	    } else {
		dec_tindent();
		stack = 1;
	    }
	    break;
	case WC_FUNCDEF:
	    if (!s) {
		Wordcode p = state->pc;
		Wordcode end = p + WC_FUNCDEF_SKIP(code);

		taddlist(state, *state->pc++);
		if (tjob) {
		    taddstr(" () { ... }");
		    state->pc = end;
		    stack = 1;
		} else {
		    taddstr(" () {");
		    tindent++;
		    taddnl(1);
		    n = tpush(code, 1);
		    n->u._funcdef.strs = state->strs;
		    n->u._funcdef.end = end;
		    state->strs += *state->pc;
		    state->pc += 3;
		}
	    } else {
		state->strs = s->u._funcdef.strs;
		state->pc = s->u._funcdef.end;
		dec_tindent();
		taddnl(0);
		taddstr("}");
		stack = 1;
	    }
	    break;
	case WC_FOR:
	    if (!s) {
		taddstr("for ");
		if (WC_FOR_TYPE(code) == WC_FOR_COND) {
		    taddstr("((");
		    taddstr(ecgetstr(state, EC_NODUP, NULL));
		    taddstr("; ");
		    taddstr(ecgetstr(state, EC_NODUP, NULL));
		    taddstr("; ");
		    taddstr(ecgetstr(state, EC_NODUP, NULL));
		    taddstr(")) do");
		} else {
		    taddlist(state, *state->pc++);
		    if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
			taddstr(" in ");
			taddlist(state, *state->pc++);
		    }
		    taddnl(0);
		    taddstr("do");
		}
		tindent++;
		taddnl(0);
		tpush(code, 1);
	    } else {
		dec_tindent();
		taddnl(0);
		taddstr("done");
		stack = 1;
	    }
	    break;
	case WC_SELECT:
	    if (!s) {
		taddstr("select ");
		taddstr(ecgetstr(state, EC_NODUP, NULL));
		if (WC_SELECT_TYPE(code) == WC_SELECT_LIST) {
		    taddstr(" in ");
		    taddlist(state, *state->pc++);
		}
		tindent++;
		taddnl(0);
		tpush(code, 1);
	    } else {
		dec_tindent();
		taddnl(0);
		taddstr("done");
		stack = 1;
	    }
	    break;
	case WC_WHILE:
	    if (!s) {
		taddstr(WC_WHILE_TYPE(code) == WC_WHILE_UNTIL ?
			"until " : "while ");
		tindent++;
		tpush(code, 0);
	    } else if (!s->pop) {
		dec_tindent();
		taddnl(0);
		taddstr("do");
		tindent++;
		taddnl(0);
		s->pop = 1;
	    } else {
		dec_tindent();
		taddnl(0);
		taddstr("done");
		stack = 1;
	    }
	    break;
	case WC_REPEAT:
	    if (!s) {
		taddstr("repeat ");
		taddstr(ecgetstr(state, EC_NODUP, NULL));
		taddnl(0);
		taddstr("do");
		tindent++;
		taddnl(0);
		tpush(code, 1);
	    } else {
		dec_tindent();
		taddnl(0);
		taddstr("done");
		stack = 1;
	    }
	    break;
	case WC_CASE:
	    if (!s) {
		Wordcode end = state->pc + WC_CASE_SKIP(code);

		taddstr("case ");
		taddstr(ecgetstr(state, EC_NODUP, NULL));
		taddstr(" in");

		if (state->pc >= end) {
		    if (tnewlins)
			taddnl(0);
		    else
			taddchr(' ');
		    taddstr("esac");
		    stack = 1;
		} else {
		    tindent++;
		    if (tnewlins)
			taddnl(0);
		    else
			taddchr(' ');
		    taddstr("(");
		    code = *state->pc++;
		    taddstr(ecgetstr(state, EC_NODUP, NULL));
		    state->pc++;
		    taddstr(") ");
		    tindent++;
		    n = tpush(code, 0);
		    n->u._case.end = end;
		    n->pop = (state->pc - 2 + WC_CASE_SKIP(code) >= end);
		}
	    } else if (state->pc < s->u._case.end) {
		dec_tindent();
		switch (WC_CASE_TYPE(code)) {
		case WC_CASE_OR:
		    taddstr(" ;;");
		    break;

		case WC_CASE_AND:
		    taddstr(";&");
		    break;

		default:
		    taddstr(";|");
		    break;
		}
		if (tnewlins)
		    taddnl(0);
		else
		    taddchr(' ');
		taddstr("(");
		code = *state->pc++;
		taddstr(ecgetstr(state, EC_NODUP, NULL));
		state->pc++;
		taddstr(") ");
		tindent++;
		s->code = code;
		s->pop = ((state->pc - 2 + WC_CASE_SKIP(code)) >=
			  s->u._case.end);
	    } else {
		dec_tindent();
		switch (WC_CASE_TYPE(code)) {
		case WC_CASE_OR:
		    taddstr(" ;;");
		    break;

		case WC_CASE_AND:
		    taddstr(";&");
		    break;

		default:
		    taddstr(";|");
		    break;
		}
		dec_tindent();
		if (tnewlins)
		    taddnl(0);
		else
		    taddchr(' ');
		taddstr("esac");
		stack = 1;
	    }
	    break;
	case WC_IF:
	    if (!s) {
		Wordcode end = state->pc + WC_IF_SKIP(code);

		taddstr("if ");
		tindent++;
		state->pc++;

		n = tpush(code, 0);
		n->u._if.end = end;
		n->u._if.cond = 1;
	    } else if (s->pop) {
		stack = 1;
	    } else if (s->u._if.cond) {
		dec_tindent();
		taddnl(0);
		taddstr("then");
		tindent++;
		taddnl(0);
		s->u._if.cond = 0;
	    } else if (state->pc < s->u._if.end) {
		dec_tindent();
		taddnl(0);
		code = *state->pc++;
		if (WC_IF_TYPE(code) == WC_IF_ELIF) {
		    taddstr("elif ");
		    tindent++;
		    s->u._if.cond = 1;
		} else {
		    taddstr("else");
		    tindent++;
		    taddnl(0);
		}
	    } else {
		s->pop = 1;
		dec_tindent();
		taddnl(0);
		taddstr("fi");
		stack = 1;
	    }
	    break;
	case WC_COND:
	    {
		static char *c1[] = {
		    "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
		    "-ne", "-lt", "-gt", "-le", "-ge", "=~"
		};

		int ctype;

		if (!s) {
		    taddstr("[[ ");
		    n = tpush(code, 1);
		    n->u._cond.par = 2;
		} else if (s->u._cond.par == 2) {
		    taddstr(" ]]");
		    stack = 1;
		    break;
		} else if (s->u._cond.par == 1) {
		    taddstr(" )");
		    stack = 1;
		    break;
		} else if (WC_COND_TYPE(s->code) == COND_AND) {
		    taddstr(" && ");
		    code = *state->pc++;
		    if (WC_COND_TYPE(code) == COND_OR) {
			taddstr("( ");
			n = tpush(code, 1);
			n->u._cond.par = 1;
		    }
		} else if (WC_COND_TYPE(s->code) == COND_OR) {
		    taddstr(" || ");
		    code = *state->pc++;
		    if (WC_COND_TYPE(code) == COND_AND) {
			taddstr("( ");
			n = tpush(code, 1);
			n->u._cond.par = 1;
		    }
		}
		while (!stack) {
		    switch ((ctype = WC_COND_TYPE(code))) {
		    case COND_NOT:
			taddstr("! ");
			code = *state->pc++;
			if (WC_COND_TYPE(code) <= COND_OR) {
			    taddstr("( ");
			    n = tpush(code, 1);
			    n->u._cond.par = 1;
			}
			break;
		    case COND_AND:
			n = tpush(code, 1);
			n->u._cond.par = 0;
			code = *state->pc++;
			if (WC_COND_TYPE(code) == COND_OR) {
			    taddstr("( ");
			    n = tpush(code, 1);
			    n->u._cond.par = 1;
			}
			break;
		    case COND_OR:
			n = tpush(code, 1);
			n->u._cond.par = 0;
			code = *state->pc++;
			if (WC_COND_TYPE(code) == COND_AND) {
			    taddstr("( ");
			    n = tpush(code, 1);
			    n->u._cond.par = 1;
			}
			break;
		    case COND_MOD:
			taddstr(ecgetstr(state, EC_NODUP, NULL));
			taddchr(' ');
			taddlist(state, WC_COND_SKIP(code));
			stack = 1;
			break;
		    case COND_MODI:
			{
			    char *name = ecgetstr(state, EC_NODUP, NULL);

			    taddstr(ecgetstr(state, EC_NODUP, NULL));
			    taddchr(' ');
			    taddstr(name);
			    taddchr(' ');
			    taddstr(ecgetstr(state, EC_NODUP, NULL));
			    stack = 1;
			}
			break;
		    default:
			if (ctype < COND_MOD) {
			    /* Binary test: `a = b' etc. */
			    taddstr(ecgetstr(state, EC_NODUP, NULL));
			    taddstr(" ");
			    taddstr(c1[ctype - COND_STREQ]);
			    taddstr(" ");
			    taddstr(ecgetstr(state, EC_NODUP, NULL));
			    if (ctype == COND_STREQ ||
				ctype == COND_STRNEQ)
				state->pc++;
			} else {
			    /* Unary test: `-f foo' etc. */ 
			    char c2[4];

			    c2[0] = '-';
			    c2[1] = ctype;
			    c2[2] = ' ';
			    c2[3] = '\0';
			    taddstr(c2);
			    taddstr(ecgetstr(state, EC_NODUP, NULL));
			}
			stack = 1;
			break;
		    }
		}
	    }
	    break;
	case WC_ARITH:
	    taddstr("((");
	    taddstr(ecgetstr(state, EC_NODUP, NULL));
	    taddstr("))");
	    stack = 1;
	    break;
	case WC_TRY:
	    if (!s) {
		taddstr("{");
		tindent++;
		taddnl(0);
		n = tpush(code, 0);
		state->pc++;
		/* this is the end of the try block alone */
		n->u._subsh.end = state->pc + WC_CURSH_SKIP(state->pc[-1]);
	    } else if (!s->pop) {
		state->pc = s->u._subsh.end;
		dec_tindent();
		taddnl(0);
		taddstr("} always {");
		tindent++;
		taddnl(0);
		s->pop = 1;
	    } else {
		dec_tindent();
		taddnl(0);
		taddstr("}");
		stack = 1;
	    }
	    break;
	case WC_END:
	    stack = 1;
	    break;
	default:
	    DPUTS(1, "unknown word code in gettext2()");
	    return;
	}
    }
    tdopending();
}
Example #6
0
File: loop.c Project: 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;
}
Example #7
0
File: loop.c Project: 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;
}
Example #8
0
File: loop.c Project: 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;
}
Example #9
0
File: cond.c Project: 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;
    }
}