예제 #1
0
/*
 * Perform expansions on an argument, placing the resulting list of arguments
 * in arglist.  Parameter expansion, command substitution and arithmetic
 * expansion are always performed; additional expansions can be requested
 * via flag (EXP_*).
 * The result is left in the stack string.
 * When arglist is NULL, perform here document expansion.
 *
 * When doing something that may cause this to be re-entered, make sure
 * the stack string is empty via grabstackstr() and do not assume expdest
 * remains valid.
 */
void
expandarg(union node *arg, struct arglist *arglist, int flag)
{
	struct worddest exparg;
	struct nodelist *argbackq;

	if (fflag)
		flag &= ~EXP_GLOB;
	argbackq = arg->narg.backquote;
	exparg.list = arglist;
	exparg.state = WORD_IDLE;
	STARTSTACKSTR(expdest);
	argstr(arg->narg.text, &argbackq, flag, &exparg);
	if (arglist == NULL) {
		STACKSTRNUL(expdest);
		return;			/* here document expanded */
	}
	if ((flag & EXP_SPLIT) == 0 || expdest != stackblock() ||
	    exparg.state == WORD_QUOTEMARK) {
		STPUTC('\0', expdest);
		if (flag & EXP_SPLIT) {
			if (flag & EXP_GLOB)
				expandmeta(grabstackstr(expdest), exparg.list);
			else
				appendarglist(exparg.list, grabstackstr(expdest));
		}
	}
	if ((flag & EXP_SPLIT) == 0)
		appendarglist(arglist, grabstackstr(expdest));
}
예제 #2
0
/*
 * Perform expansions on an argument, placing the resulting list of arguments
 * in arglist.  Parameter expansion, command substitution and arithmetic
 * expansion are always performed; additional expansions can be requested
 * via flag (EXP_*).
 * The result is left in the stack string.
 * When arglist is NULL, perform here document expansion.
 *
 * Caution: this function uses global state and is not reentrant.
 * However, a new invocation after an interrupted invocation is safe
 * and will reset the global state for the new call.
 */
void
expandarg(union node* arg, struct arglist* arglist, int32_t flag)
{
    struct strlist* sp;
    cstring_t p;
    argbackq = arg->narg.backquote;
    STARTSTACKSTR(expdest);
    ifsfirst.next = NULL;
    ifslastp = NULL;
    argstr(arg->narg.text, flag);
    if (arglist == NULL)
    {
        STACKSTRNUL(expdest);
        return;			/* here document expanded */
    }
    STPUTC('\0', expdest);
    p = grabstackstr(expdest);
    exparg.lastp = &exparg.list;
    /*
     * TODO - EXP_REDIR
     */
    if (flag & EXP_FULL)
    {
        ifsbreakup(p, &exparg);
        *exparg.lastp = NULL;
        exparg.lastp = &exparg.list;
        expandmeta(exparg.list, flag);
    }
    else
    {
        if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
            rmescapes(p);
        sp = (struct strlist*)stalloc(sizeof(struct strlist));
        sp->text = p;
        *exparg.lastp = sp;
        exparg.lastp = &sp->next;
    }
    while (ifsfirst.next != NULL)
    {
        pifsregion_t ifsp;
        INTOFF;
        ifsp = ifsfirst.next->next;
        ckfree(ifsfirst.next);
        ifsfirst.next = ifsp;
        INTON;
    }
    *exparg.lastp = NULL;
    if (exparg.list)
    {
        *arglist->lastp = exparg.list;
        arglist->lastp = exparg.lastp;
    }
}
예제 #3
0
/*
 * Perform expansions on an argument, placing the resulting list of arguments
 * in arglist.  Parameter expansion, command substitution and arithmetic
 * expansion are always performed; additional expansions can be requested
 * via flag (EXP_*).
 * The result is left in the stack string.
 * When arglist is NULL, perform here document expansion.
 *
 * Caution: this function uses global state and is not reentrant.
 * However, a new invocation after an interrupted invocation is safe
 * and will reset the global state for the new call.
 */
