Exemple #1
0
Fichier : loop.c Projet : Lujaw/zsh
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;

    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. */
    endval = lastval;

    freeheap();

    cmdpop();
    cmdpush(CS_ALWAYS);

    /* The always clause. */
    save_try_errflag = try_errflag;
    try_errflag = (zlong)errflag;
    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);

    errflag = try_errflag ? 1 : 0;
    try_errflag = save_try_errflag;
    if (!retflag)
	retflag = save_retflag;
    if (!breaks)
	breaks = save_breaks;
    if (!contflag)
	contflag = save_contflag;

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

    return endval;
}
Exemple #2
0
int
execif(Estate state, int do_exec)
{
    Wordcode end, next;
    wordcode code = state->pc[-1];
    int olderrexit, s = 0, run = 0;

    olderrexit = noerrexit;
    end = state->pc + WC_IF_SKIP(code);

    noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN;
    while (state->pc < end) {
	code = *state->pc++;
	if (wc_code(code) != WC_IF ||
	    (run = (WC_IF_TYPE(code) == WC_IF_ELSE))) {
	    if (run)
		run = 2;
	    break;
	}
	next = state->pc + WC_IF_SKIP(code);
	cmdpush(s ? CS_ELIF : CS_IF);
	execlist(state, 1, 0);
	cmdpop();
	if (!lastval) {
	    run = 1;
	    break;
	}
	if (retflag)
	    break;
	s = 1;
	state->pc = next;
    }

    if (run) {
	/* we need to ignore lastval until we reach execcmd() */
	if (olderrexit)
	    noerrexit = olderrexit;
	else if (lastval)
	    noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN | NOERREXIT_UNTIL_EXEC;
	else
	    noerrexit &= ~ (NOERREXIT_EXIT | NOERREXIT_RETURN);
	cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
	execlist(state, 1, do_exec);
	cmdpop();
    } else {
	noerrexit = olderrexit;
	if (!retflag)
	    lastval = 0;
    }
    state->pc = end;
    this_noerrexit = 1;

    return lastval;
}
Exemple #3
0
int
execif(Estate state, int do_exec)
{
    Wordcode end, next;
    wordcode code = state->pc[-1];
    int olderrexit, s = 0, run = 0;

    olderrexit = noerrexit;
    end = state->pc + WC_IF_SKIP(code);

    if (!noerrexit)
	noerrexit = 1;
    while (state->pc < end) {
	code = *state->pc++;
	if (wc_code(code) != WC_IF ||
	    (run = (WC_IF_TYPE(code) == WC_IF_ELSE))) {
	    if (run)
		run = 2;
	    break;
	}
	next = state->pc + WC_IF_SKIP(code);
	cmdpush(s ? CS_ELIF : CS_IF);
	execlist(state, 1, 0);
	cmdpop();
	if (!lastval) {
	    run = 1;
	    break;
	}
	if (retflag)
	    break;
	s = 1;
	state->pc = next;
    }

    if (run) {
	/* we need to ignore lastval until we reach execcmd() */
	noerrexit = olderrexit ? olderrexit : lastval ? 2 : 0;
	cmdpush(run == 2 ? CS_ELSE : (s ? CS_ELIFTHEN : CS_IFTHEN));
	execlist(state, 1, do_exec);
	cmdpop();
    } else {
	noerrexit = olderrexit;
	lastval = 0;
    }
    state->pc = end;

    return lastval;
}
Exemple #4
0
static int
cmd_or_math(int cs_type)
{
    int oldlen = len;
    int c;

    cmdpush(cs_type);
    c = dquote_parse(')', 0);
    cmdpop();
    *bptr = '\0';
    if (!c) {
	c = hgetc();
	if (c == ')')
	    return 1;
	hungetc(c);
	lexstop = 0;
	c = ')';
    }
    hungetc(c);
    lexstop = 0;
    while (len > oldlen) {
	len--;
	hungetc(itok(*--bptr) ? ztokens[*bptr - Pound] : *bptr);
    }
    hungetc('(');
    return 0;
}
Exemple #5
0
void
yylex(void)
{
    if (tok == LEXERR)
	return;
    do
	tok = gettok();
    while (tok != ENDINPUT && exalias());
    if (tok == NEWLIN || tok == ENDINPUT) {
	while (hdocs) {
	    struct heredocs *next = hdocs->next;
	    char *name;

	    hwbegin(0);
	    cmdpush(hdocs->type == REDIR_HEREDOC ? CS_HEREDOC : CS_HEREDOCD);
	    STOPHIST
	    name = gethere(hdocs->str, hdocs->type);
	    ALLOWHIST
	    cmdpop();
	    hwend();
	    setheredoc(hdocs->pc, REDIR_HERESTR, name);
	    zfree(hdocs, sizeof(struct heredocs));
	    hdocs = next;
	}
    }
    if (tok != NEWLIN)
	isnewlin = 0;
    else
	isnewlin = (inbufct) ? -1 : 1;
    if (tok == SEMI || tok == NEWLIN)
	tok = SEPER;
}
Exemple #6
0
static int
cmd_or_math(int cs_type)
{
    int oldlen = len;
    int c;

    cmdpush(cs_type);
    c = dquote_parse(')', 0);
    cmdpop();
    *bptr = '\0';
    if (!c) {
	/* Successfully parsed, see if it was math */
	c = hgetc();
	if (c == ')')
	    return 1; /* yes */
	hungetc(c);
	lexstop = 0;
	c = ')';
    } else if (lexstop) {
	/* we haven't got anything to unget */
	return 2;
    }
    /* else unsuccessful: unget the whole thing */
    hungetc(c);
    lexstop = 0;
    while (len > oldlen) {
	len--;
	hungetc(itok(*--bptr) ? ztokens[*bptr - Pound] : *bptr);
    }
    hungetc('(');
    return 0;
}
Exemple #7
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;
}
Exemple #8
0
Fichier : lex.c Projet : AMDmi3/zsh
void
zshlex(void)
{
    if (tok == LEXERR)
	return;
    do {
	if (inrepeat_)
	    ++inrepeat_;
	if (inrepeat_ == 3 && isset(SHORTLOOPS))
	    incmdpos = 1;
	tok = gettok();
    } while (tok != ENDINPUT && exalias());
    nocorrect &= 1;
    if (tok == NEWLIN || tok == ENDINPUT) {
	while (hdocs) {
	    struct heredocs *next = hdocs->next;
	    char *doc, *munged_term;

	    hwbegin(0);
	    cmdpush(hdocs->type == REDIR_HEREDOC ? CS_HEREDOC : CS_HEREDOCD);
	    munged_term = dupstring(hdocs->str);
	    STOPHIST
	    doc = gethere(&munged_term, hdocs->type);
	    ALLOWHIST
	    cmdpop();
	    hwend();
	    if (!doc) {
		zerr("here document too large");
		while (hdocs) {
		    next = hdocs->next;
		    zfree(hdocs, sizeof(struct heredocs));
		    hdocs = next;
		}
		tok = LEXERR;
		break;
	    }
	    setheredoc(hdocs->pc, REDIR_HERESTR, doc, hdocs->str,
		       munged_term);
	    zfree(hdocs, sizeof(struct heredocs));
	    hdocs = next;
	}
    }
    if (tok != NEWLIN)
	isnewlin = 0;
    else
	isnewlin = (inbufct) ? -1 : 1;
    if (tok == SEMI || (tok == NEWLIN && !(lexflags & LEXFLAGS_NEWLINE)))
	tok = SEPER;
}
Exemple #9
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;
}
Exemple #10
0
Fichier : lex.c Projet : AMDmi3/zsh
static int
cmd_or_math(int cs_type)
{
    int oldlen = lexbuf.len;
    int c;
    int oinflags = inbufflags;

    cmdpush(cs_type);
    inbufflags |= INP_APPEND;
    c = dquote_parse(')', 0);
    if (!(oinflags & INP_APPEND))
	inbufflags &= ~INP_APPEND;
    cmdpop();
    *lexbuf.ptr = '\0';
    if (!c) {
	/* Successfully parsed, see if it was math */
	c = hgetc();
	if (c == ')')
	    return CMD_OR_MATH_MATH; /* yes */
	hungetc(c);
	lexstop = 0;
	c = ')';
    } else if (lexstop) {
	/* we haven't got anything to unget */
	return CMD_OR_MATH_ERR;
    }
    /* else unsuccessful: unget the whole thing */
    hungetc(c);
    lexstop = 0;
    while (lexbuf.len > oldlen && !(errflag & ERRFLAG_ERROR)) {
	lexbuf.len--;
	hungetc(itok(*--lexbuf.ptr) ?
		ztokens[*lexbuf.ptr - Pound] : *lexbuf.ptr);
    }
    if (errflag)
	return CMD_OR_MATH_ERR;
    hungetc('(');
    return errflag ? CMD_OR_MATH_ERR : CMD_OR_MATH_CMD;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
Fichier : lex.c Projet : AMDmi3/zsh
static enum lextok
gettokstr(int c, int sub)
{
    int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0;
    int intpos = 1, in_brace_param = 0;
    int inquote, unmatched = 0;
    enum lextok peek;
#ifdef DEBUG
    int ocmdsp = cmdsp;
#endif

    peek = STRING;
    if (!sub) {
	lexbuf.len = 0;
	lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE);
    }
    for (;;) {
	int act;
	int e;
	int inbl = inblank(c);
	
	if (fdpar && !inbl && c != ')')
	    fdpar = 0;

	if (inbl && !in_brace_param && !pct)
	    act = LX2_BREAK;
	else {
	    act = lexact2[STOUC(c)];
	    c = lextok2[STOUC(c)];
	}
	switch (act) {
	case LX2_BREAK:
	    if (!in_brace_param && !sub)
		goto brk;
	    break;
	case LX2_META:
	    c = hgetc();
#ifdef DEBUG
	    if (lexstop) {
		fputs("BUG: input terminated by Meta\n", stderr);
		fflush(stderr);
		goto brk;
	    }
#endif
	    add(Meta);
	    break;
	case LX2_OUTPAR:
	    if (fdpar) {
		/* this is a single word `(   )', treat as INOUTPAR */
		add(c);
		*lexbuf.ptr = '\0';
		return INOUTPAR;
	    }
	    if ((sub || in_brace_param) && isset(SHGLOB))
		break;
	    if (!in_brace_param && !pct--) {
		if (sub) {
		    pct = 0;
		    break;
		} else
		    goto brk;
	    }
	    c = Outpar;
	    break;
	case LX2_BAR:
	    if (!pct && !in_brace_param) {
		if (sub)
		    break;
		else
		    goto brk;
	    }
	    if (unset(SHGLOB) || (!sub && !in_brace_param))
		c = Bar;
	    break;
	case LX2_STRING:
	    e = hgetc();
	    if (e == '[') {
		cmdpush(CS_MATHSUBST);
		add(String);
		add(Inbrack);
		c = dquote_parse(']', sub);
		cmdpop();
		if (c) {
		    peek = LEXERR;
		    goto brk;
		}
		c = Outbrack;
	    } else if (e == '(') {
		add(String);
		switch (cmd_or_math_sub()) {
		case CMD_OR_MATH_CMD:
		    c = Outpar;
		    break;

		case CMD_OR_MATH_MATH:
		    c = Outparmath;
		    break;

		default:
		    peek = LEXERR;
		    goto brk;
		}
	    } else {
		if (e == '{') {
		    add(c);
		    c = Inbrace;
		    ++bct;
		    cmdpush(CS_BRACEPAR);
		    if (!in_brace_param) {
			if ((in_brace_param = bct))
			    seen_brct = 0;
		    }
		} else {
		    hungetc(e);
		    lexstop = 0;
		}
	    }
	    break;
	case LX2_INBRACK:
	    if (!in_brace_param) {
		brct++;
		seen_brct = 1;
	    }
	    c = Inbrack;
	    break;
	case LX2_OUTBRACK:
	    if (!in_brace_param)
		brct--;
	    if (brct < 0)
		brct = 0;
	    c = Outbrack;
	    break;
	case LX2_INPAR:
	    if (isset(SHGLOB)) {
		if (sub || in_brace_param)
		    break;
		if (incasepat && !lexbuf.len)
		    return INPAR;
		if (!isset(KSHGLOB) && lexbuf.len)
		    goto brk;
	    }
	    if (!in_brace_param) {
		if (!sub) {
		    e = hgetc();
		    hungetc(e);
		    lexstop = 0;
		    /* For command words, parentheses are only
		     * special at the start.  But now we're tokenising
		     * the remaining string.  So I don't see what
		     * the old incmdpos test here is for.
		     *   pws 1999/6/8
		     *
		     * Oh, no.
		     *  func1(   )
		     * is a valid function definition in [k]sh.  The best
		     * thing we can do, without really nasty lookahead tricks,
		     * is break if we find a blank after a parenthesis.  At
		     * least this can't happen inside braces or brackets.  We
		     * only allow this with SHGLOB (set for both sh and ksh).
		     *
		     * Things like `print @( |foo)' should still
		     * work, because [k]sh don't allow multiple words
		     * in a function definition, so we only do this
		     * in command position.
		     *   pws 1999/6/14
		     */
		    if (e == ')' || (isset(SHGLOB) && inblank(e) && !bct &&
				     !brct && !intpos && incmdpos)) {
			/*
			 * Either a () token, or a command word with
			 * something suspiciously like a ksh function
			 * definition.
			 * The current word isn't spellcheckable.
			 */
			nocorrect |= 2;
			goto brk;
		    }
		}
		/*
		 * This also handles the [k]sh `foo( )' function definition.
		 * Maintain a variable fdpar, set as long as a single set of
		 * parentheses contains only space.  Then if we get to the
		 * closing parenthesis and it is still set, we can assume we
		 * have a function definition.  Only do this at the start of
		 * the word, since the (...) must be a separate token.
		 */
		if (!pct++ && isset(SHGLOB) && intpos && !bct && !brct)
		    fdpar = 1;
	    }
	    c = Inpar;
	    break;
	case LX2_INBRACE:
	    if (isset(IGNOREBRACES) || sub)
		c = '{';
	    else {
		if (!lexbuf.len && incmdpos) {
		    add('{');
		    *lexbuf.ptr = '\0';
		    return STRING;
		}
		if (in_brace_param) {
		    cmdpush(CS_BRACE);
		}
		bct++;
	    }
	    break;
	case LX2_OUTBRACE:
	    if ((isset(IGNOREBRACES) || sub) && !in_brace_param)
		break;
	    if (!bct)
		break;
	    if (in_brace_param) {
		cmdpop();
	    }
	    if (bct-- == in_brace_param)
		in_brace_param = 0;
	    c = Outbrace;
	    break;
	case LX2_COMMA:
	    if (unset(IGNOREBRACES) && !sub && bct > in_brace_param)
		c = Comma;
	    break;
	case LX2_OUTANG:
	    if (in_brace_param || sub)
		break;
	    e = hgetc();
	    if (e != '(') {
		hungetc(e);
		lexstop = 0;
		goto brk;
	    }
	    add(OutangProc);
	    if (skipcomm()) {
		peek = LEXERR;
		goto brk;
	    }
	    c = Outpar;
	    break;
	case LX2_INANG:
	    if (isset(SHGLOB) && sub)
		break;
	    e = hgetc();
	    if (!(in_brace_param || sub) && e == '(') {
		add(Inang);
		if (skipcomm()) {
		    peek = LEXERR;
		    goto brk;
		}
		c = Outpar;
		break;
	    }
	    hungetc(e);
	    if(isnumglob()) {
		add(Inang);
		while ((c = hgetc()) != '>')
		    add(c);
		c = Outang;
		break;
	    }
	    lexstop = 0;
	    if (in_brace_param || sub)
		break;
	    goto brk;
	case LX2_EQUALS:
	    if (!sub) {
		if (intpos) {
		    e = hgetc();
		    if (e != '(') {
			hungetc(e);
			lexstop = 0;
			c = Equals;
		    } else {
			add(Equals);
			if (skipcomm()) {
			    peek = LEXERR;
			    goto brk;
			}
			c = Outpar;
		    }
		} else if (peek != ENVSTRING &&
			   (incmdpos || intypeset) && !bct && !brct) {
		    char *t = tokstr;
		    if (idigit(*t))
			while (++t < lexbuf.ptr && idigit(*t));
		    else {
			int sav = *lexbuf.ptr;
			*lexbuf.ptr = '\0';
			t = itype_end(t, IIDENT, 0);
			if (t < lexbuf.ptr) {
			    skipparens(Inbrack, Outbrack, &t);
			} else {
			    *lexbuf.ptr = sav;
			}
		    }
		    if (*t == '+')
			t++;
		    if (t == lexbuf.ptr) {
			e = hgetc();
			if (e == '(') {
			    *lexbuf.ptr = '\0';
			    return ENVARRAY;
			}
			hungetc(e);
			lexstop = 0;
			peek = ENVSTRING;
			intpos = 2;
		    } else
			c = Equals;
		} else
		    c = Equals;
	    }
	    break;
	case LX2_BKSLASH:
	    c = hgetc();
	    if (c == '\n') {
		c = hgetc();
		if (!lexstop)
		    continue;
	    } else {
		add(Bnull);
		if (c == STOUC(Meta)) {
		    c = hgetc();
#ifdef DEBUG
		    if (lexstop) {
			fputs("BUG: input terminated by Meta\n", stderr);
			fflush(stderr);
			goto brk;
		    }
#endif
		    add(Meta);
		}
	    }
	    if (lexstop)
		goto brk;
	    break;
	case LX2_QUOTE: {
	    int strquote = (lexbuf.len && lexbuf.ptr[-1] == String);

	    add(Snull);
	    cmdpush(CS_QUOTE);
	    for (;;) {
		STOPHIST
		while ((c = hgetc()) != '\'' && !lexstop) {
		    if (strquote && c == '\\') {
			c = hgetc();
			if (lexstop)
			    break;
			/*
			 * Mostly we don't need to do anything special
			 * with escape backslashes or closing quotes
			 * inside $'...'; however in completion we
			 * need to be able to strip multiple backslashes
			 * neatly.
			 */
			if (c == '\\' || c == '\'')
			    add(Bnull);
			else
			    add('\\');
		    } else if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') {
			if (lexbuf.ptr[-1] == '\\')
			    lexbuf.ptr--, lexbuf.len--;
			else
			    break;
		    }
		    add(c);
		}
		ALLOWHIST
		if (c != '\'') {
		    unmatched = '\'';
		    peek = LEXERR;
		    cmdpop();
		    goto brk;
		}
		e = hgetc();
		if (e != '\'' || unset(RCQUOTES) || strquote)
		    break;
		add(c);
	    }
	    cmdpop();
	    hungetc(e);
	    lexstop = 0;
	    c = Snull;
	    break;
	}
	case LX2_DQUOTE:
	    add(Dnull);
	    cmdpush(CS_DQUOTE);
	    c = dquote_parse('"', sub);
	    cmdpop();
	    if (c) {
		unmatched = '"';
		peek = LEXERR;
		goto brk;
	    }
	    c = Dnull;
	    break;
	case LX2_BQUOTE:
	    add(Tick);
	    cmdpush(CS_BQUOTE);
	    SETPARBEGIN
	    inquote = 0;
	    while ((c = hgetc()) != '`' && !lexstop) {
		if (c == '\\') {
		    c = hgetc();
		    if (c != '\n') {
			add(c == '`' || c == '\\' || c == '$' ? Bnull : '\\');
			add(c);
		    }
		    else if (!sub && isset(CSHJUNKIEQUOTES))
			add(c);
		} else {
		    if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') {
			break;
		    }
		    add(c);
		    if (c == '\'') {
			if ((inquote = !inquote))
			    STOPHIST
			else
			    ALLOWHIST
		    }
		}
	    }
	    if (inquote)
		ALLOWHIST
	    cmdpop();
	    if (c != '`') {
		unmatched = '`';
		peek = LEXERR;
		goto brk;
	    }
	    c = Tick;
	    SETPAREND
	    break;
	case LX2_DASH:
	    /*
	     * - shouldn't be treated as a special character unless
	     * we're in a pattern.  Howeve,simply  counting "[" doesn't
	     * work as []a-z] is a valid expression and we don't know
	     * down here what this "[" is for as $foo[stuff] is valid
	     * in zsh.  So just detect an opening [, which is enough
	     * to turn this into a pattern; the Dash will be harmlessly
	     * untokenised if not wanted.
	     */
	    if (seen_brct)
		c = Dash;
           else
               c = '-';
           break;
       case LX2_BANG:
           /*
            * Same logic as Dash, for ! to perform negation in range.
            */
           if (seen_brct)
               c = Bang;
           else
               c = '!';
       }
       add(c);
       c = hgetc();
	if (intpos)
	    intpos--;
	if (lexstop)
	    break;
    }
  brk:
    if (errflag) {
	if (in_brace_param) {
	    while(bct-- >= in_brace_param)
		cmdpop();
	}
	return LEXERR;
    }
    hungetc(c);
    if (unmatched)
	zerr("unmatched %c", unmatched);
    if (in_brace_param) {
	while(bct-- >= in_brace_param)
	    cmdpop();
	zerr("closing brace expected");
    } else if (unset(IGNOREBRACES) && !sub && lexbuf.len > 1 &&
	       peek == STRING && lexbuf.ptr[-1] == '}' &&
	       lexbuf.ptr[-2] != Bnull) {
	/* hack to get {foo} command syntax work */
	lexbuf.ptr--;
	lexbuf.len--;
	lexstop = 0;
	hungetc('}');
    }
    *lexbuf.ptr = '\0';
    DPUTS(cmdsp != ocmdsp, "BUG: gettok: cmdstack changed.");
    return peek;
}
Exemple #14
0
Fichier : lex.c Projet : AMDmi3/zsh
static enum lextok
gettok(void)
{
    int c, d;
    int peekfd = -1;
    enum lextok peek;

  beginning:
    tokstr = NULL;
    while (iblank(c = hgetc()) && !lexstop);
    toklineno = lineno;
    if (lexstop)
	return (errflag) ? LEXERR : ENDINPUT;
    isfirstln = 0;
    if ((lexflags & LEXFLAGS_ZLE))
	wordbeg = inbufct - (qbang && c == bangchar);
    hwbegin(-1-(qbang && c == bangchar));
    /* word includes the last character read and possibly \ before ! */
    if (dbparens) {
	lexbuf.len = 0;
	lexbuf.ptr = tokstr = (char *) hcalloc(lexbuf.siz = LEX_HEAP_SIZE);
	hungetc(c);
	cmdpush(CS_MATH);
	c = dquote_parse(infor ? ';' : ')', 0);
	cmdpop();
	*lexbuf.ptr = '\0';
	if (!c && infor) {
	    infor--;
	    return DINPAR;
	}
	if (c || (c = hgetc()) != ')') {
	    hungetc(c);
	    return LEXERR;
	}
	dbparens = 0;
	return DOUTPAR;
    } else if (idigit(c)) {	/* handle 1< foo */
	d = hgetc();
	if(d == '&') {
	    d = hgetc();
	    if(d == '>') {
		peekfd = c - '0';
		hungetc('>');
		c = '&';
	    } else {
		hungetc(d);
		lexstop = 0;
		hungetc('&');
	    }
	} else if (d == '>' || d == '<') {
	    peekfd = c - '0';
	    c = d;
	} else {
	    hungetc(d);
	    lexstop = 0;
	}
    }

    /* chars in initial position in word */

    /*
     * Handle comments.  There are some special cases when this
     * is not normal command input: lexflags implies we are examining
     * a line lexically without it being used for normal command input.
     */
    if (c == hashchar && !nocomments &&
	(isset(INTERACTIVECOMMENTS) ||
	 ((!lexflags || (lexflags & LEXFLAGS_COMMENTS)) && !expanding &&
	  (!interact || unset(SHINSTDIN) || strin)))) {
	/* History is handled here to prevent extra  *
	 * newlines being inserted into the history. */

	if (lexflags & LEXFLAGS_COMMENTS_KEEP) {
	    lexbuf.len = 0;
	    lexbuf.ptr = tokstr =
		(char *)hcalloc(lexbuf.siz = LEX_HEAP_SIZE);
	    add(c);
	}
	hwend();
	while ((c = ingetc()) != '\n' && !lexstop) {
	    hwaddc(c);
	    addtoline(c);
	    if (lexflags & LEXFLAGS_COMMENTS_KEEP)
		add(c);
	}

	if (errflag)
	    peek = LEXERR;
	else {
	    if (lexflags & LEXFLAGS_COMMENTS_KEEP) {
		*lexbuf.ptr = '\0';
		if (!lexstop)
		    hungetc(c);
		peek = STRING;
	    } else {
		hwend();
		hwbegin(0);
		hwaddc('\n');
		addtoline('\n');
		/*
		 * If splitting a line and removing comments,
		 * we don't want a newline token since it's
		 * treated specially.
		 */
		if ((lexflags & LEXFLAGS_COMMENTS_STRIP) && lexstop)
		    peek = ENDINPUT;
		else
		    peek = NEWLIN;
	    }
	}
	return peek;
    }
    switch (lexact1[STOUC(c)]) {
    case LX1_BKSLASH:
	d = hgetc();
	if (d == '\n')
	    goto beginning;
	hungetc(d);
	lexstop = 0;
	break;
    case LX1_NEWLIN:
	return NEWLIN;
    case LX1_SEMI:
	d = hgetc();
	if(d == ';')
	    return DSEMI;
	else if(d == '&')
	    return SEMIAMP;
	else if (d == '|')
	    return SEMIBAR;
	hungetc(d);
	lexstop = 0;
	return SEMI;
    case LX1_AMPER:
	d = hgetc();
	if (d == '&')
	    return DAMPER;
	else if (d == '!' || d == '|')
	    return AMPERBANG;
	else if (d == '>') {
	    tokfd = peekfd;
	    d = hgetc();
	    if (d == '!' || d == '|')
		return OUTANGAMPBANG;
	    else if (d == '>') {
		d = hgetc();
		if (d == '!' || d == '|')
		    return DOUTANGAMPBANG;
		hungetc(d);
		lexstop = 0;
		return DOUTANGAMP;
	    }
	    hungetc(d);
	    lexstop = 0;
	    return AMPOUTANG;
	}
	hungetc(d);
	lexstop = 0;
	return AMPER;
    case LX1_BAR:
	d = hgetc();
	if (d == '|')
	    return DBAR;
	else if (d == '&')
	    return BARAMP;
	hungetc(d);
	lexstop = 0;
	return BAR;
    case LX1_INPAR:
	d = hgetc();
	if (d == '(') {
	    if (infor) {
		dbparens = 1;
		return DINPAR;
	    }
	    if (incmdpos || (isset(SHGLOB) && !isset(KSHGLOB))) {
		lexbuf.len = 0;
		lexbuf.ptr = tokstr = (char *)
		    hcalloc(lexbuf.siz = LEX_HEAP_SIZE);
		switch (cmd_or_math(CS_MATH)) {
		case CMD_OR_MATH_MATH:
		    return DINPAR;

		case CMD_OR_MATH_CMD:
		    /*
		     * Not math, so we don't return the contents
		     * as a string in this case.
		     */
		    tokstr = NULL;
		    return INPAR;
		    
		case CMD_OR_MATH_ERR:
		    /*
		     * LEXFLAGS_ACTIVE means we came from bufferwords(),
		     * so we treat as an incomplete math expression
		     */
		    if (lexflags & LEXFLAGS_ACTIVE)
			tokstr = dyncat("((", tokstr ? tokstr : "");
		    /* fall through */

		default:
		    return LEXERR;
		}
	    }
	} else if (d == ')')
	    return INOUTPAR;
	hungetc(d);
	lexstop = 0;
	if (!(isset(SHGLOB) || incond == 1 || incmdpos))
	    break;
	return INPAR;
    case LX1_OUTPAR:
	return OUTPAR;
    case LX1_INANG:
	d = hgetc();
	if (d == '(') {
	    hungetc(d);
	    lexstop = 0;
	    unpeekfd:
	    if(peekfd != -1) {
		hungetc(c);
		c = '0' + peekfd;
	    }
	    break;
	}
	if (d == '>') {
	    peek = INOUTANG;
	} else if (d == '<') {
	    int e = hgetc();

	    if (e == '(') {
		hungetc(e);
		hungetc(d);
		peek = INANG;
	    } else if (e == '<')
		peek = TRINANG;
	    else if (e == '-')
		peek = DINANGDASH;
	    else {
		hungetc(e);
		lexstop = 0;
		peek = DINANG;
	    }
	} else if (d == '&') {
	    peek = INANGAMP;
	} else {
	    hungetc(d);
	    if(isnumglob())
		goto unpeekfd;
	    peek = INANG;
	}
	tokfd = peekfd;
	return peek;
    case LX1_OUTANG:
	d = hgetc();
	if (d == '(') {
	    hungetc(d);
	    goto unpeekfd;
	} else if (d == '&') {
	    d = hgetc();
	    if (d == '!' || d == '|')
		peek = OUTANGAMPBANG;
	    else {
		hungetc(d);
		lexstop = 0;
		peek = OUTANGAMP;
	    }
	} else if (d == '!' || d == '|')
	    peek = OUTANGBANG;
	else if (d == '>') {
	    d = hgetc();
	    if (d == '&') {
		d = hgetc();
		if (d == '!' || d == '|')
		    peek = DOUTANGAMPBANG;
		else {
		    hungetc(d);
		    lexstop = 0;
		    peek = DOUTANGAMP;
		}
	    } else if (d == '!' || d == '|')
		peek = DOUTANGBANG;
	    else if (d == '(') {
		hungetc(d);
		hungetc('>');
		peek = OUTANG;
	    } else {
		hungetc(d);
		lexstop = 0;
		peek = DOUTANG;
		if (isset(HISTALLOWCLOBBER))
		    hwaddc('|');
	    }
	} else {
	    hungetc(d);
	    lexstop = 0;
	    peek = OUTANG;
	    if (!incond && isset(HISTALLOWCLOBBER))
		hwaddc('|');
	}
	tokfd = peekfd;
	return peek;
    }

    /* we've started a string, now get the *
     * rest of it, performing tokenization */
    return gettokstr(c, 0);
}
Exemple #15
0
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;
}
Exemple #16
0
int
gettok(void)
{
    int c, d;
    int peekfd = -1, peek;

  beginning:
    tokstr = NULL;
    while (iblank(c = hgetc()) && !lexstop);
    if (lexstop)
	return (errflag) ? LEXERR : ENDINPUT;
    isfirstln = 0;
    wordbeg = inbufct - (qbang && c == bangchar);
    hwbegin(-1-(qbang && c == bangchar));
    /* word includes the last character read and possibly \ before ! */
    if (dbparens) {
	len = 0;
	bptr = tokstr = (char *) hcalloc(bsiz = 32);
	hungetc(c);
	cmdpush(CS_MATH);
	c = dquote_parse(infor ? ';' : ')', 0);
	cmdpop();
	*bptr = '\0';
	if (!c && infor) {
	    infor--;
	    return DINPAR;
	}
	if (c || (c = hgetc()) != ')') {
	    hungetc(c);
	    return LEXERR;
	}
	dbparens = 0;
	return DOUTPAR;
    } else if (idigit(c)) {	/* handle 1< foo */
	d = hgetc();
	if(d == '&') {
	    d = hgetc();
	    if(d == '>') {
		peekfd = c - '0';
		hungetc('>');
		c = '&';
	    } else {
		hungetc(d);
		lexstop = 0;
		hungetc('&');
	    }
	} else if (d == '>' || d == '<') {
	    peekfd = c - '0';
	    c = d;
	} else {
	    hungetc(d);
	    lexstop = 0;
	}
    }

    /* chars in initial position in word */

    if (c == hashchar && !nocomments &&
	(isset(INTERACTIVECOMMENTS) ||
	 (!zleparse && !expanding &&
	  (!interact || unset(SHINSTDIN) || strin)))) {
	/* History is handled here to prevent extra  *
	 * newlines being inserted into the history. */

	while ((c = ingetc()) != '\n' && !lexstop) {
	    hwaddc(c);
	    addtoline(c);
	}

	if (errflag)
	    peek = LEXERR;
	else {
	    hwend();
	    hwbegin(0);
	    hwaddc('\n');
	    addtoline('\n');
	    peek = NEWLIN;
	}
	return peek;
    }
    switch (lexact1[STOUC(c)]) {
    case LX1_BKSLASH:
	d = hgetc();
	if (d == '\n')
	    goto beginning;
	hungetc(d);
	lexstop = 0;
	break;
    case LX1_NEWLIN:
	return NEWLIN;
    case LX1_SEMI:
	d = hgetc();
	if(d == ';')
	    return DSEMI;
	else if(d == '&')
	    return SEMIAMP;
	hungetc(d);
	lexstop = 0;
	return SEMI;
    case LX1_AMPER:
	d = hgetc();
	if (d == '&')
	    return DAMPER;
	else if (d == '!' || d == '|')
	    return AMPERBANG;
	else if (d == '>') {
	    tokfd = peekfd;
	    d = hgetc();
	    if (d == '!' || d == '|')
		return OUTANGAMPBANG;
	    else if (d == '>') {
		d = hgetc();
		if (d == '!' || d == '|')
		    return DOUTANGAMPBANG;
		hungetc(d);
		lexstop = 0;
		return DOUTANGAMP;
	    }
	    hungetc(d);
	    lexstop = 0;
	    return AMPOUTANG;
	}
	hungetc(d);
	lexstop = 0;
	return AMPER;
    case LX1_BAR:
	d = hgetc();
	if (d == '|')
	    return DBAR;
	else if (d == '&')
	    return BARAMP;
	hungetc(d);
	lexstop = 0;
	return BAR;
    case LX1_INPAR:
	d = hgetc();
	if (d == '(') {
	    if (infor) {
		dbparens = 1;
		return DINPAR;
	    }
	    if (incmdpos) {
		len = 0;
		bptr = tokstr = (char *) hcalloc(bsiz = 32);
		return cmd_or_math(CS_MATH) ? DINPAR : INPAR;
	    }
	} else if (d == ')')
	    return INOUTPAR;
	hungetc(d);
	lexstop = 0;
	if (!(incond == 1 || incmdpos))
	    break;
	return INPAR;
    case LX1_OUTPAR:
	return OUTPAR;
    case LX1_INANG:
	d = hgetc();
	if (!incmdpos && d == '(') {
	    hungetc(d);
	    lexstop = 0;
	    unpeekfd:
	    if(peekfd != -1) {
		hungetc(c);
		c = '0' + peekfd;
	    }
	    break;
	}
	if (d == '>') {
	    peek = INOUTANG;
	} else if (d == '<') {
	    int e = hgetc();

	    if (e == '(') {
		hungetc(e);
		hungetc(d);
		peek = INANG;
	    } else if (e == '<')
		peek = TRINANG;
	    else if (e == '-')
		peek = DINANGDASH;
	    else {
		hungetc(e);
		lexstop = 0;
		peek = DINANG;
	    }
	} else if (d == '&') {
	    peek = INANGAMP;
	} else {
	    hungetc(d);
	    if(isnumglob())
		goto unpeekfd;
	    peek = INANG;
	}
	tokfd = peekfd;
	return peek;
    case LX1_OUTANG:
	d = hgetc();
	if (d == '(') {
	    hungetc(d);
	    goto unpeekfd;
	} else if (d == '&') {
	    d = hgetc();
	    if (d == '!' || d == '|')
		peek = OUTANGAMPBANG;
	    else {
		hungetc(d);
		lexstop = 0;
		peek = OUTANGAMP;
	    }
	} else if (d == '!' || d == '|')
	    peek = OUTANGBANG;
	else if (d == '>') {
	    d = hgetc();
	    if (d == '&') {
		d = hgetc();
		if (d == '!' || d == '|')
		    peek = DOUTANGAMPBANG;
		else {
		    hungetc(d);
		    lexstop = 0;
		    peek = DOUTANGAMP;
		}
	    } else if (d == '!' || d == '|')
		peek = DOUTANGBANG;
	    else if (d == '(') {
		hungetc(d);
		hungetc('>');
		peek = OUTANG;
	    } else {
		hungetc(d);
		lexstop = 0;
		peek = DOUTANG;
		if (isset(HISTALLOWCLOBBER))
		    hwaddc('|');
	    }
	} else {
	    hungetc(d);
	    lexstop = 0;
	    peek = OUTANG;
	    if (!incond && isset(HISTALLOWCLOBBER))
		hwaddc('|');
	}
	tokfd = peekfd;
	return peek;
    }

    /* we've started a string, now get the *
     * rest of it, performing tokenization */
    return gettokstr(c, 0);
}
Exemple #17
0
static int
skipcomm(void)
{
    int pct = 1, c;

    cmdpush(CS_CMDSUBST);
    SETPARBEGIN
    c = Inpar;
    do {
	add(c);
	c = hgetc();
	if (itok(c) || lexstop)
	    break;
	switch (c) {
	case '(':
	    pct++;
	    break;
	case ')':
	    pct--;
	    break;
	case '\\':
	    add(c);
	    c = hgetc();
	    break;
	case '\'': {
	    int strquote = bptr[-1] == '$';
	    add(c);
	    STOPHIST
	    while ((c = hgetc()) != '\'' && !lexstop) {
		if (c == '\\' && strquote) {
		    add(c);
		    c = hgetc();
		}
		add(c);
	    }
	    ALLOWHIST
	    break;
	}
	case '\"':
	    add(c);
	    while ((c = hgetc()) != '\"' && !lexstop)
		if (c == '\\') {
		    add(c);
		    add(hgetc());
		} else
		    add(c);
	    break;
	case '`':
	    add(c);
	    while ((c = hgetc()) != '`' && !lexstop)
		if (c == '\\')
		    add(c), add(hgetc());
		else
		    add(c);
	    break;
	}
    }
    while (pct);
    if (!lexstop)
	SETPAREND
    cmdpop();
    return lexstop;
}
Exemple #18
0
static int
dquote_parse(char endchar, int sub)
{
    int pct = 0, brct = 0, bct = 0, intick = 0, err = 0;
    int c;
    int math = endchar == ')' || endchar == ']';
    int zlemath = math && cs > ll + addedx - inbufct;

    while (((c = hgetc()) != endchar || bct ||
	    (math && ((pct > 0) || (brct > 0))) ||
	    intick) && !lexstop) {
      cont:
	switch (c) {
	case '\\':
	    c = hgetc();
	    if (c != '\n') {
		if (c == '$' || c == '\\' || (c == '}' && !intick && bct) ||
		    c == endchar || c == '`' ||
		    (endchar == ']' && (c == '[' || c == ']' ||
					c == '(' || c == ')' ||
					c == '{' || c == '}' ||
					(c == '"' && sub))))
		    add(Bnull);
		else {
		    /* lexstop is implicitly handled here */
		    add('\\');
		    goto cont;
		}
	    } else if (sub || unset(CSHJUNKIEQUOTES) || endchar != '"')
		continue;
	    break;
	case '\n':
	    err = !sub && isset(CSHJUNKIEQUOTES) && endchar == '"';
	    break;
	case '$':
	    if (intick)
		break;
	    c = hgetc();
	    if (c == '(') {
		add(Qstring);
		err = cmd_or_math_sub();
		c = Outpar;
	    } else if (c == '[') {
		add(String);
		add(Inbrack);
		cmdpush(CS_MATHSUBST);
		err = dquote_parse(']', sub);
		cmdpop();
		c = Outbrack;
	    } else if (c == '{') {
		add(Qstring);
		c = Inbrace;
		cmdpush(CS_BRACEPAR);
		bct++;
	    } else if (c == '$')
		add(Qstring);
	    else {
		hungetc(c);
		lexstop = 0;
		c = Qstring;
	    }
	    break;
	case '}':
	    if (intick || !bct)
		break;
	    c = Outbrace;
	    bct--;
	    cmdpop();
	    break;
	case '`':
	    c = Qtick;
	    if (intick == 2)
		ALLOWHIST
	    if ((intick = !intick)) {
		SETPARBEGIN
		cmdpush(CS_BQUOTE);
	    } else {
		SETPAREND
	        cmdpop();
	    }
	    break;
	case '\'':
	    if (!intick)
		break;
	    if (intick == 1)
		intick = 2, STOPHIST
	    else
		intick = 1, ALLOWHIST
	    break;
	case '(':
	    if (!math || !bct)
		pct++;
	    break;
	case ')':
	    if (!math || !bct)
		err = (!pct-- && math);
	    break;
	case '[':
	    if (!math || !bct)
		brct++;
	    break;
	case ']':
	    if (!math || !bct)
		err = (!brct-- && math);
	    break;
	case '"':
	    if (intick || ((endchar == ']' || !endchar) && !bct))
		break;
	    if (bct) {
		add(Dnull);
		cmdpush(CS_DQUOTE);
		err = dquote_parse('"', sub);
		cmdpop();
		c = Dnull;
	    } else
		err = 1;
	    break;
	}
	if (err || lexstop)
	    break;
	add(c);
    }
    if (intick == 2)
	ALLOWHIST
    if (intick) {
	cmdpop();
    }
    while (bct--)
	cmdpop();
    if (lexstop)
	err = intick || endchar || err;
    else if (err == 1)
	err = c;
    if (zlemath && cs <= ll + 1 - inbufct)
	inwhat = IN_MATH;
    return err;
}
Exemple #19
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;
    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;
}
Exemple #20
0
static int
gettokstr(int c, int sub)
{
    int bct = 0, pct = 0, brct = 0, fdpar = 0;
    int intpos = 1, in_brace_param = 0;
    int peek, inquote, unmatched = 0;
    char endchar='"';
#ifdef DEBUG
    int ocmdsp = cmdsp;
#endif

    peek = STRING;
    if (!sub) {
	len = 0;
	bptr = tokstr = (char *) hcalloc(bsiz = 32);
    }
    for (;;) {
	int act;
	int e;
	int inbl = inblank(c);
	
	if (fdpar && !inbl && c != ')')
	    fdpar = 0;

	if (inbl && !in_brace_param && !pct)
	    act = LX2_BREAK;
	else {
	    act = lexact2[STOUC(c)];
	    c = lextok2[STOUC(c)];
	}
	switch (act) {
	case LX2_BREAK:
	    if (!in_brace_param && !sub)
		goto brk;
	    break;
	case LX2_META:
	    c = hgetc();
#ifdef DEBUG
	    if (lexstop) {
		fputs("BUG: input terminated by Meta\n", stderr);
		fflush(stderr);
		goto brk;
	    }
#endif
	    add(Meta);
	    break;
	case LX2_OUTPAR:
	    if (fdpar) {
		/* this is a single word `(   )', treat as INOUTPAR */
		add(c);
		*bptr = '\0';
		return INOUTPAR;
	    }
	    if ((sub || in_brace_param) && isset(SHGLOB))
		break;
	    if (!in_brace_param && !pct--) {
		if (sub) {
		    pct = 0;
		    break;
		} else
		    goto brk;
	    }
	    c = Outpar;
	    break;
	case LX2_BAR:
	    if (!pct && !in_brace_param) {
		if (sub)
		    break;
		else
		    goto brk;
	    }
	    if (unset(SHGLOB) || (!sub && !in_brace_param))
		c = Bar;
	    break;
	case LX2_STRING:
	    e = hgetc();
	    if (e == '[') {
		cmdpush(CS_MATHSUBST);
		add(String);
		add(Inbrack);
		c = dquote_parse(']', sub);
		cmdpop();
		if (c) {
		    peek = LEXERR;
		    goto brk;
		}
		c = Outbrack;
	    } else if (e == '(') {
		add(String);
		c = cmd_or_math_sub();
		if (c) {
		    peek = LEXERR;
		    goto brk;
		}
		c = Outpar;
	    } else {
		if (e == '{') {
		    add(c);
		    c = Inbrace;
		    ++bct;
		    cmdpush(CS_BRACEPAR);
		    if (!in_brace_param)
			in_brace_param = bct;
		} else {
		    hungetc(e);
		    lexstop = 0;
		}
	    }
	    break;
	case LX2_INBRACK:
	    if (!in_brace_param)
		brct++;
	    c = Inbrack;
	    break;
	case LX2_OUTBRACK:
	    if (!in_brace_param)
		brct--;
	    if (brct < 0)
		brct = 0;
	    c = Outbrack;
	    break;
	case LX2_INPAR:
	    if (isset(SHGLOB)) {
		if (sub || in_brace_param)
		    break;
		if (incasepat && !len)
		    return INPAR;
	    }
	    if (!in_brace_param) {
		if (!sub) {
		    e = hgetc();
		    hungetc(e);
		    lexstop = 0;
		    /* For command words, parentheses are only
		     * special at the start.  But now we're tokenising
		     * the remaining string.  So I don't see what
		     * the old incmdpos test here is for.
		     *   pws 1999/6/8
		     *
		     * Oh, no.
		     *  func1(   )
		     * is a valid function definition in [k]sh.  The best
		     * thing we can do, without really nasty lookahead tricks,
		     * is break if we find a blank after a parenthesis.  At
		     * least this can't happen inside braces or brackets.  We
		     * only allow this with SHGLOB (set for both sh and ksh).
		     *
		     * Things like `print @( |foo)' should still
		     * work, because [k]sh don't allow multiple words
		     * in a function definition, so we only do this
		     * in command position.
		     *   pws 1999/6/14
		     */
		    if (e == ')' || (isset(SHGLOB) && inblank(e) && !bct &&
				     !brct && !intpos && incmdpos))
			goto brk;
		}
		/*
		 * This also handles the [k]sh `foo( )' function definition.
		 * Maintain a variable fdpar, set as long as a single set of
		 * parentheses contains only space.  Then if we get to the
		 * closing parenthesis and it is still set, we can assume we
		 * have a function definition.  Only do this at the start of
		 * the word, since the (...) must be a separate token.
		 */
		if (!pct++ && isset(SHGLOB) && intpos && !bct && !brct)
		    fdpar = 1;
	    }
	    c = Inpar;
	    break;
	case LX2_INBRACE:
	    if (isset(IGNOREBRACES) || sub)
		c = '{';
	    else {
		if (!len && incmdpos) {
		    add('{');
		    *bptr = '\0';
		    return STRING;
		}
		if (in_brace_param) {
		    cmdpush(CS_BRACE);
		}
		bct++;
	    }
	    break;
	case LX2_OUTBRACE:
	    if ((isset(IGNOREBRACES) || sub) && !in_brace_param)
		break;
	    if (!bct)
		break;
	    if (in_brace_param) {
		cmdpop();
	    }
	    if (bct-- == in_brace_param)
		in_brace_param = 0;
	    c = Outbrace;
	    break;
	case LX2_COMMA:
	    if (unset(IGNOREBRACES) && !sub && bct > in_brace_param)
		c = Comma;
	    break;
	case LX2_OUTANG:
	    if (!intpos) {
		if (in_brace_param || sub)
		    break;
		else
		    goto brk;
	    }
	    e = hgetc();
	    if (e != '(') {
		hungetc(e);
		lexstop = 0;
		goto brk;
	    }
	    add(Outang);
	    if (skipcomm()) {
		peek = LEXERR;
		goto brk;
	    }
	    c = Outpar;
	    break;
	case LX2_INANG:
	    if (isset(SHGLOB) && sub)
		break;
	    e = hgetc();
	    if(e == '(' && intpos) {
		add(Inang);
		if (skipcomm()) {
		    peek = LEXERR;
		    goto brk;
		}
		c = Outpar;
		break;
	    }
	    hungetc(e);
	    if(isnumglob()) {
		add(Inang);
		while ((c = hgetc()) != '>')
		    add(c);
		c = Outang;
		break;
	    }
	    lexstop = 0;
	    if (in_brace_param || sub)
		break;
	    goto brk;
	case LX2_EQUALS:
	    if (intpos) {
		e = hgetc();
		if (e != '(') {
		    hungetc(e);
		    lexstop = 0;
		    c = Equals;
		} else {
		    add(Equals);
		    if (skipcomm()) {
			peek = LEXERR;
			goto brk;
		    }
		    c = Outpar;
		}
	    } else if (!sub && peek != ENVSTRING &&
		       incmdpos && !bct && !brct) {
		char *t = tokstr;
		if (idigit(*t))
		    while (++t < bptr && idigit(*t));
		else {
		    while (iident(*t) && ++t < bptr);
		    if (t < bptr) {
			*bptr = '\0';
			skipparens(Inbrack, Outbrack, &t);
		    }
		}
		if (*t == '+')
                    t++;
		if (t == bptr) {
		    e = hgetc();
		    if (e == '(' && incmdpos) {
			*bptr = '\0';
			return ENVARRAY;
		    }
		    hungetc(e);
		    lexstop = 0;
		    peek = ENVSTRING;
		    intpos = 2;
		} else
		    c = Equals;
	    } else
		c = Equals;
	    break;
#ifndef __SYMBIAN32__	    
	case LX2_BKSLASH:
	    c = hgetc();
	    if (c == '\n') {
		c = hgetc();
		if (!lexstop)
		    continue;
	    } else
		add(Bnull);
	    if (lexstop)
		goto brk;
	    break;
#endif	    
	case LX2_QUOTE: {
	    int strquote = (len && bptr[-1] == String);

	    add(Snull);
	    cmdpush(CS_QUOTE);
	    for (;;) {
		STOPHIST
		while ((c = hgetc()) != '\'' && !lexstop) {
		    if (strquote && c == '\\') {
			add(c);
			c = hgetc();
			if (lexstop)
			    break;
		    } else if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') {
			if (bptr[-1] == '\\')
			    bptr--, len--;
			else
			    break;
		    }
		    add(c);
		}
		ALLOWHIST
		if (c != '\'') {
		    unmatched = '\'';
		    peek = LEXERR;
		    cmdpop();
		    goto brk;
		}
		e = hgetc();
		if (e != '\'' || unset(RCQUOTES) || strquote)
		    break;
		add(c);
	    }
	    cmdpop();
	    hungetc(e);
	    lexstop = 0;
	    c = Snull;
	    break;
	}
	case LX2_DQUOTE:
	    add(Dnull);
	    cmdpush(CS_DQUOTE);
	    c = dquote_parse('"', sub);
	    cmdpop();
	    if (c) {
		unmatched = '"';
		peek = LEXERR;
		goto brk;
	    }
	    c = Dnull;
	    break;
	case LX2_BQUOTE:
	    add(Tick);
	    cmdpush(CS_BQUOTE);
	    SETPARBEGIN
	    inquote = 0;
	    while ((c = hgetc()) != '`' && !lexstop) {
		if (c == '\\') {
		    c = hgetc();
		    if (c != '\n') {
			add(c == '`' || c == '\\' || c == '$' ? Bnull : '\\');
			add(c);
		    }
		    else if (!sub && isset(CSHJUNKIEQUOTES))
			add(c);
		} else {
		    if (!sub && isset(CSHJUNKIEQUOTES) && c == '\n') {
			break;
		    }
		    add(c);
		    if (c == '\'') {
			if ((inquote = !inquote))
			    STOPHIST
			else
			    ALLOWHIST
		    }
		}
	    }
	    if (inquote)
		ALLOWHIST
	    cmdpop();
	    if (c != '`') {
		unmatched = '`';
		peek = LEXERR;
		goto brk;
	    }
	    c = Tick;
	    SETPAREND
	    break;
	}
	#ifdef __SYMBIAN32__	
	if(c=='\\') 
		{
	    c = hgetc();
	    if (c != '\n') {
		if (c == endchar)
		    add(Bnull);
		else {
		    /* lexstop is implicitly handled here */
		    add('\\');
		    
		}
	    } 
	}
	#endif
	add(c);
	c = hgetc();
	if (intpos)
	    intpos--;
	if (lexstop)
	    break;
    }
  brk:
    hungetc(c);
    if (unmatched)
	zerr("unmatched %c", NULL, unmatched);
    if (in_brace_param) {
	while(bct-- >= in_brace_param)
	    cmdpop();
	zerr("closing brace expected", NULL, 0);
    } else if (unset(IGNOREBRACES) && !sub && len > 1 &&
	       peek == STRING && bptr[-1] == '}' && bptr[-2] != Bnull) {
	/* hack to get {foo} command syntax work */
	bptr--;
	len--;
	lexstop = 0;
	hungetc('}');
    }
    *bptr = '\0';
    DPUTS(cmdsp != ocmdsp, "BUG: gettok: cmdstack changed.");
    return peek;
}
Exemple #21
0
Fichier : lex.c Projet : AMDmi3/zsh
static int
skipcomm(void)
{
#ifdef ZSH_OLD_SKIPCOMM
    int pct = 1, c, start = 1;

    cmdpush(CS_CMDSUBST);
    SETPARBEGIN
    c = Inpar;
    do {
	int iswhite;
	add(c);
	c = hgetc();
	if (itok(c) || lexstop)
	    break;
	iswhite = inblank(c);
	switch (c) {
	case '(':
	    pct++;
	    break;
	case ')':
	    pct--;
	    break;
	case '\\':
	    add(c);
	    c = hgetc();
	    break;
	case '\'': {
	    int strquote = lexbuf.ptr[-1] == '$';
	    add(c);
	    STOPHIST
	    while ((c = hgetc()) != '\'' && !lexstop) {
		if (c == '\\' && strquote) {
		    add(c);
		    c = hgetc();
		}
		add(c);
	    }
	    ALLOWHIST
	    break;
	}
	case '\"':
	    add(c);
	    while ((c = hgetc()) != '\"' && !lexstop)
		if (c == '\\') {
		    add(c);
		    add(hgetc());
		} else
		    add(c);
	    break;
	case '`':
	    add(c);
	    while ((c = hgetc()) != '`' && !lexstop)
		if (c == '\\')
		    add(c), add(hgetc());
		else
		    add(c);
	    break;
	case '#':
	    if (start) {
		add(c);
		while ((c = hgetc()) != '\n' && !lexstop)
		    add(c);
		iswhite = 1;
	    }
	    break;
	}
	start = iswhite;
    }
    while (pct);
    if (!lexstop)
	SETPAREND
    cmdpop();
    return lexstop;
#else
    char *new_tokstr;
    int new_lexstop, new_lex_add_raw;
    int save_infor = infor;
    struct lexbufstate new_lexbuf;
    int noalias = noaliases;

    noaliases = 1;
    infor = 0;
    cmdpush(CS_CMDSUBST);
    SETPARBEGIN
    add(Inpar);

    new_lex_add_raw = lex_add_raw + 1;
    if (!lex_add_raw) {
	/*
	 * We'll combine the string so far with the input
	 * read in for the command substitution.  To do this
	 * we'll just propagate the current tokstr etc. as the
	 * variables used for adding raw input, and
	 * ensure we swap those for the real tokstr etc. at the end.
	 *
	 * However, we need to save and restore the rest of the
	 * lexical and parse state as we're effectively parsing
	 * an internal string.  Because we're still parsing it from
	 * the original input source (we have to --- we don't know
	 * when to stop inputting it otherwise and can't rely on
	 * the input being recoverable until we've read it) we need
	 * to keep the same history context.
	 */
	new_tokstr = tokstr;
	new_lexbuf = lexbuf;

	/*
	 * If we're expanding an alias at this point, we need the whole
	 * remaining text as part of the string for the command in
	 * parentheses, so don't backtrack.  This is different from the
	 * usual case where the alias is fully within the command, where
	 * we want the unexpanded text so that it will be expanded
	 * again when the command in the parentheses is executed.
	 *
	 * I never wanted to be a software engineer, you know.
	 */
	if (inbufflags & INP_ALIAS)
	    inbufflags |= INP_RAW_KEEP;
	zcontext_save_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE);
	hist_in_word(1);
    } else {
	/*
	 * Set up for nested command subsitution, however
	 * we don't actually need the string until we get
	 * back to the top level and recover the lot.
	 * The $() body just appears empty.
	 *
	 * We do need to propagate the raw variables which would
	 * otherwise by cleared, though.
	 */
	new_tokstr = tokstr_raw;
	new_lexbuf = lexbuf_raw;

	zcontext_save_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE);
    }
    tokstr_raw = new_tokstr;
    lexbuf_raw = new_lexbuf;
    lex_add_raw = new_lex_add_raw;
    /*
     * Don't do any ZLE specials down here: they're only needed
     * when we return the string from the recursive parse.
     * (TBD: this probably means we should be initialising lexflags
     * more consistently.)
     *
     * Note that in that case we're still using the ZLE line reading
     * function at the history layer --- this is consistent with the
     * intention of maintaining the history and input layers across
     * the recursive parsing.
     */
    lexflags &= ~LEXFLAGS_ZLE;
    dbparens = 0;	/* restored by zcontext_restore_partial() */

    if (!parse_event(OUTPAR) || tok != OUTPAR)
	lexstop = 1;
     /* Outpar lexical token gets added in caller if present */

    /*
     * We're going to keep the full raw input string
     * as the current token string after popping the stack.
     */
    new_tokstr = tokstr_raw;
    new_lexbuf = lexbuf_raw;
    /*
     * We're also going to propagate the lexical state:
     * if we couldn't parse the command substitution we
     * can't continue.
     */
    new_lexstop = lexstop;

    zcontext_restore_partial(ZCONTEXT_LEX|ZCONTEXT_PARSE);

    if (lex_add_raw) {
	/*
	 * Keep going, so retain the raw variables.
	 */
	tokstr_raw = new_tokstr;
	lexbuf_raw = new_lexbuf;
    } else {
	if (!new_lexstop) {
	    /* Ignore the ')' added on input */
	    new_lexbuf.len--;
	    *--new_lexbuf.ptr = '\0';
	}

	/*
	 * Convince the rest of lex.c we were examining a string
	 * all along.
	 */
	tokstr = new_tokstr;
	lexbuf = new_lexbuf;
	lexstop = new_lexstop;
	hist_in_word(0);
    }

    if (!lexstop)
	SETPAREND
    cmdpop();
    infor = save_infor;
    noaliases = noalias;

    return lexstop;
