Ejemplo n.º 1
0
void
singsub(char **s)
{
    LinkList foo;

    foo = newlinklist();
    addlinknode(foo, *s);
    prefork(foo, 4);
    if (errflag)
	return;
    *s = (char *) ugetnode(foo);
    DPUTS(nonempty(foo), "BUG: singsub() produced more than one word!");
}
Ejemplo n.º 2
0
Archivo: cond.c Proyecto: AMDmi3/zsh
static void cond_subst(char **strp, int glob_ok)
{
    if (glob_ok &&
	checkglobqual(*strp, strlen(*strp), 1, NULL)) {
	LinkList args = newlinklist();
	addlinknode(args, *strp);
	prefork(args, 0, NULL);
	while (!errflag && args && nonempty(args) &&
	       has_token((char *)peekfirst(args)))
	    zglob(args, firstnode(args), 0);
	*strp = sepjoin(hlinklist2array(args, 0), NULL, 1);
    } else
	singsub(strp);
}
Ejemplo n.º 3
0
int
multsub(char **s, char ***a, int *isarr, char *sep)
{
    LinkList foo;
    int l;
    char **r, **p;

    foo = newlinklist();
    addlinknode(foo, *s);
    prefork(foo, 0);
    if (errflag) {
	if (isarr)
	    *isarr = 0;
	return 0;
    }
    if ((l = countlinknodes(foo)) > 1) {
	p = r = ncalloc((l + 1) * sizeof(char*));
	while (nonempty(foo))
	    *p++ = (char *)ugetnode(foo);
	*p = NULL;
	if (a) {
	    *a = r;
	    *isarr = 1;
	    return 0;
	}
	*s = sepjoin(r, NULL);
	return 0;
    }
    if (l)
	*s = (char *) ugetnode(foo);
    else
	*s = dupstring("");
    if (isarr)
	*isarr = 0;
    return !l;
}
Ejemplo n.º 4
0
mod_export void
iremovesuffix(ZLE_INT_T c, int keep)
{
    if (suffixfunc) {
	Shfunc shfunc = getshfunc(suffixfunc);

	if (shfunc) {
	    LinkList args = newlinklist();
	    char buf[20];
	    int osc = sfcontext;
	    int wasmeta = (zlemetaline != 0);

	    if (wasmeta) {
		/*
		 * The suffix removal function runs as a normal
		 * ZLE function, not a completion function, so
		 * the line should be unmetafied if this was
		 * called from completion.  (It may not be since
		 * we may decide to remove the suffix later.)
		 */
		unmetafy_line();
	    }

	    sprintf(buf, "%d", suffixfunclen);
	    addlinknode(args, suffixfunc);
	    addlinknode(args, buf);

	    startparamscope();
	    makezleparams(0);
	    sfcontext = SFC_COMPLETE;
	    doshfunc(shfunc, args, 1);
	    sfcontext = osc;
	    endparamscope();

	    if (wasmeta)
		metafy_line();
	}
	zsfree(suffixfunc);
	suffixfunc = NULL;
    } else {
	int sl = 0, flags = 0;
	struct suffixset *ss;

	if (c == NO_INSERT_CHAR) {
	    sl = suffixnoinsrem ? suffixlen : 0;
	} else {
	    ZLE_CHAR_T ch = c;
	    /*
	     * Search for a match for ch in the suffix list.
	     * We stop if we encounter a match in a positive or negative
	     * list, using the suffix length specified or zero respectively.
	     * If we reached the end and passed through a negative
	     * list, we use the suffix length for that, else zero.
	     * This would break if it were possible to have negative
	     * sets with different suffix length:  that's not supposed
	     * to happen.
	     */
	    int negsuflen = 0, found = 0;

	    for (ss = suffixlist; ss; ss = ss->next) {
		switch (ss->tp) {
		case SUFTYP_POSSTR:
		    if (ZS_memchr(ss->chars, ch, ss->lenstr)) {
			sl = ss->lensuf;
			found = 1;
		    }
		    break;

		case SUFTYP_NEGSTR:
		    if (ZS_memchr(ss->chars, ch, ss->lenstr)) {
			sl = 0;
			found = 1;
		    } else {
			negsuflen = ss->lensuf;
		    }
		    break;

		case SUFTYP_POSRNG:
		    if (ss->chars[0] <= ch && ch <= ss->chars[1]) {
			sl = ss->lensuf;
			found = 1;
		    }
		    break;

		case SUFTYP_NEGRNG:
		    if (ss->chars[0] <= ch && ch <= ss->chars[1]) {
			sl = 0;
			found = 1;
		    } else {
			negsuflen = ss->lensuf;
		    }
		    break;
		}
		if (found) {
		    flags = ss->flags;
		    break;
		}
	    }

	    if (!found)
		sl = negsuflen;
	}
	if (sl) {
	    /* must be shifting wide character lengths */
	    backdel(sl, CUT_RAW);
	    if (flags & SUFFLAGS_SPACE)
	    {
		/* Add a space and advance over it */
		spaceinline(1);
		if (zlemetaline) {
		    zlemetaline[zlemetacs++] = ' ';
		} else {
		    zleline[zlecs++] = ZWC(' ');
		}
	    }
	    if (!keep)
		invalidatelist();
	}
    }
    fixsuffix();
}
Ejemplo n.º 5
0
Thingy
executenamedcommand(char *prmt)
{
    Thingy cmd, retval = NULL;
    int l, len, feep = 0, listed = 0, curlist = 0;
    int ols = (listshown && validlist), olll = lastlistlen;
    char *cmdbuf, *ptr;
    char *okeymap = ztrdup(curkeymapname);

    clearlist = 1;
    /* prmt may be constant */
    prmt = ztrdup(prmt);
    l = strlen(prmt);
    cmdbuf = (char *)zhalloc(l + NAMLEN + 2
#ifdef MULTIBYTE_SUPPORT
			     + 2 * MB_CUR_MAX
#endif
			     );
    strcpy(cmdbuf, prmt);
    zsfree(prmt);
    statusline = cmdbuf;
    selectlocalmap(command_keymap);
    selectkeymap("main", 1);
    ptr = cmdbuf += l;
    len = 0;
    for (;;) {
	*ptr = '_';
	ptr[1] = '\0';
	zrefresh();
	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
	    statusline = NULL;
	    selectkeymap(okeymap, 1);
	    zsfree(okeymap);
	    if ((listshown = ols)) {
		showinglist = -2;
		lastlistlen = olll;
	    } else if (listed)
		clearlist = listshown = 1;

	    retval = NULL;
	    goto done;
	}
	if(cmd == Th(z_clearscreen)) {
	    clearscreen(zlenoargs);
	    if (curlist) {
		int zmultsav = zmult;

		zmult = 1;
		listlist(namedcmdll);
		showinglist = 0;
		zmult = zmultsav;
	    }
	} else if(cmd == Th(z_redisplay)) {
	    redisplay(zlenoargs);
	    if (curlist) {
		int zmultsav = zmult;

		zmult = 1;
		listlist(namedcmdll);
		showinglist = 0;
		zmult = zmultsav;
	    }
	} else if(cmd == Th(z_viquotedinsert)) {
	    *ptr = '^';
	    zrefresh();
	    getfullchar(0);
	    if(LASTFULLCHAR == ZLEEOF || !LASTFULLCHAR || len >= NAMLEN)
		feep = 1;
	    else {
		int ret = zlecharasstring(LASTFULLCHAR, ptr);
		len += ret;
		ptr += ret;
		curlist = 0;
	    }
	} else if(cmd == Th(z_quotedinsert)) {
	    if(getfullchar(0) == ZLEEOF ||
	       !LASTFULLCHAR || len == NAMLEN)
		feep = 1;
	    else {
		int ret = zlecharasstring(LASTFULLCHAR, ptr);
		len += ret;
		ptr += ret;
		curlist = 0;
	    }
	} else if(cmd == Th(z_backwarddeletechar) ||
		  cmd == Th(z_vibackwarddeletechar)) {
	    if (len) {
		ptr = backwardmetafiedchar(cmdbuf, ptr, NULL);
		len = ptr - cmdbuf;
		curlist = 0;
	    }
	} else if(cmd == Th(z_killregion) || cmd == Th(z_backwardkillword) ||
		  cmd == Th(z_vibackwardkillword)) {
	    if (len)
		curlist = 0;
	    while (len) {
		convchar_t cc;
		ptr = backwardmetafiedchar(cmdbuf, ptr, &cc);
		len = ptr - cmdbuf;
		if (cc == ZWC('-'))
		    break;
	    }
	} else if(cmd == Th(z_killwholeline) || cmd == Th(z_vikillline) ||
	    	cmd == Th(z_backwardkillline)) {
	    len = 0;
	    ptr = cmdbuf;
	    if (listed)
		clearlist = listshown = 1;
	    curlist = 0;
	} else if (cmd == Th(z_bracketedpaste)) {
	    char *insert = bracketedstring();
	    size_t inslen = strlen(insert);
	    if (len + inslen > NAMLEN)
		feep = 1;
	    else {
		strcpy(ptr, insert);
		len += inslen;
		ptr += inslen;
		if (listed) {
		    clearlist = listshown = 1;
		    listed = 0;
		} else
		    curlist = 0;
	    }
	    free(insert);
	} else {
	    if(cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode)) {
		Thingy r;
		unambiguous:
		*ptr = 0;
		r = rthingy(cmdbuf);
		if (!(r->flags & DISABLED)) {
		    unrefthingy(r);
		    statusline = NULL;
		    selectkeymap(okeymap, 1);
		    zsfree(okeymap);
		    if ((listshown = ols)) {
			showinglist = -2;
			lastlistlen = olll;
		    } else if (listed)
			clearlist = listshown = 1;

		    retval = r;
		    goto done;
		}
		unrefthingy(r);
	    }
	    if(cmd == Th(z_selfinsertunmeta)) {
		fixunmeta();
		cmd = Th(z_selfinsert);
	    }
	    if (cmd == Th(z_listchoices) || cmd == Th(z_deletecharorlist) ||
		cmd == Th(z_expandorcomplete) || cmd == Th(z_completeword) ||
		cmd == Th(z_expandorcompleteprefix) || cmd == Th(z_vicmdmode) ||
		cmd == Th(z_acceptline) || lastchar == ' ' || lastchar == '\t') {
		namedcmdambig = 100;

		namedcmdll = newlinklist();

		*ptr = '\0';
		namedcmdstr = cmdbuf;
		scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
		namedcmdstr = NULL;

		if (empty(namedcmdll)) {
		    feep = 1;
		    if (listed)
			clearlist = listshown = 1;
		    curlist = 0;
		} else if (cmd == Th(z_listchoices) ||
		    cmd == Th(z_deletecharorlist)) {
		    int zmultsav = zmult;
		    *ptr = '_';
		    ptr[1] = '\0';
		    zmult = 1;
		    listlist(namedcmdll);
		    listed = curlist = 1;
		    showinglist = 0;
		    zmult = zmultsav;
		} else if (!nextnode(firstnode(namedcmdll))) {
		    strcpy(ptr = cmdbuf, peekfirst(namedcmdll));
		    len = strlen(ptr);
		    ptr += len;
		    if (cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode))
			goto unambiguous;
		} else {
		    strcpy(cmdbuf, peekfirst(namedcmdll));
		    ptr = cmdbuf + namedcmdambig;
		    *ptr = '_';
		    ptr[1] = '\0';
		    if (isset(AUTOLIST) &&
			!(isset(LISTAMBIGUOUS) && namedcmdambig > len)) {
			int zmultsav = zmult;
			if (isset(LISTBEEP))
			    feep = 1;
			zmult = 1;
			listlist(namedcmdll);
			listed = curlist = 1;
			showinglist = 0;
			zmult = zmultsav;
		    }
		    len = namedcmdambig;
		}
	    } else {
		if (len == NAMLEN || cmd != Th(z_selfinsert))
		    feep = 1;
		else {
#ifdef MULTIBYTE_SUPPORT
		    if (!lastchar_wide_valid)
			getrestchar(lastchar, NULL, NULL);
		    if (lastchar_wide == WEOF)
			feep = 1;
		    else
#endif
		    if (ZC_icntrl(LASTFULLCHAR))
			feep = 1;
		    else {
			int ret = zlecharasstring(LASTFULLCHAR, ptr);
			len += ret;
			ptr += ret;
			if (listed) {
			    clearlist = listshown = 1;
			    listed = 0;
			} else
			    curlist = 0;
		    }
		}
	    }
	}
	if (feep)
	    handlefeep(zlenoargs);
	feep = 0;
    }

 done:
    selectlocalmap(NULL);
    return retval;
}
Ejemplo n.º 6
0
Archivo: loop.c Proyecto: 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;
}
Ejemplo n.º 7
0
Archivo: loop.c Proyecto: 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;
}
Ejemplo n.º 8
0
Archivo: init.c Proyecto: AMDmi3/zsh
enum loop_return
loop(int toplevel, int justonce)
{
    Eprog prog;
    int err, non_empty = 0;

    queue_signals();
    pushheap();
    if (!toplevel)
	zcontext_save();
    for (;;) {
	freeheap();
	if (stophist == 3)	/* re-entry via preprompt() */
	    hend(NULL);
	hbegin(1);		/* init history mech        */
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact && toplevel) {
	        int hstop = stophist;
		stophist = 3;
		/*
		 * Reset all errors including the interrupt error status
		 * immediately, so preprompt runs regardless of what
		 * just happened.  We'll reset again below as a
		 * precaution to ensure we get back to the command line
		 * no matter what.
		 */
		errflag = 0;
		preprompt();
		if (stophist != 3)
		    hbegin(1);
		else
		    stophist = hstop;
		/*
		 * Reset all errors, including user interupts.
		 * This is what allows ^C in an interactive shell
		 * to return us to the command line.
		 */
		errflag = 0;
	    }
	}
	use_exit_printed = 0;
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(prog = parse_event(ENDINPUT))) {
	    /* if we couldn't parse a list */
	    hend(NULL);
	    if ((tok == ENDINPUT && !errflag) ||
		(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
		justonce)
		break;
	    if (exit_pending) {
		/*
		 * Something down there (a ZLE function?) decided
		 * to exit when there was stuff to clear up.
		 * Handle that now.
		 */
		stopmsg = 1;
		zexit(exit_pending >> 1, 0);
	    }
	    if (tok == LEXERR && !lastval)
		lastval = 1;
	    continue;
	}
	if (hend(prog)) {
	    enum lextok toksav = tok;

	    non_empty = 1;
	    if (toplevel &&
		(getshfunc("preexec") ||
		 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
		LinkList args;
		char *cmdstr;

		/*
		 * As we're about to freeheap() or popheap()
		 * anyway, there's no gain in using permanent
		 * storage here.
		 */
		args = newlinklist();
		addlinknode(args, "preexec");
		/* If curline got dumped from the history, we don't know
		 * what the user typed. */
		if (hist_ring && curline.histnum == curhist)
		    addlinknode(args, hist_ring->node.nam);
		else
		    addlinknode(args, "");
		addlinknode(args, dupstring(getjobtext(prog, NULL)));
		addlinknode(args, cmdstr = getpermtext(prog, NULL, 0));

		callhookfunc("preexec", args, 1, NULL);

		/* The only permanent storage is from getpermtext() */
		zsfree(cmdstr);
		/*
		 * Note this does *not* remove a user interrupt error
		 * condition, even though we're at the top level loop:
		 * that would be inconsistent with the case where
		 * we didn't execute a preexec function.  This is
		 * an implementation detail that an interrupting user
		 * does't care about.
		 */
		errflag &= ~ERRFLAG_ERROR;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execode(prog, 0, 0, toplevel ? "toplevel" : "file");
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	if (ferror(stderr)) {
	    zerr("write error");
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (isset(SINGLECOMMAND) && toplevel) {
	    dont_queue_signals();
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }
Ejemplo n.º 9
0
int
execzlefunc(Thingy func, char **args, int set_bindk)
{
    int r = 0, ret = 0, remetafy = 0;
    Widget w;
    Thingy save_bindk = bindk;

    if (set_bindk)
	bindk = func;
    if (zlemetaline) {
	unmetafy_line();
	remetafy = 1;
    }

    if(func->flags & DISABLED) {
	/* this thingy is not the name of a widget */
	char *nm = nicedup(func->nam, 0);
	char *msg = tricat("No such widget `", nm, "'");

	zsfree(nm);
	showmsg(msg);
	zsfree(msg);
	ret = 1;
    } else if((w = func->widget)->flags & (WIDGET_INT|WIDGET_NCOMP)) {
	int wflags = w->flags;

	/*
	 * The rule is that "zle -N" widgets suppress EOF warnings.  When
	 * a "zle -N" widget invokes "zle another-widget" we pass through
	 * this code again, but with actual arguments rather than with the
	 * zlenoargs placeholder.
	 */
	if (keybuf[0] == eofchar && !keybuf[1] && args == zlenoargs &&
	    !zlell && isfirstln && (zlereadflags & ZLRF_IGNOREEOF)) {
	    showmsg((!islogin) ? "zsh: use 'exit' to exit." :
		    "zsh: use 'logout' to logout.");
	    use_exit_printed = 1;
	    eofsent = 1;
	    ret = 1;
	} else {
	    if(!(wflags & ZLE_KEEPSUFFIX))
		removesuffix();
	    if(!(wflags & ZLE_MENUCMP)) {
		fixsuffix();
		invalidatelist();
	    }
	    if (wflags & ZLE_LINEMOVE)
		vilinerange = 1;
	    if(!(wflags & ZLE_LASTCOL))
		lastcol = -1;
	    if (wflags & WIDGET_NCOMP) {
		int atcurhist = histline == curhist;
		compwidget = w;
		ret = completecall(args);
		if (atcurhist)
		    histline = curhist;
	    } else if (!w->u.fn) {
		handlefeep(zlenoargs);
	    } else {
		queue_signals();
		ret = w->u.fn(args);
		unqueue_signals();
	    }
	    if (!(wflags & ZLE_NOTCOMMAND))
		lastcmd = wflags;
	}
	r = 1;
    } else {
	Shfunc shf = (Shfunc) shfunctab->getnode(shfunctab, w->u.fnnam);

	if (!shf) {
	    /* the shell function doesn't exist */
	    char *nm = nicedup(w->u.fnnam, 0);
	    char *msg = tricat("No such shell function `", nm, "'");

	    zsfree(nm);
	    showmsg(msg);
	    zsfree(msg);
	    ret = 1;
	} else {
	    int osc = sfcontext, osi = movefd(0);
	    int oxt = isset(XTRACE);
	    LinkList largs = NULL;

	    if (*args) {
		largs = newlinklist();
		addlinknode(largs, dupstring(w->u.fnnam));
		while (*args)
		    addlinknode(largs, dupstring(*args++));
	    }
	    startparamscope();
	    makezleparams(0);
	    sfcontext = SFC_WIDGET;
	    opts[XTRACE] = 0;
	    ret = doshfunc(shf, largs, 1);
	    opts[XTRACE] = oxt;
	    sfcontext = osc;
	    endparamscope();
	    lastcmd = w->flags;
	    w->flags = 0;
	    r = 1;
	    redup(osi, 0);
	}
    }
    if (r) {
	unrefthingy(lbindk);
	refthingy(func);
	lbindk = func;
    }
    if (set_bindk)
	bindk = save_bindk;
    /*
     * Goodness knows where the user's left us; make sure
     * it's not on a combining character that won't be displayed
     * directly.
     */
    CCRIGHT();
    if (remetafy)
	metafy_line();
    return ret;
}
Ejemplo n.º 10
0
Archivo: math.c Proyecto: blueyed/zsh
static mnumber
callmathfunc(char *o)
{
    MathFunc f;
    char *a, *n;
    static mnumber dummy;

    n = a = dupstring(o);

    while (*a != '(')
	a++;
    *a++ = '\0';
    a[strlen(a) - 1] = '\0';

    if ((f = getmathfunc(n, 1))) {
	if (f->flags & MFF_STR) {
	    return f->sfunc(n, a, f->funcid);
	} else {
	    int argc = 0;
	    mnumber *argv = NULL, *q, marg;
	    LinkList l = newlinklist();
	    LinkNode node;

	    if (f->flags & MFF_USERFUNC) {
		/* first argument is function name: always use mathfunc */
		addlinknode(l, n);
	    }

	    while (iblank(*a))
		a++;
	    while (*a) {
		if (*a) {
		    argc++;
		    if (f->flags & MFF_USERFUNC) {
			/* need to pass strings */
			char *str;
			marg = mathevall(a, MPREC_ARG, &a);
			if (marg.type & MN_FLOAT) {
			    /* convfloat is off the heap */
			    str = convfloat(marg.u.d, 0, 0, NULL);
			} else {
			    char buf[BDIGBUFSIZE];
			    convbase(buf, marg.u.l, 10);
			    str = dupstring(buf);
			}
			addlinknode(l, str);
		    } else {
			q = (mnumber *) zhalloc(sizeof(mnumber));
			*q = mathevall(a, MPREC_ARG, &a);
			addlinknode(l, q);
		    }
		    if (errflag || mtok != COMMA)
			break;
		}
	    }
	    if (*a && !errflag)
		zerr("bad math expression: illegal character: %c", *a);
	    if (!errflag) {
		if (argc >= f->minargs && (f->maxargs < 0 ||
					   argc <= f->maxargs)) {
		    if (f->flags & MFF_USERFUNC) {
			char *shfnam = f->module ? f->module : n;
			Shfunc shfunc = getshfunc(shfnam);
			if (!shfunc)
			    zerr("no such function: %s", shfnam);
			else {
			    doshfunc(shfunc, l, 1);
			    return lastmathval;
			}
		    } else {
			if (argc) {
			    q = argv =
				(mnumber *)zhalloc(argc * sizeof(mnumber));
			    for (node = firstnode(l); node; incnode(node))
				*q++ = *(mnumber *)getdata(node);
			}
			return f->nfunc(n, argc, argv, f->funcid);
		    }
		} else
		    zerr("wrong number of arguments: %s", o);
	    }
	}
    } else {
	zerr("unknown function: %s", n);
    }

    dummy.type = MN_INTEGER;
    dummy.u.l = 0;

    return dummy;
}
Ejemplo n.º 11
0
void
loop(int toplevel, int justonce)
{
    List list;
#ifdef DEBUG
    int oasp = toplevel ? 0 : alloc_stackp;
#endif

    pushheap();
    for (;;) {
	freeheap();
	errflag = 0;
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact)
		preprompt();
	}
	hbegin();		/* init history mech        */
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(list = parse_event())) {	/* if we couldn't parse a list */
	    hend();
	    if ((tok == ENDINPUT && !errflag) || justonce)
		break;
	    continue;
	}
	if (hend()) {
	    int toksav = tok;
	    List prelist;

	    if (toplevel && (prelist = getshfunc("preexec")) != &dummy_list) {
		Histent he = gethistent(curhist);
		LinkList args;
		PERMALLOC {
		    args = newlinklist();
		    addlinknode(args, "preexec");
		    if (he && he->text)
			addlinknode(args, he->text);
		} LASTALLOC;
		doshfunc(prelist, args, 0, 1);
		freelinklist(args, (FreeFunc) NULL);
		errflag = 0;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execlist(list, 0, 0);
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	DPUTS(alloc_stackp != oasp, "BUG: alloc_stackp changed in loop()");
	if (ferror(stderr)) {
	    zerr("write error", NULL, 0);
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (trapreturn) {
	    lastval = trapreturn;
	    trapreturn = 0;
	}
	if (isset(SINGLECOMMAND) && toplevel) {
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }
Ejemplo n.º 12
0
Archivo: init.c Proyecto: Lujaw/zsh
enum loop_return
loop(int toplevel, int justonce)
{
    Eprog prog;
    int err, non_empty = 0;

    pushheap();
    if (!toplevel)
	lexsave();
    for (;;) {
	freeheap();
	if (stophist == 3)	/* re-entry via preprompt() */
	    hend(NULL);
	hbegin(1);		/* init history mech        */
	if (isset(SHINSTDIN)) {
	    setblock_stdin();
	    if (interact && toplevel) {
	        int hstop = stophist;
		stophist = 3;
		preprompt();
		if (stophist != 3)
		    hbegin(1);
		else
		    stophist = hstop;
		errflag = 0;
	    }
	}
	use_exit_printed = 0;
	intr();			/* interrupts on            */
	lexinit();              /* initialize lexical state */
	if (!(prog = parse_event())) {	/* if we couldn't parse a list */
	    hend(NULL);
	    if ((tok == ENDINPUT && !errflag) ||
		(tok == LEXERR && (!isset(SHINSTDIN) || !toplevel)) ||
		justonce)
		break;
	    if (exit_pending) {
		/*
		 * Something down there (a ZLE function?) decided
		 * to exit when there was stuff to clear up.
		 * Handle that now.
		 */
		stopmsg = 1;
		zexit(exit_pending >> 1, 0);
	    }
	    if (tok == LEXERR && !lastval)
		lastval = 1;
	    continue;
	}
	if (hend(prog)) {
	    int toksav = tok;

	    non_empty = 1;
	    if (toplevel &&
		(getshfunc("preexec") ||
		 paramtab->getnode(paramtab, "preexec" HOOK_SUFFIX))) {
		LinkList args;
		char *cmdstr;

		/*
		 * As we're about to freeheap() or popheap()
		 * anyway, there's no gain in using permanent
		 * storage here.
		 */
		args = newlinklist();
		addlinknode(args, "preexec");
		/* If curline got dumped from the history, we don't know
		 * what the user typed. */
		if (hist_ring && curline.histnum == curhist)
		    addlinknode(args, hist_ring->node.nam);
		else
		    addlinknode(args, "");
		addlinknode(args, dupstring(getjobtext(prog, NULL)));
		addlinknode(args, cmdstr = getpermtext(prog, NULL, 0));

		callhookfunc("preexec", args, 1, NULL);

		/* The only permanent storage is from getpermtext() */
		zsfree(cmdstr);
		errflag = 0;
	    }
	    if (stopmsg)	/* unset 'you have stopped jobs' flag */
		stopmsg--;
	    execode(prog, 0, 0, toplevel ? "toplevel" : "file");
	    tok = toksav;
	    if (toplevel)
		noexitct = 0;
	}
	if (ferror(stderr)) {
	    zerr("write error");
	    clearerr(stderr);
	}
	if (subsh)		/* how'd we get this far in a subshell? */
	    exit(lastval);
	if (((!interact || sourcelevel) && errflag) || retflag)
	    break;
	if (isset(SINGLECOMMAND) && toplevel) {
	    if (sigtrapped[SIGEXIT])
		dotrap(SIGEXIT);
	    exit(lastval);
	}
	if (justonce)
	    break;
    }
Ejemplo n.º 13
0
int
init_term(void)
{
#ifndef TGETENT_ACCEPTS_NULL
    static char termbuf[2048];	/* the termcap buffer */
#endif

    if (!*term)
	return termok = TERM_BAD;

    /* unset zle if using zsh under emacs */
    if (!strcmp(term, "emacs"))
	opts[USEZLE] = 0;

#ifdef TGETENT_ACCEPTS_NULL
    /* If possible, we let tgetent allocate its own termcap buffer */
    if (tgetent(NULL, term) != 1) {
#else
    if (tgetent(termbuf, term) != 1) {
#endif

	if (isset(INTERACTIVE))
	    zerr("can't find termcap info for %s", term, 0);
	errflag = 0;
	return termok = TERM_BAD;
    } else {
	char tbuf[1024], *pp;
	int t0;

	termok = TERM_OK;
	for (t0 = 0; t0 != TC_COUNT; t0++) {
	    pp = tbuf;
	    zsfree(tcstr[t0]);
	/* AIX tgetstr() ignores second argument */
	    if (!(pp = tgetstr(tccapnams[t0], &pp)))
		tcstr[t0] = NULL, tclen[t0] = 0;
	    else {
		tclen[t0] = strlen(pp);
		tcstr[t0] = (char *) zalloc(tclen[t0] + 1);
		memcpy(tcstr[t0], pp, tclen[t0] + 1);
	    }
	}

	/* check whether terminal has automargin (wraparound) capability */
	hasam = tgetflag("am");

	/* if there's no termcap entry for cursor up, use single line mode: *
	 * this is flagged by termok which is examined in zle_refresh.c     *
	 */
	if (!tccan(TCUP)) {
		tcstr[TCUP] = NULL;
		termok = TERM_NOUP;
	}

	/* if there's no termcap entry for cursor left, use \b. */
	if (!tccan(TCLEFT)) {
	    tcstr[TCLEFT] = ztrdup("\b");
	    tclen[TCLEFT] = 1;
	}

	/* if the termcap entry for down is \n, don't use it. */
	if (tccan(TCDOWN) && tcstr[TCDOWN][0] == '\n') {
	    tclen[TCDOWN] = 0;
	    zsfree(tcstr[TCDOWN]);
	    tcstr[TCDOWN] = NULL;
	}

	/* if there's no termcap entry for clear, use ^L. */
	if (!tccan(TCCLEARSCREEN)) {
	    tcstr[TCCLEARSCREEN] = ztrdup("\14");
	    tclen[TCCLEARSCREEN] = 1;
	}
    }
    return termok;
}

/* Initialize lots of global variables and hash tables */

/**/
void
setupvals(void)
{
    struct passwd *pswd;
    struct timezone dummy_tz;
    char *ptr;
#ifdef HAVE_GETRLIMIT
    int i;
#endif

    noeval = 0;
    curhist = 0;
    histsiz = DEFAULT_HISTSIZE;
    inithist();
    clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));

    cmdstack = (unsigned char *) zalloc(256);
    cmdsp = 0;

    bangchar = '!';
    hashchar = '#';
    hatchar = '^';
    termok = TERM_BAD;
    curjob = prevjob = coprocin = coprocout = -1;
    gettimeofday(&shtimer, &dummy_tz);	/* init $SECONDS */
    srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */

    hostnam     = (char *) zalloc(256);
    gethostname(hostnam, 256);

    /* Set default path */
    path    = (char **) zalloc(sizeof(*path) * 5);
    path[0] = ztrdup("/bin");
    path[1] = ztrdup("/usr/bin");
    path[2] = ztrdup("/usr/ucb");
    path[3] = ztrdup("/usr/local/bin");
    path[4] = NULL;

    cdpath   = mkarray(NULL);
    manpath  = mkarray(NULL);
    fignore  = mkarray(NULL);
    fpath    = mkarray(NULL);
    mailpath = mkarray(NULL);
    watch    = mkarray(NULL);
    psvar    = mkarray(NULL);
#ifdef DYNAMIC
    module_path = mkarray(ztrdup(MODULE_DIR));
    modules = newlinklist();
#endif

    /* Set default prompts */
    if (opts[INTERACTIVE]) {
	prompt  = ztrdup("%m%# ");
	prompt2 = ztrdup("%_> ");
    } else {
	prompt = ztrdup("");
	prompt2 = ztrdup("");
    }
    prompt3 = ztrdup("?# ");
    prompt4 = ztrdup("+ ");
    sprompt = ztrdup("zsh: correct '%R' to '%r' [nyae]? ");

    ifs         = ztrdup(DEFAULT_IFS);
    wordchars   = ztrdup(DEFAULT_WORDCHARS);
    postedit    = ztrdup("");
    underscore  = ztrdup("");

    zoptarg = ztrdup("");
    zoptind = 1;
    schedcmds = NULL;

    ppid  = (long) getppid();
    mypid = (long) getpid();
    term  = ztrdup("");

#ifdef TIOCGWINSZ
    if (!(columns = shttyinfo.winsize.ws_col))
	columns = 80;
    if (columns < 2)
	opts[USEZLE] = 0;
    if (!(lines = shttyinfo.winsize.ws_row))
	lines = 24;
    if (lines < 2)
	opts[SINGLELINEZLE] = 1;
#else
    columns = 80;
    lines = 24;
#endif

    /* The following variable assignments cause zsh to behave more *
     * like Bourne and Korn shells when invoked as "sh" or "ksh".  *
     * NULLCMD=":" and READNULLCMD=":"                             */

    if (emulation == EMULATE_KSH || emulation == EMULATE_SH) {
	nullcmd     = ztrdup(":");
	readnullcmd = ztrdup(":");
    } else {
	nullcmd     = ztrdup("cat");
	readnullcmd = ztrdup("more");
    }

    /* We cache the uid so we know when to *
     * recheck the info for `USERNAME'     */
    cached_uid = getuid();

    /* Get password entry and set info for `HOME' and `USERNAME' */
    if ((pswd = getpwuid(cached_uid))) {
	home = metafy(pswd->pw_dir, -1, META_DUP);
	cached_username = ztrdup(pswd->pw_name);
    } else {
	home = ztrdup("/");
	cached_username = ztrdup("");
    }

    /* Try a cheap test to see if we can *
     * initialize `PWD' from `HOME'      */
    if (ispwd(home))
	pwd = ztrdup(home);
    else if ((ptr = zgetenv("PWD")) && ispwd(ptr))
	pwd = ztrdup(ptr);
    else
	pwd = metafy(zgetcwd(), -1, META_REALLOC);

    oldpwd = ztrdup(pwd);  /* initialize `OLDPWD' = `PWD' */
#ifdef __EMX__
    *cdrive = _getdrive();
    strcat(cdrive+1,":");
#endif

    inittyptab();     /* initialize the ztypes table */
    initlextabs();    /* initialize lexing tables    */

    createreswdtable();     /* create hash table for reserved words    */
    createaliastable();     /* create hash table for aliases           */
    createcmdnamtable();    /* create hash table for external commands */
    createshfunctable();    /* create hash table for shell functions   */
    createbuiltintable();   /* create hash table for builtin commands  */
    createnameddirtable();  /* create hash table for named directories */
    createparamtable();     /* create paramater hash table             */

#ifdef ZLE_MODULE
    add_dep("compctl", "zle");
    addbuiltin("bindkey", 0, NULL, 0, -1, "zle");
    addbuiltin("vared", 0, NULL, 1, 7, "zle");
    addbuiltin("compctl", 0, NULL, 0, -1, "compctl");
#endif

#ifdef HAVE_GETRLIMIT
    for (i = 0; i != RLIM_NLIMITS; i++) {
	getrlimit(i, current_limits + i);
	limits[i] = current_limits[i];
    }
#endif

    breaks = loops = 0;
    lastmailcheck = time(NULL);
    locallist = NULL;
    locallevel = sourcelevel = 0;
    trapreturn = 0;
    noerrexit = 0;
    nohistsave = 1;
    dirstack = newlinklist();
    bufstack = newlinklist();
    hsubl = hsubr = NULL;
    lastpid = 0;
    bshin = SHIN ? fdopen(SHIN, "r") : stdin;
    if (isset(SHINSTDIN) && !SHIN && unset(INTERACTIVE)) {
#ifdef _IONBF
	setvbuf(stdin, NULL, _IONBF, 0);
#else
	setlinebuf(stdin);
#endif
    }

    times(&shtms);
}

/* Initialize signal handling */

/**/
void
init_signals(void)
{
    intr();

#ifndef QDEBUG
    signal_ignore(SIGQUIT);
#endif

    install_handler(SIGHUP);
    install_handler(SIGCHLD);
    if (interact) {
	install_handler(SIGALRM);
#ifdef SIGWINCH
	install_handler(SIGWINCH);
#endif
	signal_ignore(SIGTERM);
    }
    if (jobbing) {
	long ttypgrp;

#ifndef __EMX__
	while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp)
	    kill(0, SIGTTIN);
#endif
	if (ttypgrp == -1) {
	    opts[MONITOR] = 0;
	} else {
#ifndef __EMX__
	    signal_ignore(SIGTTOU);
	    signal_ignore(SIGTSTP);
	    signal_ignore(SIGTTIN);
#endif
	    signal_ignore(SIGPIPE);
	    attachtty(mypgrp);
	}
    }
    if (islogin) {
	signal_setmask(signal_mask(0));
    } else if (interact) {
	sigset_t set;

	sigemptyset(&set);
	sigaddset(&set, SIGINT);
	sigaddset(&set, SIGQUIT);
	signal_unblock(set);
    }
}
Ejemplo n.º 14
0
void
parseargs(char **argv)
{
    char **x;
    int action, optno;
    LinkList paramlist;
    int bourne = (emulation == EMULATE_KSH || emulation == EMULATE_SH);

    hackzero = argzero = *argv++;
    SHIN = 0;

    /* There's a bit of trickery with opts[INTERACTIVE] here.  It starts *
     * at a value of 2 (instead of 1) or 0.  If it is explicitly set on  *
     * the command line, it goes to 1 or 0.  If input is coming from     *
     * somewhere that normally makes the shell non-interactive, we do    *
     * "opts[INTERACTIVE] &= 1", so that only a *default* on state will  *
     * be changed.  At the end of the function, a value of 2 gets        *
     * changed to 1.                                                     */
    opts[INTERACTIVE] = isatty(0) ? 2 : 0;
    opts[SHINSTDIN] = 0;
    opts[SINGLECOMMAND] = 0;

    /* loop through command line options (begins with "-" or "+") */
    while (*argv && (**argv == '-' || **argv == '+')) {
	action = (**argv == '-');
	if(!argv[0][1])
	    *argv = "--";
	while (*++*argv) {
	    /* The pseudo-option `--' signifies the end of options. *
	     * `-b' does too, csh-style, unless we're emulating a   *
	     * Bourne style shell.                                  */
	    if (**argv == '-' || (!bourne && **argv == 'b')) {
		argv++;
		goto doneoptions;
	    }

	    if (**argv == 'c') {         /* -c command */
		if (!*++argv) {
		    zerr("string expected after -c", NULL, 0);
		    exit(1);
		}
		cmd = *argv++;
		opts[INTERACTIVE] &= 1;
		opts[SHINSTDIN] = 0;
		goto doneoptions;
	    } else if (**argv == 'o') {
		if (!*++*argv)
		    argv++;
		if (!*argv) {
		    zerr("string expected after -o", NULL, 0);
		    exit(1);
		}
		if(!(optno = optlookup(*argv)))
		    zerr("no such option: %s", *argv, 0);
		else
		    dosetopt(optno, action, 1);
		break;
	    } else {
	    	if (!(optno = optlookupc(**argv))) {
		    zerr("bad option: -%c", NULL, **argv);
		    exit(1);
		} else
		    dosetopt(optno, action, 1);
	    }
	}
	argv++;
    }
    doneoptions:
    paramlist = newlinklist();
    if (*argv) {
	if (unset(SHINSTDIN)) {
	    argzero = *argv;
	    if (!cmd)
		SHIN = movefd(open(unmeta(argzero), O_RDONLY));
	    if (SHIN == -1) {
		zerr("can't open input file: %s", argzero, 0);
		exit(1);
	    }
	    opts[INTERACTIVE] &= 1;
	    argv++;
	}
	while (*argv)
	    addlinknode(paramlist, ztrdup(*argv++));
    } else
	opts[SHINSTDIN] = 1;
    if(isset(SINGLECOMMAND))
	opts[INTERACTIVE] &= 1;
    opts[INTERACTIVE] = !!opts[INTERACTIVE];
    pparams = x = (char **) zcalloc((countlinknodes(paramlist) + 1) * sizeof(char *));

    while ((*x++ = (char *)getlinknode(paramlist)));
    free(paramlist);
    argzero = ztrdup(argzero);
}