void
expandarg(union node *arg, struct arglist *arglist, int flag)
{
	struct strlist *sp;
	char *p;

	argbackq = arg->narg.backquote;
	STARTSTACKSTR(expdest);
	ifsfirst.next = NULL;
	ifslastp = NULL;
	argstr(arg->narg.text, flag);
	if (arglist == NULL) {
		STACKSTRNUL(expdest);
		return;			/* here document expanded */
	}
	STPUTC('\0', expdest);
	p = grabstackstr(expdest);
	exparg.lastp = &exparg.list;
	if (flag & EXP_FULL) {
		ifsbreakup(p, &exparg);
		*exparg.lastp = NULL;
		exparg.lastp = &exparg.list;
		expandmeta(exparg.list);
	} else {
		sp = (struct strlist *)stalloc(sizeof (struct strlist));
		sp->text = p;
		*exparg.lastp = sp;
		exparg.lastp = &sp->next;
	}
	while (ifsfirst.next != NULL) {
		struct ifsregion *ifsp;
		INTOFF;
		ifsp = ifsfirst.next->next;
		ckfree(ifsfirst.next);
		ifsfirst.next = ifsp;
		INTON;
	}
	*exparg.lastp = NULL;
	if (exparg.list) {
		*arglist->lastp = exparg.list;
		arglist->lastp = exparg.lastp;
	}
}
예제 #4
0
void
expandarg(shinstance *psh, union node *arg, struct arglist *arglist, int flag)
{
	struct strlist *sp;
	char *p;

	psh->argbackq = arg->narg.backquote;
	STARTSTACKSTR(psh, psh->expdest);
	psh->ifsfirst.next = NULL;
	psh->ifslastp = NULL;
	argstr(psh, arg->narg.text, flag);
	if (arglist == NULL) {
		return;			/* here document expanded */
	}
	STPUTC(psh, '\0', psh->expdest);
	p = grabstackstr(psh, psh->expdest);
	TRACE2((psh, "expandarg: p='%s'\n", p));
	psh->exparg.lastp = &psh->exparg.list;
	/*
	 * TODO - EXP_REDIR
	 */
	if (flag & EXP_FULL) {
		ifsbreakup(psh, p, &psh->exparg);
		*psh->exparg.lastp = NULL;
		psh->exparg.lastp = &psh->exparg.list;
		expandmeta(psh, psh->exparg.list, flag);
	} else {
		if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
			rmescapes(psh, p);
		sp = (struct strlist *)stalloc(psh, sizeof (struct strlist));
		sp->text = p;
		*psh->exparg.lastp = sp;
		psh->exparg.lastp = &sp->next;
	}
	ifsfree(psh);
	*psh->exparg.lastp = NULL;
	if (psh->exparg.list) {
		*arglist->lastp = psh->exparg.list;
		arglist->lastp = psh->exparg.lastp;
	}
}
예제 #5
0
static char *
nextword(char c, int flag, char *p, struct worddest *dst)
{
	int is_ws;

	is_ws = c == '\t' || c == '\n' || c == ' ';
	if (p != stackblock() || (is_ws ? dst->state == WORD_QUOTEMARK :
	    dst->state != WORD_WS_DELIMITED) || c == '\0') {
		STPUTC('\0', p);
		if (flag & EXP_GLOB)
			expandmeta(grabstackstr(p), dst->list);
		else
			appendarglist(dst->list, grabstackstr(p));
		dst->state = is_ws ? WORD_WS_DELIMITED : WORD_IDLE;
	} else if (!is_ws && dst->state == WORD_WS_DELIMITED)
		dst->state = WORD_IDLE;
	/* Reserve space while the stack string is empty. */
	appendarglist(dst->list, NULL);
	dst->list->count--;
	STARTSTACKSTR(p);
	return p;
}