#endif
}
Exemple #22
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;
}
Exemple #23
0
Fichier : lex.c Projet : AMDmi3/zsh
static int
dquote_parse(char endchar, int sub)
{
    int pct = 0, brct = 0, bct = 0, intick = 0, err = 0;
    int c;
    int math = endchar == ')' || endchar == ']' || infor;
    int zlemath = math && zlemetacs > zlemetall + addedx - inbufct;

    while (((c = hgetc()) != endchar || bct ||
	    (math && ((pct > 0) || (brct > 0))) ||
	    intick) && !lexstop) {
      cont:
	switch (c) {
	case '\\':
	    c = hgetc();
	    if (c != '\n') {
		if (c == '$' || c == '\\' || (c == '}' && !intick && bct) ||
		    c == endchar || c == '`' ||
		    (endchar == ']' && (c == '[' || c == ']' ||
					c == '(' || c == ')' ||
					c == '{' || c == '}' ||
					(c == '"' && sub))))
		    add(Bnull);
		else {
		    /* lexstop is implicitly handled here */
		    add('\\');
		    goto cont;
		}
	    } else if (sub || unset(CSHJUNKIEQUOTES) || endchar != '"')
		continue;
	    break;
	case '\n':
	    err = !sub && isset(CSHJUNKIEQUOTES) && endchar == '"';
	    break;
	case '$':
	    if (intick)
		break;
	    c = hgetc();
	    if (c == '(') {
		add(Qstring);
		switch (cmd_or_math_sub()) {
		case CMD_OR_MATH_CMD:
		    c = Outpar;
		    break;

		case CMD_OR_MATH_MATH:
		    c = Outparmath;
		    break;

		default:
		    err = 1;
		    break;
		}
	    } else if (c == '[') {
		add(String);
		add(Inbrack);
		cmdpush(CS_MATHSUBST);
		err = dquote_parse(']', sub);
		cmdpop();
		c = Outbrack;
	    } else if (c == '{') {
		add(Qstring);
		c = Inbrace;
		cmdpush(CS_BRACEPAR);
		bct++;
	    } else if (c == '$')
		add(Qstring);
	    else {
		hungetc(c);
		lexstop = 0;
		c = Qstring;
	    }
	    break;
	case '}':
	    if (intick || !bct)
		break;
	    c = Outbrace;
	    bct--;
	    cmdpop();
	    break;
	case '`':
	    c = Qtick;
	    if (intick == 2)
		ALLOWHIST
	    if ((intick = !intick)) {
		SETPARBEGIN
		cmdpush(CS_BQUOTE);
	    } else {
		SETPAREND
	        cmdpop();
	    }
	    break;
	case '\'':
	    if (!intick)
		break;
	    if (intick == 1)
		intick = 2, STOPHIST
	    else
		intick = 1, ALLOWHIST
	    break;
	case '(':
	    if (!math || !bct)
		pct++;
	    break;
	case ')':
	    if (!math || !bct)
		err = (!pct-- && math);
	    break;
	case '[':
	    if (!math || !bct)
		brct++;
	    break;
	case ']':
	    if (!math || !bct)
		err = (!brct-- && math);
	    break;
	case '"':
	    if (intick || (endchar != '"' && !bct))
		break;
	    if (bct) {
		add(Dnull);
		cmdpush(CS_DQUOTE);
		err = dquote_parse('"', sub);
		cmdpop();
		c = Dnull;
	    } else
		err = 1;
	    break;
	}
	if (err || lexstop)
	    break;
	add(c);
    }
    if (intick == 2)
	ALLOWHIST
    if (intick) {
	cmdpop();
    }
    while (bct--)
	cmdpop();
    if (lexstop)
	err = intick || endchar || err;
    else if (err == 1) {
	/*
	 * TODO: as far as I can see, this hack is used in gettokstr()
	 * to hungetc() a character on an error.  However, I don't
	 * understand what that actually gets us, and we can't guarantee
	 * it's a character anyway, because of the previous test.
	 *
	 * We use the same feature in cmd_or_math where we actually do
	 * need to unget if we decide it's really a command substitution.
	 * We try to handle the other case by testing for lexstop.
	 */
	err = c;
    }
    if (zlemath && zlemetacs <= zlemetall + 1 - inbufct)
	inwhat = IN_MATH;
    return err;
}